Next.js가 SEO에 유리한 이유
전통적 SPA의 SEO 문제
React, Vue 같은 SPA(Single Page Application)는 클라이언트 측 JavaScript가 DOM을 생성합니다. 검색 엔진 크롤러가 페이지에 접근할 때 빈 HTML만 받게 되어, 콘텐츠를 인식하지 못하는 문제가 발생합니다.
Google의 크롤러(Googlebot)는 JavaScript 렌더링을 지원하지만, "렌더링 큐"에서 순서를 기다려야 하므로 인덱싱이 수일~수주 지연될 수 있습니다. 네이버, 다음 등 국내 검색 엔진은 JavaScript 렌더링 지원이 Google보다 제한적입니다.
Next.js의 렌더링 전략
Next.js는 다양한 렌더링 방식을 제공하여 SEO 문제를 해결합니다:
- SSG (Static Site Generation): 빌드 시 HTML 사전 생성 → 가장 빠른 TTFB
- SSR (Server-Side Rendering): 요청 시 서버에서 HTML 생성 → 실시간 데이터 반영
- ISR (Incremental Static Regeneration): SSG + 주기적 재생성 → 정적 성능 + 동적 데이터
- Streaming SSR: 서버에서 점진적으로 HTML 전송 → 빠른 FCP
크롤러가 페이지에 접근하면 완성된 HTML을 즉시 받을 수 있어, JavaScript 실행 없이도 콘텐츠가 인덱싱됩니다.
---
App Router 메타데이터 최적화
정적 메타데이터
Next.js 14+ App Router에서는 `metadata` 객체를 export하여 메타데이터를 설정합니다:
```typescript // app/blog/[slug]/page.tsx export const metadata: Metadata = { title: '블로그 제목 | 사이트명', description: '150자 이내의 설명. 핵심 키워드를 자연스럽게 포함.', openGraph: { title: '블로그 제목', description: '소셜 미디어 공유 시 표시될 설명', images: [{ url: '/og-image.png', width: 1200, height: 630 }], }, }; ```
동적 메타데이터
URL 파라미터에 따라 메타데이터를 동적으로 생성해야 할 때:
```typescript export async function generateMetadata({ params }): Promise<Metadata> { const article = await getArticle(params.slug); return { title: `${article.title} | 사이트명`, description: article.excerpt, openGraph: { title: article.title, images: [{ url: article.thumbnail }], }, }; } ```
메타데이터 최적화 원칙
타이틀 태그 (`<title>`):
- 길이: 50~60자 (한글 기준 25~30자)
- 핵심 키워드를 앞쪽에 배치
- 브랜드명은 뒤에 파이프(|)로 구분
- 각 페이지마다 고유한 타이틀 (중복 타이틀 = SEO 감점)
메타 설명 (`<meta description>`):
- 길이: 120~158자 (한글 기준 60~80자)
- 검색 결과에 표시되는 스니펫 → 클릭 유도 문구
- 핵심 키워드 1~2개 자연스럽게 포함
- CTA(Call to Action) 포함 시 CTR 향상
---
구조화 데이터 (JSON-LD)
구조화 데이터란
구조화 데이터는 검색 엔진에게 페이지 콘텐츠의 의미와 맥락을 기계가 읽을 수 있는 형태로 전달합니다. Google은 이를 바탕으로 리치 스니펫(Rich Snippet) — 별점, FAQ, 빵부스러기 등 — 을 검색 결과에 표시합니다.
블로그 글의 Article 구조화 데이터
```typescript // components/ArticleJsonLd.tsx export function ArticleJsonLd({ article }) { const jsonLd = { '@context': 'https://schema.org', '@type': 'Article', headline: article.title, description: article.excerpt, image: article.thumbnail, datePublished: article.publishedAt, dateModified: article.updatedAt, author: { '@type': 'Organization', name: article.author, }, };
return ( <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} /> ); } ```
자주 사용되는 구조화 데이터 타입
- Article: 블로그 글, 뉴스 기사
- FAQPage: 자주 묻는 질문 → 검색 결과에서 확장형 FAQ 표시
- BreadcrumbList: 빵부스러기 내비게이션
- WebSite: 사이트 전체 정보 + 사이트링크 검색상자(Sitelinks Searchbox)
- Product: 제품 페이지 (가격, 재고, 리뷰)
- LocalBusiness: 오프라인 사업장 정보
---
사이트맵과 robots.txt
동적 사이트맵 생성
Next.js App Router에서 사이트맵을 동적으로 생성합니다:
```typescript // app/sitemap.ts export default async function sitemap(): Promise<MetadataRoute.Sitemap> { const articles = await getAllArticles();
const blogEntries = articles.map((article) => ({ url: `https://example.com/blog/${article.slug}`, lastModified: article.updatedAt || article.publishedAt, changeFrequency: 'monthly' as const, priority: 0.8, }));
return [ { url: 'https://example.com', lastModified: new Date(), priority: 1.0 }, { url: 'https://example.com/blog', priority: 0.9 }, ...blogEntries, ]; } ```
robots.txt 최적화
```typescript // app/robots.ts export default function robots(): MetadataRoute.Robots { return { rules: { userAgent: '*', allow: '/', disallow: ['/api/', '/admin/'], }, sitemap: 'https://example.com/sitemap.xml', }; } ```
---
Core Web Vitals 최적화
세 가지 핵심 지표
Google은 2021년부터 Core Web Vitals를 검색 순위 요소에 반영합니다:
1. LCP (Largest Contentful Paint) — 목표: 2.5초 이내
뷰포트에서 가장 큰 콘텐츠 요소(히어로 이미지, 제목 텍스트 블록 등)가 렌더링되는 시점입니다.
최적화 전략:
- `next/image` 사용: 자동 WebP/AVIF 변환, 지연 로딩, 크기 최적화
- 히어로 이미지에 `priority` 속성 추가 (지연 로딩 해제)
- 폰트 최적화: `next/font`로 폰트를 셀프 호스팅하여 FOIT/FOUT 방지
2. INP (Interaction to Next Paint) — 목표: 200ms 이내
사용자 인터랙션(클릭, 탭, 키보드 입력) 후 다음 프레임이 렌더링되기까지의 시간입니다.
최적화 전략:
- 무거운 작업을 `useTransition`으로 비동기 처리
- 서버 컴포넌트 활용으로 클라이언트 JavaScript 번들 축소
- `dynamic import`로 필요한 시점에만 컴포넌트 로드
3. CLS (Cumulative Layout Shift) — 목표: 0.1 이하
페이지 로딩 중 레이아웃이 얼마나 불안정하게 이동하는지 측정합니다.
최적화 전략:
- 이미지·비디오에 항상 `width`와 `height` 지정
- 폰트 로드 시 `font-display: swap` + `size-adjust` 설정
- 광고·임베드에 고정 크기 컨테이너 사전 할당
---
이미지 SEO
next/image 활용
```typescript import Image from 'next/image';
<Image src="/images/blog/thumbnail.webp" alt="간헐적 단식의 16:8 방법을 설명하는 타임라인 인포그래픽" width={1200} height={630} priority // LCP 이미지인 경우 sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 800px" /> ```
이미지 SEO 체크리스트
- alt 텍스트: 이미지 내용을 구체적으로 서술 (키워드 스터핑 금지)
- 파일명: `IMG_1234.jpg` → `intermittent-fasting-timeline.webp` (의미 있는 파일명)
- WebP/AVIF 형식: JPEG 대비 25~50% 용량 절감
- 반응형 이미지: `sizes` 속성으로 뷰포트별 적정 크기 제공
- 지연 로딩: ATF(Above The Fold) 이미지를 제외한 나머지는 lazy loading
---
내부 링크 전략
토픽 클러스터 모델
SEO에서 내부 링크는 사이트의 정보 구조(Information Architecture)를 검색 엔진에 전달합니다. 효과적인 내부 링크 전략은 토픽 클러스터(Topic Cluster) 모델입니다:
- 필러 페이지(Pillar Page): 넓은 주제를 포괄적으로 다루는 메인 페이지
- 클러스터 콘텐츠: 세부 주제를 깊이 다루는 개별 글
- 양방향 링크: 필러 ↔ 클러스터 간 상호 링크
예시: "건강 관리" 필러 페이지 → "수면의 질 높이기", "스트레칭 가이드", "눈 건강" 등 클러스터 글과 상호 링크
앵커 텍스트 최적화
- "여기를 클릭하세요" ❌ → "간헐적 단식 가이드" ✅
- 앵커 텍스트에 대상 페이지의 핵심 키워드를 자연스럽게 포함
- 같은 앵커 텍스트가 다른 URL을 가리키지 않도록 주의
---
SEO 모니터링과 도구
필수 SEO 도구
- Google Search Console: 검색 실적, 인덱싱 상태, Core Web Vitals 데이터
- Google Analytics 4: 유입 경로, 사용자 행동, 전환 추적
- 네이버 서치어드바이저: 네이버 검색 최적화 (국내 사이트 필수)
- Lighthouse: 성능, 접근성, SEO 점수 측정 (Chrome DevTools 내장)
- PageSpeed Insights: 실제 사용자 데이터(CrUX) 기반 성능 분석
SEO 모니터링 체크리스트 (월간)
- [ ] Search Console에서 크롤링 오류 확인 및 수정
- [ ] 인덱스 커버리지 리포트 검토 (유효 페이지 vs 제외 페이지)
- [ ] Core Web Vitals 실패 URL 확인 및 개선
- [ ] 404 페이지 확인 → 301 리다이렉트 설정
- [ ] 검색 실적 리포트: 노출수, 클릭수, CTR, 평균 게재순위 추적
---
마무리 — SEO는 기술과 콘텐츠의 교차점
Next.js는 기술적 SEO의 많은 부분을 프레임워크 수준에서 지원하지만, 기술만으로는 검색 1페이지에 오를 수 없습니다. 궁극적으로 검색 엔진이 보상하는 것은 사용자에게 가치를 제공하는 고품질 콘텐츠입니다.
기술적 SEO(메타데이터, 구조화 데이터, 사이트맵, Core Web Vitals)는 콘텐츠가 검색 엔진에 제대로 전달되도록 하는 인프라이고, 실제 순위를 결정하는 것은 콘텐츠의 깊이, 독창성, 사용자 만족도입니다.
가장 좋은 SEO 전략은 "검색 엔진을 위한 최적화"가 아닌 "사용자를 위한 최적화"입니다. 사용자에게 진정으로 유용한 콘텐츠를 만들면, 검색 순위는 자연스럽게 따라옵니다.