JavaScript로 rel=canonical href를 업데이트하고 싶습니다

도메인에 중복된 페이지가 몇 개 있습니다. 중복된 페이지의 canonical 태그를 원본 페이지를 참조하도록 JavaScript를 사용하여 업데이트해야 합니다. (중복된 페이지는 상당한 트래픽이 있어 삭제할 수 있는 옵션이 아닙니다.)
discourse에서 JavaScript를 사용하여 a href 태그를 업데이트하는 방법에 대해 조언해 주실 수 있나요?

@KranthiKiranGude, 요청하신 내용을 정리해 드립니다. 자바스크립트에서 href 속성을 변경하는 방법은 다음과 같습니다. 먼저 DOM 요소를 선택한 후, 해당 속성을 변경하면 됩니다.

<script>
var uC = document.querySelectorAll("link[rel='canonical']")[0];
var newURL = "https://my.coolforum.com/newlink";
uC.setAttribute("href", newURL);
</script>

물론, 작업하려는 페이지에 기반한 로직이 필요합니다.

범용적인 예시 로직:

<script>
if("the_actual_page_url_or_id" == "my_interesting_page_url_or_id")
{
   var uC = document.querySelectorAll("link[rel='canonical']")[0];
   var newURL = "https://my.coolforum.com/newlink";
   uC.setAttribute("href", newURL);
}
</script>

도움이 되기를 바랍니다.

안녕하세요 @neounix,

코드에 시도해 보았지만, href가 업데이트되는 대신 새로운 script 태그가 생성되었습니다:
image
이 스크립트를 “/head” 섹션에 업데이트했습니다.

안녕하세요 @KranthiKiranGude

사용하신 정확한 코드와 정확히 어디에 추가했는지, 그리고 언급하신 </head> 섹션의 항목 스크린샷을 포함하여 게시해 주세요.

감사합니다!

JavaScript를 추가하면 새로운 JavaScript가 생성되는 것은 당연한 일입니다.

참고로, 페이지 소스 코드가 아니라 웹 개발자 도구(Elements)에서 DOM을 확인해야 합니다.

@neounix님, 안녕하세요.


이것이 제가 추가한 스크립트입니다. 단순히 테스트해 보기 위해 추가한 것입니다.

이해합니다.

참고로 스크립트의 조건문에서 시작 따옴표가 빠져 있습니다.

@neounix 님, 안녕하세요.

Dev Console에서는 정상적으로 작동했습니다. 하지만 Page Source에서는 여전히 실제 URL이 참조되고 있습니다.
제가 잘못 알고 있는 게 아니라면, 검색 엔진은 DOM 요소가 아닌 Page Source에서 정보를 가져오게 됩니다. 만약 제 말이 틀렸다면 알려 주세요.

솔직히 그 부분은 확신할 수 없습니다. 처음에는 현대적인 검색 엔진(GoogleBot)이 DOM을 읽는다고 생각했지만, 다시 생각해보니 검색 엔진이 DOM이 아닌 소스 코드만 읽을 수도 있다는 추론이 타당해 보입니다.

하지만… 이를 확인하기 위해 Google을 검색해 보니 다음과 같은 내용이 나와 있습니다:

DOM의 SEO 신호(페이지 제목, 메타 설명, canonical 태그, 메타 robots 태그 등)는 존중됩니다. DOM에 동적으로 삽입된 콘텐츠도 크롤링 및 인덱싱이 가능합니다. 또한 특정 경우, DOM 신호가 HTML 소스 코드와 모순되는 경우에도 우선시될 수 있습니다. 이는 추가적인 작업이 필요하지만, 우리의 여러 테스트에서 그러한 경우가 있었습니다.

참고 자료:

@neounix님,

도와주셔서 정말 감사합니다. 저도 이 부분에 대해 좀 더 알아볼게요. 정말 감사드립니다.

환영합니다!

조사를 마친 후 결과를 다시 게시해 주세요.

요즘 제 여가 시간에 연구하고 있는 또 다른 방법은 이 Discourse Ruby 라이브러리 파일을 직접 수정하는 것입니다:

DOM 조작 JS 기법으로 원하는 결과를 얻지 못하셨다면, @KranthiKiranGude 님께서는 이 방향으로 고려해 보시는 것도 좋습니다.

안녕하세요 @neounix,

URL 검사 도구를 사용하여 해당 페이지를 테스트해 보았으며, Google이 업데이트된 URL을 인식하고 있습니다.

완벽하네요… 작동했다고 해서 기쁩니다.

테스트해 주시고 결과를 공유해 주셔서 감사합니다.

PS: 그 JS DOM 메서드는 canonical_url.rb를 조작하는 것보다 훨씬 쉽습니다 :slight_smile:

