React, Vue, Next 같은 프레임워크로 만든 사이트가 늘면서 "분명 화면에는 잘 보이는데 검색에는 안 잡힌다"는 상담이 자주 들어옵니다. 사람 눈에는 멀쩡한 페이지가 검색엔진에는 비어 보이는 상황입니다. 구글은 JavaScript를 실행할 수 있지만, 그 처리에는 조건과 비용이 따릅니다. 이 글은 SPA(단일 페이지 앱)나 CSR(클라이언트 렌더링) 방식에서 자주 빠지는 색인 함정과, 그것을 피하는 실무 방향을 정리합니다. 프레임워크 자체가 문제가 아니라, 검색엔진이 콘텐츠를 볼 수 있게 만드느냐가 핵심입니다.
구글은 JS를 실행하지만, 공짜가 아닙니다
흔한 오해가 "구글은 JS를 못 읽는다"입니다. 정확히는 읽을 수 있지만, HTML을 바로 처리하는 것과 달리 JS는 별도의 렌더링 단계를 거칩니다. 이 단계는 자원이 들기 때문에 곧바로 처리되지 않고 대기열에 들어가는 경우가 있습니다.
즉 JS로 그려지는 콘텐츠는 색인이 늦거나, 렌더링이 실패하면 아예 빈 페이지로 인식될 수 있습니다. "언젠간 읽겠지"가 아니라 "처음부터 보이게" 만드는 게 안전한 이유입니다.
CSR만으로 만든 사이트에서 자주 보이는 문제
클라이언트 렌더링(CSR)만 쓰는 사이트는 최초 HTML이 거의 비어 있고, 브라우저가 JS를 실행해야 내용이 채워집니다. 검색엔진이 JS 실행 전 단계에서 페이지를 보면 본문이 없는 셈입니다.
이 경우 서치콘솔에서 "발견됨 - 색인되지 않음"이나 "크롤링됨 - 색인되지 않음"으로 잡히는 일이 잦습니다. 각각의 의미는 발견됨 - 색인되지 않음 원인과 크롤링됨 - 색인되지 않음 대응에서 다뤘습니다.
화면에는 정상적으로 콘텐츠가 뜨는데 이 상태로 잡힌다면, JS 렌더링 이전 단계에서 본문이 비어 있을 가능성을 먼저 의심해야 합니다.
함정 1 — 콘텐츠가 클릭·스크롤 후에만 로드됨
탭을 눌러야, 혹은 스크롤해야 내용이 불러와지는 구조는 검색엔진이 그 동작을 하지 않으면 콘텐츠를 못 봅니다. "더 보기"를 눌러야 나오는 본문, 무한 스크롤로만 접근되는 목록이 대표적입니다.
핵심 콘텐츠는 사용자 동작 없이도 처음 HTML에 담기게 하는 게 안전합니다. 인터랙션은 보조 수단이어야지, 콘텐츠에 접근하는 유일한 경로가 되면 안 됩니다.
함정 2 — 내부 링크가 진짜 링크가 아님
클릭 시 JS로 화면만 바꾸는 버튼(onclick)은 검색엔진이 따라갈 링크로 인식하지 않는 경우가 많습니다. 크롤러는 기본적으로 실제 링크, 즉 a 태그의 href 속성을 따라 페이지를 발견합니다.
내비게이션·상세 페이지 이동은 실제 href를 가진 링크로 만들어야 크롤러가 사이트 구조를 따라올 수 있습니다. 링크가 링크답지 않으면, 아무리 페이지가 많아도 발견되지 않습니다.
함정 3 — 타이틀·메타가 JS로만 바뀜
페이지마다 타이틀·메타 설명이 달라야 하는데, 이 값을 JS 실행 이후에만 설정하면 렌더링 전 단계에서는 모두 같은 기본값으로 보일 수 있습니다. 그러면 여러 페이지가 중복 제목으로 취급됩니다.
타이틀·메타·canonical 같은 핵심 태그는 가능하면 서버가 처음 응답할 때 각 페이지 값으로 담겨 나오는 게 좋습니다. 이 부분은 색인 품질에 직접 영향을 줍니다.
SSR·프리렌더 등 대안
함정 대부분은 "검색엔진이 처음 받는 HTML에 콘텐츠가 없다"는 한 가지 원인에서 나옵니다. 그래서 해법도 그 지점을 겨냥합니다.
- 서버 사이드 렌더링(SSR) — 서버가 완성된 HTML을 내려줌
- 정적 생성(SSG) — 빌드 시점에 HTML을 미리 생성
- 프리렌더링·다이내믹 렌더링 — 크롤러에게 렌더링된 HTML을 제공
Next.js·Nuxt 같은 프레임워크는 SSR·SSG를 기본 지원합니다. 플랫폼 선택 단계에서 이 점을 고려하는 것도 방법입니다. 관련 비교는 플랫폼별 SEO 비교에서 다뤘습니다. 다만 기존 사이트에 SSR을 뒤늦게 도입하는 건 손이 많이 가므로, 초기 설계 때 정해 두는 편이 비용이 적게 듭니다.
내 사이트 점검 순서
내 사이트가 JS 색인 문제를 겪는지 확인하는 순서는 다음과 같습니다.
- 서치콘솔 URL 검사의 "렌더링된 HTML"에서 본문·링크가 보이는지 확인
- 페이지 소스(초기 HTML)에 핵심 텍스트가 들어 있는지 확인
- 내부 링크가 실제 href인지 점검
- 페이지별 타이틀·메타가 초기 응답에 담기는지 확인
화면에 보이는 것과 검색엔진이 보는 것이 다를 수 있다는 점을 전제로 점검하면, 원인 대부분이 이 네 가지 안에서 드러납니다.
