AI 크롤러 JavaScript 렌더링 문제: ChatGPT가 빈 페이지를 볼 수 있는 이유

SEOgrinder 편집팀 · 게시일 · 읽는 시간 약 11분

핵심 답변: AI 크롤러 JavaScript 렌더링에는 단순한 규칙이 있습니다. 스크립트를 실행하지 않는 봇은 서버가 보내는 HTML만 봅니다. 본문을 브라우저에서 조립하는 페이지라면 그 HTML이 텅 빈 껍데기일 수 있습니다. 2024년 12월 Vercel과 MERJ의 측정에서는 주요 AI 크롤러 가운데 JavaScript를 실행한 것이 없었고, Google의 크롤러와 AppleBot은 실행했습니다. 이것은 2024년의 스냅샷이므로 내 페이지를 직접 테스트하고, 핵심 본문은 HTML에 직접 담으세요. 서버에서 렌더링하거나 미리 생성하면 됩니다.

크롤러는 어떻게 내 페이지를 가져갈까요?

모든 가져오기는 같은 방식으로 시작합니다. 서버에 요청을 보내고, 서버는 HTML로 응답합니다. 그다음에 일어나는 일이 페이지가 얼마나 전달되는지를 결정합니다.

브라우저는 HTML이 가리키는 스크립트를 불러와 실행하고 그 결과를 보여 줍니다. 크롤러는 첫 번째 HTML에서 멈출 수도 있습니다. 아니면 렌더링을 합니다. 스크립트를 실행하고, 잠시 기다리고, 그 뒤에야 읽습니다.

서버가 텍스트를 함께 보내 준다면 두 경로는 같은 내용에 도달합니다. 페이지가 브라우저에서 조립된다면 첫 번째 HTML에는 내용이 거의 없습니다. Google 문서는 이를 “앱 셸(app shell)” 모델이라고 부릅니다. JavaScript를 실행하지 않는 봇은 대략 다음과 같은 것을 받습니다.

<body>
  <div id="root"></div>
  <script src="/app.js"></script>
</body>

제목, 본문, 상품 목록, 링크는 /app.js가 실행된 뒤에야 나타납니다. 모든 크롤러가 이 스크립트를 실행하는 것은 아니며, 문제는 바로 여기에 있습니다.

Google은 JavaScript를 어떻게 처리할까요?

Google은 쉬운 경우입니다. JavaScript SEO 기본 사항 문서에는 다음과 같이 나와 있습니다.

  • Google 검색은 “evergreen” 버전의 Chromium으로 JavaScript를 실행합니다.
  • 페이지는 크롤링, 렌더링, 색인의 세 단계를 거칩니다.
  • 상태 코드가 200인 페이지는 렌더링 대기열에 들어가며, 몇 초 또는 그 이상 걸릴 수 있습니다. 404처럼 200이 아닌 상태의 페이지는 렌더링을 건너뛸 수 있습니다.
  • 제목, 메타 설명, canonical은 JavaScript로 설정해도 됩니다.

같은 문서는 이 글이 존재하는 이유도 알려 줍니다. Google은 서버 사이드 렌더링이나 사전 렌더링이 여전히 좋은 방법이라고 씁니다. 사용자와 크롤러 모두에게 페이지를 더 빠르게 만들어 주고, 모든 봇이 JavaScript를 실행할 수 있는 것은 아니기 때문입니다. 따라서 “Google이 내 페이지를 색인한다”는 것이 모든 봇이 그 페이지를 읽을 수 있다는 뜻은 아닙니다.

AI 크롤러 JavaScript 렌더링: 지금까지 확인된 사실

가장 잘 알려진 측정은 Vercel과 MERJ가 2024년 12월에 The rise of the AI crawler라는 제목으로 발표한 것입니다. 결과는 주요 AI 크롤러 가운데 JavaScript를 실행한 것이 없었다는 것입니다. 연구는 그 가운데 GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot을 명시했습니다. Googlebot(연구에서는 Gemini용으로 분류)과 AppleBot은 JavaScript를 렌더링했습니다.