JavaScript를 사용하여 canonical을 오버라이드하는 것이 동작할지 확실하지 않습니다. 이는 인덱서 레벨(봇의 데이터 해석 및 검색 인덱스에 저장하는 부분)보다는 스파이더 레벨(데이터를 검색하고 수집하는 부분)에 더 가까운 작업이기 때문입니다.

부탁하지 않은 조언이지만: 이 토픽을 읽어보시는 것이 좋습니다. 이렇게 하면 해당 오버라이드를 플러그인에 적용할 수 있습니다:

저도 그렇습니다. 그 부분에 대해서는 아직 결론이 나지 않았습니다.

하지만 이 주제에 대한 Google 검색을 해보면 많은 결과가 나오는데, 많은 사람들이 이렇게 하고 있으며, 많은 사람들이 Google이 DOM 변경을 존중한다고 말합니다(일부 사람은 그렇지 않다고 하므로, 이 주제에 대해 강력하고 압도적인 합의가 있는 것 같지는 않습니다). 예를 들어 다음을 참고하세요:

https://stackoverflow.com/questions/29067810/replace-existing-canonical-tag-with-javascript-or-jquery

제가 그렇게 하려면 (1) 페이지 소스에서 원래의 canonical 태그를 삭제하고, 그런 다음 (2) JS를 사용하여 DOM에 새로운 canonical 태그를 삽입하겠습니다.

그런 다음, 시간이 지나면 Google 검색 콘솔을 통해 Google이 어떤 canonical 태그를 선택했는지 확인할 수 있습니다.

다음도 참고하세요:

https://stackoverflow.com/questions/40370074/how-can-i-replace-the-href-for-an-existing-canonical-tag

많은 사람들이 이것이 SEO에 중요하다고 생각하기 때문에, @KranthiKiranGude의 이 확인 사항을 바탕으로 해당 사항에 대해 다시 확인해 보았습니다.

developers.google.com의 JavaScript SEO 기초 이해하기 문서에 따르면:

Googlebot은 웹 컴포넌트를 지원합니다. Googlebot이 페이지를 렌더링할 때 shadow DOM과 light DOM 콘텐츠를 평탄화(flattens)합니다. 이는 Googlebot이 렌더링된 HTML에서 보이는 콘텐츠만 볼 수 있음을 의미합니다. 렌더링 후에도 Googlebot이 콘텐츠를 볼 수 있도록 하려면 모바일 친화성 테스트 또는 URL 검사 도구를 사용하여 렌더링된 HTML을 확인해 보세요.

(1) @KranthiKiranGude가 테스트에서 URL 검사 도구를 사용했고 (2) 이 방식으로 canonical이 의도대로 변경되었음을 확인했으므로, Google의 관점에서 GoogleBot은 페이지가 렌더링된 후 DOM 콘텐츠 변경 사항을 실제로 “보고” 이를 등록한다는 결론이 도출됩니다.

참고:

네, Google이 인덱싱하는 동안 DOM 콘텐츠를 그렇게 평탄화(flatten)하는 아이디어에 전적으로 동의합니다.

하지만 일부/대부분의 meta 태그는 HTML에 존재하긴 하지만, 그 의미론적 수준은 HTML 프로토콜보다는 HTTP 프로토콜 수준에 있습니다. '인덱싱하는 동안’이라는 부분을 강조한 이유는, Google이 크롤링하는 동안 DOM을 그렇게 평탄화하고 업데이트된 canonical URL을 고려하는지 확신이 서지 않기 때문입니다.

