자바스크립트 SEO(JavaScript SEO)는 React, Vue, Angular 같은 자바스크립트로 화면을 그리는 웹사이트의 콘텐츠와 링크를 구글봇과 AI 크롤러가 빠짐없이 크롤링, 렌더링, 색인하도록 만드는 테크니컬 SEO의 한 분야다.
일반 HTML 페이지는 서버가 보낸 문서에 본문이 그대로 들어 있지만, 클라이언트 측 렌더링(CSR) 사이트는 서버가 빈 껍데기 HTML과 스크립트만 보내고 본문은 브라우저가 자바스크립트를 실행한 뒤에야 생긴다. 자바스크립트 SEO는 이 “실행 뒤에야 생기는 본문”을 크롤러가 놓치지 않게 하는 일이다.
2026년 기준 이 문제의 무게중심은 구글에서 AI 검색으로 옮겨 갔다. 구글봇은 자바스크립트를 실행하지만, ChatGPT와 Claude, Perplexity의 크롤러는 실행하지 않기 때문이다.
구글은 크롤링, 렌더링, 색인 생성의 세 단계로 처리하며, 렌더링은 별도 대기열에서 나중에 이뤄진다.
구글은 “Google은 다음 세 가지 주요 단계로 자바스크립트 웹 앱을 처리합니다. 크롤링, 렌더링, 색인 생성”이라고 설명하고, “Googlebot은 페이지를 크롤링 및 렌더링 대기열에 추가하며, 페이지가 크롤링 및 렌더링을 기다리고 있는 경우 바로 확인할 방법은 없습니다”라고 덧붙인다 (Google 검색 센터, JavaScript 검색엔진 최적화의 기본사항 이해하기).
순서를 풀면 이렇다.
<a href>에 있는 링크를 크롤링 대기열에 넣는다. 자바스크립트가 나중에 끼워 넣는 링크는 이 시점에 없다.HTTP 상태 코드가 200이 아닌 페이지는 렌더링을 건너뛸 수 있다. 네이버도 비슷하다. 네이버 검색로봇은 자바스크립트 리소스가 아직 수집돼 있지 않으면 “정적인 HTML의 내용을 먼저 수집/분석하여 색인 처리”하고, 재방문 때 확보된 스크립트로 다시 렌더링한다 (네이버 서치어드바이저, 자바스크립트 검색 최적화). 두 엔진 모두 첫 HTML에 없는 내용은 “나중에, 운이 좋으면” 읽는 셈이다.
주요 AI 크롤러는 하나도 실행하지 않는다. 첫 HTML에 없는 내용은 AI 검색에 존재하지 않는 것과 같다.
Vercel과 MERJ가 2024년 12월 자사 네트워크 트래픽을 분석한 결과 “주요 AI 크롤러 중 현재 자바스크립트를 렌더링하는 것은 없다”고 결론 내렸다. 대상은 OpenAI(OAI-SearchBot, ChatGPT-User, GPTBot), Anthropic(ClaudeBot), Meta, ByteDance, Perplexity의 크롤러다 (Vercel, The Rise of the AI Crawler).
| 크롤러 | 월간 요청 (Vercel 네트워크) | 자바스크립트 실행 |
|---|---|---|
| Googlebot (Gemini 포함) | 45억 | 실행함 |
| GPTBot (OpenAI) | 5억 6,900만 | 실행 안 함 |
| ClaudeBot (Anthropic) | 3억 7,000만 | 실행 안 함 |
| AppleBot | 3억 1,400만 | 실행함 (브라우저 기반) |
| PerplexityBot | 2,440만 | 실행 안 함 |
흥미로운 점은 이 크롤러들이 자바스크립트 파일을 가져가기는 한다는 것이다. 같은 조사에서 GPTBot 요청의 11.50%, ClaudeBot 요청의 23.84%가 자바스크립트 파일이었지만, 받아만 가고 실행하지 않는다. 가져간 파일은 학습이나 분석에 쓰일 수는 있어도 그 결과로 생기는 본문은 읽지 못한다.
AI 검색의 인용은 첫 HTML에 실린 텍스트에서 나온다. GEO 관점에서 자바스크립트 SEO는 선택이 아니라 전제 조건이고, 이것이 1페이지 상위 문서 하나가 “구글은 읽고 AI는 못 읽는 이유”라는 제목을 단 배경이다.
본문이 “언제, 어디서” HTML이 되느냐가 갈림길이다. 서버에서 미리 만들수록 크롤러에 안전하다.
| 방식 | 본문이 HTML이 되는 시점 | 구글봇 | AI 크롤러 | 대표 구현 |
|---|---|---|---|---|
| 정적 생성 (SSG) | 빌드 시 | 바로 읽음 | 바로 읽음 | Astro, Next.js 정적 내보내기, Hugo |
| 서버 사이드 렌더링 (SSR) | 요청 시 서버에서 | 바로 읽음 | 바로 읽음 | Next.js, Nuxt, Remix |
| 하이드레이션 | 서버 HTML + 클라이언트 JS 결합 | 바로 읽음 | 서버 HTML 부분만 읽음 | 위 프레임워크 기본값 |
| 클라이언트 측 렌더링 (CSR) | 브라우저에서 JS 실행 후 | 렌더링 대기열 뒤 읽음 | 못 읽음 | Create React App, 순수 Vue SPA |
| 동적 렌더링 | 크롤러에게만 서버 렌더 HTML 제공 | 읽음 | 봇 판별에 따라 다름 | Rendertron, Prerender.io |
동적 렌더링은 한때 구글이 권한 우회책이었지만 지금은 아니다. 구글은 “동적 렌더링은 임시방편이며 검색엔진에서 JavaScript 생성 콘텐츠 문제를 해결하기 위한 장기적인 솔루션이 아닙니다. 대신 서버 측 렌더링, 정적 렌더링, 하이드레이션을 사용해 문제를 해결하는 것이 좋습니다”라고 밝힌다 (Google 검색 센터, 동적 렌더링을 사용하여 대처).
네이버 역시 SPA라도 “HTML의 주요 영역 생성은 검색로봇이 잘 인식할 수 있도록 서버에서 렌더링 (Server Side Rendering)을 처리하는 것을 권장”한다. 구글, 네이버, AI 크롤러 셋의 요구를 한 번에 만족하는 답은 서버에서 본문을 만들어 보내는 것 하나다.
1페이지 문서들이 공통으로 꼽는 문제는 네 가지이고, 전부 구글 공식 문서에 해법이 있다.
| 문제 | 증상 | 해법 |
|---|---|---|
| 본문이 HTML에 없음 | 소스 보기에 <div id="root"></div>뿐, 색인된 스니펫이 비거나 로딩 문구 | SSR 또는 SSG로 전환, 최소한 핵심 본문과 메타는 서버에서 |
| 프래그먼트(#) 라우팅 | /#/products 같은 URL이 모두 한 페이지로 취급됨 | History API(pushState)로 경로형 URL 사용 |
| soft 404 | 없는 페이지가 200으로 응답해 “찾을 수 없음” 화면이 색인됨 | 서버가 404를 돌려주는 URL로 리디렉션하거나 JS로 noindex 메타 삽입 |
| 리소스 차단 | robots.txt가 JS, CSS 경로를 Disallow해 렌더링 실패 | 렌더링에 필요한 리소스는 전부 Allow |
프래그먼트에 대해 구글은 “링크가 href 속성이 있는 <a> HTML 요소인 경우에만 Google에서 링크를 발견할 수 있습니다”라고 못 박고, “다양한 페이지 콘텐츠 로드 시 프래그먼트를 사용하지 마세요”라고 안내한다 (Google 검색 센터, JavaScript 검색엔진 최적화의 기본사항 이해하기). 네이버 검색로봇도 “수집 대상 URL을 해석하는 과정에서 fragment 부분을 제거”하므로 # 뒤는 네이버에서 아예 사라진다.
soft 404는 SPA 특유의 문제다. 클라이언트 라우팅은 서버가 모든 경로에 200을 돌려주기 때문에, 구글은 “서버가 404 HTTP 상태 코드로 응답하는 경우 URL에 자바스크립트 리디렉션을 사용”하거나 “자바스크립트를 사용하여 오류 페이지에 <meta name="robots" content="noindex">를 추가”하는 두 가지 방법을 제시한다.
캐노니컬과 robots 메타도 주의 대상이다. 구글은 자바스크립트로 캐노니컬 태그를 설정할 수는 있지만 “원래 HTML에서 표준 URL로 지정한 URL을 JavaScript를 사용하여 다른 URL로 변경하면 안 됩니다”라고 적는다. 첫 HTML에 noindex가 있으면 렌더링 자체를 건너뛰므로, JS로 noindex를 지우는 방식은 통하지 않는다.
자바스크립트를 끈 상태의 HTML과 렌더링 뒤의 화면을 비교하면 된다. 둘의 차이가 곧 AI 크롤러가 못 보는 부분이다.
curl -A "GPTBot" https://example.com/page/로 받은 HTML에서 태그를 걷어낸 텍스트가 AI 크롤러가 읽는 전부다. 본문 문장이 여기에 있는지 본다.이 사이트의 위키 문서 /wiki/geo/를 2026년 10월 6일 같은 방법으로 쟀다. GPTBot User-Agent로 curl로 받은 첫 HTML에서 스크립트와 스타일을 뺀 본문 텍스트는 3,147자, 브라우저에서 자바스크립트를 실행한 뒤 보이는 텍스트는 3,048자, H2는 양쪽 다 6개였다 (2026-10-06 자체 실측). Astro 정적 생성이라 자바스크립트가 본문을 하나도 만들지 않으며, AI 크롤러와 구글봇이 같은 내용을 본다. 자바스크립트 SEO가 잘 돼 있다는 것은 이 두 숫자가 거의 같다는 뜻이다.
React 자체가 아니라 렌더링 방식이 문제다. Create React App처럼 클라이언트 측 렌더링만 하면 구글은 렌더링 대기열을 거쳐 늦게 읽고 AI 크롤러는 못 읽는다. Next.js나 Remix로 서버 사이드 렌더링을 쓰면 React를 유지한 채 첫 HTML에 본문이 들어가므로 SEO 문제가 사라진다.
빌드 시 HTML을 미리 만드는 정적 생성(SSG)이나 사전 렌더링(prerendering)이 대안이다. 크롤러에게만 렌더된 HTML을 주는 동적 렌더링도 가능하지만 구글이 임시방편으로 규정했고 AI 크롤러 봇 판별도 보장되지 않으므로 신규 구축에는 권하지 않는다.
서치폴라리스가 AI 검색 가시성을 진단하고 GEO 실행까지 대행합니다.