이 결과 옆에는 두 가지 단서가 붙어야 합니다. 첫째, 이것은 2024년의 스냅샷이며 인용할 만한 더 새로운 측정이 없습니다. 크롤러는 바뀌므로 법칙이 아니라 경고로 받아들이세요. 둘째, 이 결과는 봇이 무엇을 읽는지를 말해 줄 뿐, 페이지가 답변에서 인용되는지는 말해 주지 않습니다. JavaScript가 있든 없든 인용을 약속할 수 있는 사람은 없습니다.

봇마다 맡은 일이 다릅니다. 각 운영사가 설명하는 내용은 다음과 같습니다.

운영사봇운영사가 밝힌 용도
OpenAIGPTBot생성형 기반 모델의 학습
OpenAIOAI-SearchBotChatGPT 검색
OpenAIChatGPT-User사용자 요청에 따른 가져오기(예: ChatGPT에서의 질문)
AnthropicClaudeBot학습에 기여할 수 있는 웹 콘텐츠 수집
AnthropicClaude-SearchBot검색 결과의 품질 개선
AnthropicClaude-User사용자가 Claude에게 질문할 때의 가져오기
PerplexityPerplexityBotPerplexity 검색 결과에 웹사이트를 보여 주고 링크

출처는 OpenAI, Anthropic, Perplexity입니다. Perplexity에는 사용자 요청에 따른 가져오기를 위한 별도 봇도 있습니다. AI 검색 답변 뒤에 있는 봇들이 HTML만 읽는다면, 껍데기만 있는 페이지에서는 인용할 것이 없습니다. 그중 어떤 봇이 스크립트를 렌더링하는지는 바로 2024년 연구가 측정한 것이고, 여러분이 내 페이지에서 직접 확인해야 할 것이기도 합니다.

누가 영향을 받을까요?

서버가 보내는 HTML에 페이지의 텍스트나 링크가 없다면 영향을 받습니다.

  • 전부 브라우저에서 조립되는 페이지. 서버는 껍데기와 스크립트 번들로 응답하고, 스크립트가 제목, 본문, 내비게이션을 써 넣습니다.
  • 스크립트가 나중에 불러오는 콘텐츠. 페이지가 로드된 뒤 API 호출로 들어오는 상품 목록, 가격, 후기, 탭, “더 보기” 영역입니다.
  • 스크립트가 실행된 뒤에야 생기는 링크. JavaScript를 실행하지 않는 크롤러는 HTML에 있는 링크만 따라갈 수 있습니다. SEOgrinder의 사이트 순회도 같은 한계에 부딪힙니다. 브라우저에서만 생기는 링크는 따라갈 수 없다고 표시합니다.
  • 스크립트가 설정하는 제목, 설명, canonical, Open Graph 태그. Google은 이를 받아들입니다. 스크립트를 건너뛰는 봇은 이것을 전혀 보지 못합니다.

서버가 이미 텍스트를 보낸다면 영향을 받지 않습니다. 메뉴, 차트, 계산기 같은 상호작용 요소는 계속 브라우저에서 만들어도 됩니다. SEOgrinder는 브라우저에서만 존재하는 페이지를 “페이지가 브라우저에서만 조립됩니다”라는 결과로 알려 줍니다. 많은 AI 크롤러가 거기서 JavaScript를 실행하지 않아 거의 빈 페이지를 보기 때문입니다.

1분이면 되는 테스트 세 가지

답을 알아내는 데 도구는 필요 없습니다. 세 가지 테스트는 모두 같은 질문에 답합니다. 내 텍스트가 서버가 보내는 HTML에 들어 있는가?

  1. 페이지 소스 보기. 페이지를 열고 “페이지 소스 보기”를 고릅니다(Ctrl+U, Mac에서는 Cmd+Option+U). “검사”를 쓰면 안 됩니다. 개발자 도구는 스크립트가 실행된 뒤의 페이지를 보여 줍니다. 소스에서 페이지에 보이는 문장 하나를 검색해 보세요.
  2. curl로 페이지 가져오기. 터미널에서 curl -sL https://example.com/your-page | grep -io "페이지에 있는 짧은 구절"을 실행합니다. 구절은 내 페이지에 있는 짧은 표현으로 바꾸세요. 구절이 출력되면 HTML에 있는 것입니다. 단, script 요소 안에만 있다면 해당하지 않습니다. 아무것도 출력되지 않으면 먼저 철자와 특수문자를 확인하세요. 그래도 안 나오면 HTML에 없는 것입니다.
  3. JavaScript 끄기. 개발자 도구를 열고 명령 메뉴를 엽니다(Ctrl+Shift+P, Mac에서는 Cmd+Shift+P). “JavaScript”를 입력하고 JavaScript를 끄는 항목(영문 화면에서는 “Disable JavaScript”)을 선택한 다음 페이지를 새로 고칩니다. 핵심 본문이 사라진다면 JavaScript를 실행하지 않는 봇도 같은 화면을 봅니다.

