환경 설정

개인정보 보호는 저희에게 중요합니다. 웹사이트의 기본 기능에 반드시 필요하지 않은 특정 유형의 저장소는 사용자가 직접 비활성화할 수 있습니다. 카테고리를 차단하면 웹사이트 이용 경험에 영향을 줄 수 있습니다. 더 보기 (쿠키 정책)

모든 쿠키 허용

싱글 페이지 애플리케이션 SEO: SPA를 Google에 색인시키고 AI가 읽게 하는 방법

싱글 페이지 애플리케이션 SEO: SPA의 순위가 오르지 않는 이유, SSR·정적 생성·프리렌더링으로 해결하는 방법, AI 크롤러가 앱을 읽을 수 있게 만드는 방법을 알아봅니다.

게시 날짜:
19/10/2026
-
업데이트 날짜:
19/10/2026
클라이언트 사이드 렌더링과 서버 사이드 렌더링을 비교한 Sorank 싱글 페이지 애플리케이션 SEO 가이드 표지

도구

Thibault Besson-Magdelain, Sorank 설립자

저자 소개

Thibault Besson-Magdelain

Sorank 설립자, 7년 이상의 SEO 경력 보유, GEO 전문가.
이 페이지의 내용

요약

싱글 페이지 애플리케이션(SPA)은 하나의 HTML 셸을 불러온 뒤 모든 화면을 브라우저에서 JavaScript로 만듭니다. Google은 JavaScript를 렌더링할 수 있지만 렌더링은 지연되고 불안정하며, ChatGPT, Claude, Perplexity의 크롤러는 JavaScript를 아예 실행하지 않습니다. 순위에 오르고 인용되려면 SPA의 각 화면에 고유한 URL, href가 있는 실제 링크, 고유한 제목과 설명, 올바른 상태 코드가 필요하며, 무엇보다 서버 사이드 렌더링, 정적 생성 또는 프리렌더링을 통해 핵심 콘텐츠가 서버가 보내는 HTML에 들어 있어야 합니다.

더 알아보고 싶다면 물어보세요

싱글 페이지 애플리케이션 SEO는 React, Vue, Angular, Svelte로 만든 JavaScript 앱을 전통적인 웹사이트만큼 쉽게 크롤링되도록 만드는 기법의 집합입니다. 이 문제는 잘 알려져 있습니다. Google은 JavaScript SEO 기본사항에서 JavaScript 페이지를 세 단계(크롤링, 렌더링, 색인 생성)로 처리한다고 설명하며, SPA의 모든 약점은 이 과정 어딘가에 있습니다. 이 가이드는 SPA에 초점을 맞춥니다. JavaScript 사이트 전반에 대해서는 JavaScript SEO 가이드를 참고하세요.

싱글 페이지 애플리케이션이란 무엇이며, 왜 SEO가 어려울까요?

전통적인 웹사이트는 URL마다 완전한 HTML 문서를 반환합니다. SPA는 모든 URL에 거의 같은 문서를 반환합니다. 비어 있는 <div id="root">, 몇 개의 meta 태그, 그리고 커다란 JavaScript 번들입니다. 브라우저가 번들을 내려받고 API를 호출한 다음 페이지를 그립니다. 방문자가 링크를 클릭하면 JavaScript가 새로고침 없이 콘텐츠를 바꿉니다.