(다른 말로 하면, DOM 콘텐츠에 '콘텐츠에 내장된 메타데이터’도 포함되는지 확신이 서지 않습니다. Google은 그렇게 보긴 하지만, 실제로 그렇게 사용하는지는 불확실합니다.)

아마 이 글이 더 잘 설명해 줄 것 같습니다: How Google Crawls Your Website and Indexes Your Content

Google이 JavaScript 사이트를 크롤링할 필요가 있을 때, 전통적인 HTML 콘텐츠에는 필요하지 않은 추가 단계가 필요합니다. 이것이 렌더링 단계로, 추가적인 시간이 소요됩니다. 인덱싱 단계와 렌더링 단계는 별개의 단계로, 이를 통해 Google은 JavaScript가 아닌 콘텐츠를 먼저 인덱싱할 수 있습니다

.

별로 그렇지 않네요, 죄송합니다. www.hillwebcreations.com의 그 기사는 DOM에 대해 언급하지도 않고, DOM을 검사하는 방법 등도 다루지 않으며, 적어도 저에게는 “낡고 주관적인”(실제로 최신도 아니고, 사실에 기반하지도 않은) 느낌으로 읽힙니다.

개인적으로는 다음 두 가지 잘 쓰인 참고 자료를 선호합니다. 모두 더 권위 있고, 사실에 기반하며 잘 참고된 자료라고 생각합니다:

그리고 실제로 테스트를 수행했던 첫 번째 자료(그리고 그것은 GoogleBot이 DOM(JavaScript)을 더 잘 읽을 수 있는 Chromium 코어로 전환되기 훨씬 전의 일이었습니다):

We Tested How Googlebot Crawls Javascript And Here’s What We Learned

제 조사 결과, 저는 Google 개발자들의 의견에 동의하는 편입니다. 즉, URL 검사 도구(URL Inspection Tool)를 통해 발견되는 것을 색인화(그리고 SEO 신호를 얻는)한다는 것입니다. 그리고 바로 이 것을 통해 우리는 SEO 신호와 콘텐츠를 "판단"할 수 있습니다. Google의 논의는 명확하고, 사실에 기반하며, 권위 있고, 추측에 의존하지 않습니다.

@KranthiKiranGude가 Google이 권위 있는 기관으로서 "모든 것을 확인하는 데 필요한 모든 것"이라고 말한 URL 검사 도구를 사용하여 자신의 canonical 링크가 업데이트되었음을 확인했기 때문입니다.

기술적 요약

Google이 URL 검사 도구에서 볼 수 있는 것에서 SEO 신호를 사용한다는 사실; 그리고 Google 개발자들이 그들의 SEO 신호가 URL 검사 도구를 통해 직접 분석될 수 있다고 명확히 진술했다는 사실; 그리고 @KranthiKiranGude가 DOM에 대해 수행한 JS 변경 사항이 URL 검사 도구에서 가시적이라는 사실로 인해, 제 생각에는 그것이 "충분히 좋다"고 볼 수 있습니다.

도움이 되셨기를 바랍니다.

네, 그 글에는 실제로 동적으로 삽입된 canonical 태그가 소스 코드에 있는 것과 완전히 동일한 방식으로 동작하는 것을 확인했다고 명확히 명시되어 있습니다. 말씀이 맞습니다 (처음에 그 글을 게시했을 때 더 자세히 읽어야 했었네요).

다만 이 토픽에서 언급하신 네 개의 페이지 중 세 개, 그리고 우리에게 답을 주었던 페이지를 포함해, 제가 게시한 그 글보다도 더 오래된 것들입니다 :wink:

참고로 @RGJ, "not current(최신 아님)"에 대해 혼동을 드려 죄송합니다…

저는 "dated(시대에 뒤처진)"나 "not current"라는 용어를 사용할 때, 특정 기사의 물리적 날짜가 아니라 개념과 아이디어를 두고 말씀하는 것입니다.

오늘날의 날짜를 붙여 작성했지만 개념이 “시대에 뒤처져” 있고(또는 틀린) 기사가 있는 반면, 10년 전에 작성되었음에도 오늘날 여전히 매우 관련성이 높은 기사가 있습니다.

제가 "dated"나 "not current"라고 할 때 의도하는 바는 바로 이것이며, 이는 종이나 웹 기사에 적힌 물리적 날짜가 아닌 "개념"에 기반합니다. 이 용어를 그렇게 사용하여 혼동을 드린 점 죄송합니다.

저에게 중요한 것, 적어도 제 생각에는, @KranthiKiranGude에게 해결책을 제공했고 그가 그것이 작동한다고 확인했으며, 님의 회의적인 게시물을 바탕으로 우리 둘 다 이 문제에 대해 추가 조사를 수행했다는 것입니다.

우리는 (1) canonical 링크를 자바스크립트로 변경하는 이 방법이 유효하다는 것, 그리고 (2) 구글 개발자들이 이를 확인했다는 것, 그리고 (3) @KranthiKiranGude가 사용하고 우리에게 공유한 URL 검사 도구를 통해 사용자로서 이를 확인할 수 있는 방법이 있다는 것을 검증했습니다.

이 흥미로운 주제에 대해 "상호 교류"를 해 주시고, 해결책을 더욱 유효하고 강력하게 만들어 주셔서 진심으로 감사드립니다. 모두 좋은 일만 있으시길 바랍니다.

이제 다른 작업으로 넘어가려 합니다 (PHP 코딩을 10년 넘게 해 왔는데도 여전히 Ruby on Rails를 배우는 데 고군분투 중입니다) ; 이 주제는 완전히 “임무 완료” 상태입니다 :slight_smile:

다음에 뵙겠습니다… 모두 좋은 일만 있으시길 바랍니다!