결과는 이렇게 읽습니다.

보이는 것의미
구절이 소스와 curl 출력에 모두 있음텍스트가 전달되는 HTML에 들어 있습니다. 이 부분은 문제없습니다.
구절이 소스에는 없는데 브라우저에서는 보임페이지가 브라우저에서 만들어집니다. 스크립트를 건너뛰는 봇은 텍스트를 보지 못합니다.

두 가지 한계가 있습니다. curl은 서버가 curl에게 보내는 내용을 보여 줄 뿐, 특정 봇에게 보내는 내용은 보여 주지 않습니다. 예를 들어 방화벽이 봇을 다르게 취급하는 경우가 그렇습니다. 그리고 Google이 렌더링한 결과를 보려면 Google Search Console의 URL 검사를 사용하세요.

해결 방법: 콘텐츠를 HTML에 담기

목표는 제목, 본문, 내부 링크가 소스에 보이게 하는 것입니다. 널리 쓰이는 방법은 두 가지입니다.

  • 서버 사이드 렌더링(SSR). 서버가 요청마다 완성된 HTML을 만듭니다.
  • 사전 렌더링, 곧 정적 생성(SSG). 빌드할 때처럼 미리 페이지를 생성해 두고, 서버는 그 파일을 내주기만 합니다.

두 방법 모두 콘텐츠를 첫 응답에 담습니다. 그 밖에 다음 사항을 지키세요.

  • 중요한 페이지부터 시작하세요. 전면적인 재작성은 거의 필요하지 않습니다. 순위에 오르거나 인용되길 원하는 페이지부터 시작하세요.
  • 핵심을 첫 HTML에 담으세요. 제목, 메타 설명, canonical, Open Graph 태그, 본문, 그리고 진짜 <a href> 요소로 쓴 내비게이션 링크가 여기에 해당합니다.
  • 크롤러와 방문자에게 같은 콘텐츠를 보여 주세요. Google은 봇에게 미리 만든 버전을 주는 “동적 렌더링(dynamic rendering)”을 임시방편으로만 언급합니다. 크롤러에게 방문자와 다른 것을 보여 주는 것은 클로킹입니다.
  • 결과를 소스에서 확인하세요. 변경한 뒤 위의 세 가지 테스트를 다시 해 보세요.

이 중 어느 것도 순위를 보장하지 않습니다. 기술적 장애물 하나를 치울 뿐입니다.

SEOgrinder는 브라우저에서만 만들어지는 페이지를 어떻게 찾나요?

SEOgrinder는 브라우저가 만들어 낸 결과가 아니라 서버가 전달하는 HTML을 봅니다. 주소를 입력하고 분석을 시작하면 할 일 탭에 영향이 큰 순서대로 할 일이 나타납니다. 이 주제와 관련된 결과는 세 가지입니다.

  • “페이지가 브라우저에서만 조립됩니다”. 전달된 HTML에 단어, 제목, 내부 링크가 각각 몇 개 있는지 알려 주고, Google은 이런 페이지를 시차를 두고 렌더링하며 많은 AI 크롤러는 거의 빈 페이지를 본다고 덧붙입니다.
  • “{N}개 페이지가 브라우저에서만 조립됩니다”. 사이트 순회에서 크롤링한 페이지 가운데 거의 빈 HTML 껍데기를 전달하는 페이지가 몇 개인지 알려 줍니다. noindex가 걸린 페이지와 로그인·가입 페이지는 세지 않습니다.
  • “로그인·가입 페이지 {N}개가 브라우저에서 만들어집니다”. 대체로 문제없습니다. 이런 페이지는 서버 사이드 렌더링이 없어도 방문자에게 잘 작동하기 때문입니다. 순위에 오르길 원하는 페이지라면 서버에서 렌더링하세요.