빠른 휴대폰을 쓰는 사람에게는 결과가 즉각적으로 느껴집니다. 하지만 크롤러에게 첫 응답은 빈 셸입니다. 제목도, 텍스트도, 링크도 없습니다. 모든 것은 봇이 JavaScript를 실행하는지, 그리고 언제 실행하는지에 달려 있습니다. 이 한 가지 사실이 SPA SEO 문제 대부분을 설명합니다.

  • 지연되거나 누락된 콘텐츠: 텍스트는 렌더링 후에만 존재하는데, Google은 렌더링을 나중에 수행하고 다른 봇은 건너뜁니다.
  • 여러 화면에 하나의 URL: 오래된 SPA는 프래그먼트(/#/pricing)로 라우팅하는데, # 뒤의 부분은 서버로 전송되지 않으므로 모든 화면이 하나의 URL로 합쳐집니다.
  • 동일한 제목과 설명: 셸에는 <title>이 하나뿐이고, 라우터가 이를 업데이트하지 않으면 모든 페이지가 같은 제목을 공유합니다.
  • href가 없는 링크: 버튼과 onClick 핸들러는 사용자를 이동시키지만 크롤러에게는 따라갈 것을 전혀 남기지 않습니다.
  • 소프트 404 오류: 서버가 존재하지 않는 페이지를 포함한 모든 경로에 200으로 응답하므로, 오류 화면이 빈약한 페이지로 색인됩니다.
  • 무거운 JavaScript: 큰 번들은 첫 화면 표시와 상호작용을 느리게 만들어 Core Web Vitals에 악영향을 줍니다.

Google은 SPA를 어떻게 크롤링하고 렌더링할까요?

Googlebot은 먼저 원본 HTML을 가져와 그 안의 링크와 지시어를 읽습니다. 200 상태를 반환한 페이지는 헤드리스 Chromium인 Web Rendering Service의 대기열에 들어갑니다. Google은 페이지가 "이 대기열에 몇 초 동안 머무를 수 있지만 그보다 오래 걸릴 수도 있다"고 밝힙니다. 렌더링이 끝나면 결과 HTML을 다시 파싱해 콘텐츠와 링크를 찾은 뒤 색인에 추가합니다.

Google 문서에서 SPA에 중요한 세부 사항은 네 가지입니다.

  1. href가 있는 <a> 요소만 신뢰할 수 있는 링크입니다. JavaScript로 삽입한 링크도 이 형식을 따르면 문제없습니다.
  2. 프래그먼트는 별도의 페이지가 아닙니다. Google은 # 경로 대신 History API(pushState)를 사용하라고 권합니다. 예전의 AJAX 크롤링 방식(#! URL)은 2015년 10월에 지원 중단되었습니다.
  3. 원본 HTML의 noindex가 우선합니다. Google은 noindex를 발견하면 렌더링을 건너뛸 수 있으므로, 나중에 JavaScript로 제거해도 효과가 없습니다.
  4. 렌더링에는 캐시된 파일이 사용됩니다. Googlebot은 JavaScript와 CSS를 적극적으로 캐시하므로, 오래된 번들을 피하려면 핑거프린트가 붙은 파일 이름(파일 이름에 콘텐츠 해시 포함)을 사용하세요.

실무적인 결론은 이렇습니다. Google은 클라이언트 사이드 렌더링 SPA도 색인할 수 있지만, 모든 페이지에 두 번째 단계, 지연, 실패 지점이 하나씩 추가됩니다. 렌더링 중 시간 초과, 차단된 API 호출, JavaScript 오류가 생기면 색인된 버전은 비어 있게 됩니다. Search Console의 URL 검사 도구로 Google이 보는 내용을 확인하고, 페이지가 계속 색인되지 않는다면 Google 색인 생성의 작동 방식에 관한 가이드를 읽어 보세요.

ChatGPT, Claude, Perplexity는 JavaScript를 읽을까요?

대부분 읽지 않습니다. Vercel과 MERJ는 2024년 12월 Vercel 네트워크의 트래픽을 바탕으로 발표한 연구에서 "현재 주요 AI 크롤러 중 JavaScript를 렌더링하는 것은 없다"는 사실을 확인했습니다. GPTBot, OAI-SearchBot, ChatGPT-User(OpenAI), ClaudeBot(Anthropic), PerplexityBot, Meta-ExternalAgent, Bytespider는 모두 원본 HTML만 읽습니다. 이들은 JavaScript 파일을 내려받기는 하지만(ChatGPT 요청의 약 11.5%, Claude 요청의 약 23.8%) 실행하지는 않습니다. 예외는 Google의 렌더링 인프라를 활용하는 Gemini와, 브라우저 기반 크롤러를 사용하는 AppleBot입니다.

클라이언트 사이드 렌더링 SPA라면, ChatGPT, Claude, Perplexity에 데이터를 공급하는 AI 크롤러가 빈 페이지를 본다는 뜻입니다. 제품이 Google에서 상위에 오르더라도 AI 답변에서는 보이지 않을 수 있습니다. 어시스턴트가 그 내용을 한 단어도 읽지 못했기 때문입니다. 소셜 네트워크와 메신저 앱의 링크 미리보기 봇 대부분도 마찬가지로, 원본 HTML의 Open Graph 태그를 읽습니다. 콘텐츠가 HTML에 들어갔다면 robots.txt가 원하는 AI 크롤러를 허용하는지도 확인하세요.

SPA는 어떤 렌더링 전략을 써야 할까요?

해결책은 첫 응답에서 실제 HTML을 보내는 것입니다. Google은 동적 렌더링 문서에서 동적 렌더링(사전 렌더링한 버전을 봇에게만 제공하는 방식)을 "임시방편이며 권장되는 해결책이 아니다"라고 설명하며, 대신 서버 사이드 렌더링, 정적 렌더링 또는 하이드레이션을 권합니다. 아래 정의는 web.dev의 참고 문서 Rendering on the Web을 따릅니다.

전략작동 방식첫 HTML의 콘텐츠적합한 용도한계
클라이언트 사이드 렌더링(CSR)브라우저가 JavaScript와 API로 페이지를 만듦없음대시보드와 로그인이 필요한 페이지Google 색인 지연, 대부분의 AI 크롤러에게 보이지 않음
서버 사이드 렌더링(SSR)서버가 요청마다 HTML을 렌더링하고, 이후 JavaScript가 하이드레이션함있음카탈로그, 목록 페이지, 자주 바뀌거나 개인화된 콘텐츠서버 비용, 캐시하지 않으면 응답 시간이 느려짐
정적 생성(SSG)빌드 시 URL마다 HTML을 생성해 CDN에서 제공있음마케팅 페이지, 블로그, 문서, 랜딩 페이지콘텐츠가 바뀌면 다시 빌드해야 함(증분 옵션 있음)
빌드 시 프리렌더링헤드리스 브라우저가 각 경로의 초기 상태를 정적 HTML로 캡처있음공개 경로 수가 제한된 기존 SPA데이터가 빌드 시점에 고정되고, 경로를 나열해야 함
동적 렌더링봇은 사전 렌더링된 스냅숏을, 사용자는 SPA를 받음있음(목록에 있는 봇만)레거시 앱의 임시 해결책공식적으로 임시방편, 유지보수 비용, 봇에게 다른 콘텐츠를 제공할 위험

대부분의 최신 프레임워크는 경로별로 전략을 섞을 수 있게 해 줍니다. 마케팅 페이지는 정적으로, 카탈로그는 서버 렌더링으로, 로그인 후 앱은 클라이언트 렌더링으로 처리하는 식입니다. 이런 하이브리드 구성은 검색 유입이 일어나는 곳에서는 크롤러에게 완전한 HTML을 제공하고, SPA 경험이 가치를 더하는 곳에서는 그 경험을 유지합니다.

프레임워크별 선택지

라이브러리첫 로드에서 HTML을 제공하는 프레임워크 또는 기능
ReactNext.js(서버 컴포넌트, SSR, 정적 생성), 프레임워크 모드의 React Router, Gatsby
VueNuxt(기본값은 유니버설 렌더링, 정적 생성 지원)
AngularAngular SSR(서버 렌더링과 빌드 시 프리렌더링)
SvelteSvelteKit(기본값은 서버 렌더링, 경로별 프리렌더링)
어느 것이든Astro(기본값은 정적 HTML, 인터랙티브 아일랜드는 필요한 곳에서만 로드)

AI 웹사이트 빌더로 만든 사이트는 특히 주의해야 합니다. 상당수가 클라이언트 사이드 렌더링 React 앱을 내보내기 때문입니다. 이런 도구로 사이트를 만들었다면, Google과 ChatGPT가 읽을 수 있다고 가정하기 전에 Lovable SEO와 GEO에 관한 설명을 확인하세요.

SPA SEO 체크리스트: 경로별로 고쳐야 할 것

1. 모든 화면에 깔끔하고 크롤링 가능한 URL 부여하기

History API를 사용하고(/pricing, 절대 /#/pricing은 쓰지 않기), 콘텐츠 하나에 URL 하나를 두며, 방문자가 직접 들어오든 앱 내 이동으로 들어오든 같은 URL을 쓰세요. 모든 URL은 새 탭에서 열었을 때 올바른 콘텐츠를 불러와야 합니다. 크롤러가 하는 테스트가 바로 이것입니다.

2. 실제 링크 사용하기

색인 대상 페이지로 이어지는 모든 탐색 요소는 <a href="/path">여야 합니다. 프레임워크의 링크 컴포넌트(Link, NuxtLink, routerLink)는 이 마크업을 출력하지만, div나 button 요소에 붙인 사용자 정의 클릭 핸들러는 그렇지 않습니다. 좋은 링크는 사이트 구조도 전달합니다. 링크되지 않은 페이지는 크롤러가 거의 찾지 못합니다.

3. 경로마다 제목, 설명, canonical 업데이트하기

각 경로에는 고유한 제목, 메타 설명, canonical, Open Graph 태그가 필요하며, 가능하면 서버에서 생성해야 합니다. 설정할 항목은 메타 태그 페이지에 정리되어 있습니다. canonical 태그는 하나만 유지하세요. Google은 HTML에서 설정할 것을 권장하며, JavaScript로 변경하더라도 결과가 원래 값과 모순되어서는 안 됩니다.

4. 정직한 상태 코드 반환하기

없는 상품이나 삭제된 글이 오류 메시지와 함께 200으로 응답해서는 안 됩니다. SSR을 쓴다면 서버에서 실제 404나 410을 반환하세요. 순수 SPA라면 Google은 두 가지 대안을 인정합니다. 404를 반환하는 URL로 JavaScript 리디렉션을 하거나, 오류 화면에 noindex robots 메타 태그를 추가하는 것입니다.

5. 핵심 콘텐츠와 구조화된 데이터를 HTML에 넣기

제목, 본문, 가격, 자주 묻는 질문, JSON-LD 구조화된 데이터는 클릭이나 스크롤 후에 불러오는 것이 아니라 서버 응답에 들어 있어야 합니다. 요청 시 렌더링되는 탭 뒤나 "더 보기" 버튼 뒤에 숨은 콘텐츠는 놓치기 쉽습니다.

6. JavaScript를 가볍게 유지하기

경로별로 번들을 분할하고, 첫 화면에 필요 없는 것은 지연시키며, 하이드레이션 중에 페이지 전체를 다시 렌더링하지 마세요. Chrome 현장 데이터(CrUX)는 앱 내 이동의 지표를 방문자가 처음 불러온 URL에 귀속시키므로, 주요 템플릿은 각각 따로 테스트해야 합니다.

7. 봇이 받는 내용 테스트하기

주요 템플릿마다 세 가지 버전을 비교하세요. 원본 HTML(소스 보기 또는 명령줄 도구로 페이지 가져오기), Google이 렌더링한 HTML(URL 검사 후 "크롤링된 페이지 보기"), 그리고 JavaScript를 끈 페이지입니다. 핵심 텍스트가 두 번째 버전에만 나타난다면 AI 크롤러는 그것을 보지 못합니다. 무료 AI 크롤링 가능성 진단과 색인 가능성 검사기로 어떤 URL이든 이 점검을 실행할 수 있습니다.

SPA에 SEO 문제가 있는지 어떻게 알 수 있을까요?

증상가능한 원인해결 방법
Search Console에 "크롤링됨 - 현재 색인이 생성되지 않음" 페이지가 많이 표시됨렌더링 전 HTML이 비어 있거나 거의 동일함공개 경로에 SSR, SSG 또는 프리렌더링 적용
site: 검색 결과가 모두 같은 제목으로 표시됨경로별로 제목이 업데이트되지 않음서버에서 경로 단위로 head 관리
홈페이지만 색인됨해시 라우팅 또는 href가 없는 링크History API와 실제 <a> 링크
오류 페이지가 색인에 나타남소프트 404(모든 곳에서 상태 200)서버 404, 404 URL로의 JavaScript 리디렉션, 또는 noindex
Google에서는 순위가 있지만 ChatGPT나 Perplexity에는 인용되지 않음JavaScript 실행 후에만 콘텐츠가 보임첫 HTML 응답에 콘텐츠 포함
Google 렌더링 화면에 오래된 콘텐츠가 표시됨캐시된 JavaScript 또는 CSS 파일핑거프린트가 붙은 파일 이름

SPA SEO와 GEO: Google에서 발견되고 AI에 인용되기

수년 동안 클라이언트 사이드 렌더링은 감당할 수 있는 위험이었습니다. Google이 결국에는 JavaScript를 렌더링했기 때문입니다. 이제는 정보 탐색의 일부가 ChatGPT, Claude, Gemini, Perplexity에서 이루어지면서 그 대가가 달라졌습니다. JavaScript 실행 후에만 존재하는 페이지는 대부분의 어시스턴트가 읽을 수 있는 출처에서 빠집니다. 원본 HTML의 크롤링 가능성은 생성형 엔진 최적화의 첫 번째 조건이 되었습니다.

HTML이 완전해지면 나머지는 일반적인 규칙을 따릅니다. 하나의 질문에 명확하게 답하고, 출처가 있는 사실과 구조화된 데이터를 갖춘 페이지가 어시스턴트가 인용하는 페이지입니다. Sorank의 GEO 최적화 기능은 그런 콘텐츠를 작성하고 게시하도록 돕고, AI 언급 추적은 렌더링을 수정한 뒤 ChatGPT, Claude, Gemini가 브랜드를 인용하는지 보여 줍니다.

싱글 페이지 애플리케이션 SEO의 핵심 규칙은 한 문장으로 요약됩니다. Google이 순위를 매기고 AI가 인용하기를 원하는 것은 모두 서버가 보내는 HTML에 있어야 합니다. SPA는 로그인 후 경험에 남겨 두고, 공개 페이지는 서버나 빌드 시점에 렌더링한 다음, 매 릴리스 전후로 봇이 받는 내용을 테스트하세요.

자주 묻는 질문

싱글 페이지 애플리케이션은 SEO에 불리한가요?

Google이 싱글 페이지 애플리케이션에 불이익을 주지는 않지만, 기본 구성인 하나의 HTML 셸 기반 클라이언트 사이드 렌더링은 색인 생성을 더 느리고 불안정하게 만듭니다. 대부분의 AI 크롤러는 JavaScript를 실행하지 않으므로 빈 페이지를 봅니다. 공개 경로에 서버 사이드 렌더링, 정적 생성 또는 프리렌더링을 적용하면 SPA도 일반 웹사이트만큼 순위에 오를 수 있습니다.

React는 SEO에 좋은가요?

React 자체는 중립적입니다. 중요한 것은 HTML이 어디에서 만들어지느냐입니다. 브라우저에서만 렌더링되는 React 앱은 SPA의 일반적인 문제를 겪지만, 같은 컴포넌트를 Next.js나 프레임워크 모드의 React Router로 서버에서 렌더링하면 크롤러에게 완전한 HTML을 제공합니다. 색인되기를 원하는 페이지에는 서버 렌더링이나 정적 렌더링을 지원하는 프레임워크를 선택하세요.

SPA에 동적 렌더링을 사용해야 하나요?

임시 조치로만 사용하세요. Google은 동적 렌더링을 권장 해결책이 아닌 임시방편으로 설명합니다. 봇용으로 별도 버전을 유지하면 비용과 위험이 늘어나기 때문입니다. 서버 사이드 렌더링, 정적 생성, 빌드 시 프리렌더링은 모든 방문자에게 같은 HTML을 제공하며 장기적인 해결책입니다.

야심 찬 기업을 위한 블로그

Sorank 무료 SEO 도구

무료 도구 모두 보기

먼저 Sorank를 경험한 사람들

야망 있는 창업자들의 후기

오가닉 성장이커머스

5개월 만에 방문자 0에서 10000명

Celio Fabianomonrobotlavevitre.fr
오가닉 성장소프트웨어

8개월 만에 고객 0에서 5000명

Thibault BMsorank.com
오가닉 성장레저 및 항공

4개월 만에 클릭 0에서 1104회로

Dominiqueflight-sensations-idf.com
오가닉 성장음악 소프트웨어

4개월 만에 클릭 30배

Valentin Cordiertiger-sounds.com
오가닉 성장건강 및 웰니스

4개월 만에 클릭 30배

Rodrigue Bretonalthevia.com