고친 뒤에는 다시 확인을 누르세요. 리포트는 최대 24시간 동안 캐시에 남으며, 이 버튼은 새로 검사를 실행합니다(시간당 몇 번까지 가능합니다). AI에 넘기기는 리포트를 Claude Code, Cursor, GitHub Copilot 같은 코딩 에이전트용 Markdown 작업 지시서로 바꿔 주며, 발견 사항마다 검증 가능한 목표 조건이 하나씩 붙습니다.

SEOgrinder가 하지 않는 일도 있습니다. ChatGPT, Gemini, Perplexity가 내 브랜드를 실제로 언급하는지는 측정하지 않습니다. 기술적 토대, 곧 콘텐츠를 읽을 수 있는지를 검사합니다.

자주 하는 실수

  • “페이지 소스 보기” 대신 “검사”로 테스트하기. 검사는 스크립트가 실행된 뒤의 결과를 보여 주는데, JavaScript를 실행하지 않는 봇이 받지 못하는 것이 바로 그것입니다.
  • “Google이 색인하니까 모든 봇이 읽을 수 있다”고 결론짓기. Google은 JavaScript를 실행하지만, Google 자신의 문서가 모든 봇이 그럴 수 있는 것은 아니라고 말합니다.
  • 제목과 메타 태그를 스크립트로만 설정하기. Google은 허용하지만, 스크립트를 실행하지 않는 봇은 이를 전혀 보지 못합니다. 첫 번째 HTML에 넣으세요.
  • 클릭 핸들러일 뿐인 링크. 크롤러가 스크립트 없이도 따라갈 수 있도록 진짜 <a href> 링크를 쓰세요.
  • 동적 렌더링을 장기 계획으로 삼기. Google은 이를 임시방편이라고 부릅니다.
  • 모르는 주소마다 껍데기와 상태 코드 200으로 응답하기. 클라이언트에서 렌더링하는 앱이 흔히 이렇게 하며, 이런 페이지는 소프트 404로 판단될 수 있습니다. 없는 페이지는 404나 410을 보내고, 옮겨진 페이지는 301로 새 페이지에 연결하며, 직접 만든 오류 페이지도 상태 코드는 404여야 합니다.
  • robots.txt에서는 봇을 허용하고 방화벽에서는 돌려보내기. 텍스트는 있는데 봇은 오류를 받습니다. SEOgrinder에는 이 경우를 위한 결과가 따로 있습니다. “AI 크롤러는 허용했지만 서버가 거부합니다 — 확인 필요”입니다. 함께 robots.txt로 AI 크롤러 차단·허용하기도 읽어 보세요.

자주 묻는 질문

Google은 내 JavaScript 페이지를 볼 수 있나요?

대체로 볼 수 있지만 나중에 봅니다. Google은 evergreen Chromium으로 JavaScript를 실행하며, 상태 코드가 200인 페이지는 렌더링 대기열에서 기다립니다. 색인은 결코 보장되지 않습니다. Google Search Console의 URL 검사는 Googlebot이 무엇을 보는지 알려 줍니다.

사이트맵이면 충분하지 않나요?

아닙니다. 사이트맵은 크롤러에게 어떤 주소가 있는지 알려 줍니다. 그 페이지들의 HTML에 텍스트를 넣어 주지는 않습니다.

ChatGPT와 Claude는 JavaScript를 실행하나요?

Vercel과 MERJ의 2024년 측정에서는 그 연구에 언급된 OpenAI와 Anthropic의 크롤러가 실행하지 않았습니다. 인용할 만한 더 새로운 측정은 없습니다. 어느 쪽 답에도 기대지 말고 내 페이지를 직접 테스트하세요.

사이트 전체를 다시 만들어야 하나요?

꼭 그렇지는 않습니다. 순위에 오르거나 인용되길 원하는 페이지에 서버 사이드 렌더링이나 사전 렌더링을 적용하는 것이 보통의 첫 단계입니다. 상호작용 부분은 브라우저에 남겨 둘 수 있습니다.

다음 단계

중요한 페이지 하나를 골라 위의 세 가지 테스트를 해 보세요. 소스에 텍스트가 없다면 SEOgrinder에서 무료 스캔을 실행하고 할 일 탭을 여세요. 가장 중요한 페이지부터 서버에서 렌더링하거나 미리 생성해 고친 다음, 다시 확인을 누르세요.

블로그의 다른 글