TIL_20250429_SEO

Kim jisu·2025년 4월 29일

TIL

목록 보기
38/43

Next.js 프로젝트에 SEO를 적용하는 방법.


SEO?

SEO(Search Engine Optimization, 검색엔진최적화)는 웹사이트가 검색엔진(주로 Google)의 크롤링·색인·랭킹 알고리즘에 잘 노출되도록 하는 일련의 활동입니다.

1. On-Page SEO (페이지 내 최적화)

웹페이지 내부 요소를 최적화하여 검색엔진과 사용자의 이해도를 높입니다.

  • 키워드 배치: 제목(<h1>), 부제목(<h2>), 본문, 메타 설명에 주요 키워드를 자연스럽게 포함
  • 메타태그: <title>, <meta name="description">를 페이지별로 고유하게 설정
  • URL 구조: 설명적이고 읽기 쉬운 URL 사용(예: /products/seo-guide)
  • 내부 링크: 관련 콘텐츠 간 자연스러운 연결로 크롤러가 사이트 깊숙한 페이지까지 탐색하도록 유도

2. Off-Page SEO (페이지 외 최적화)

사이트 외부에서 신뢰도와 권위를 쌓는 활동으로, 검색엔진에 ‘입소문’처럼 작용합니다.

  • 백링크 구축: 권위 있는 외부 도메인으로부터의 자연스러운 링크 획득
  • 소셜 신호: SNS 공유·언급을 통해 브랜드 인지도와 트래픽 증가
  • 게스트 포스팅 & PR: 관련 업계 블로그나 매체에 콘텐츠 제공으로 도메인 권위 향상

3. Technical SEO (기술적 최적화)

검색엔진 크롤러가 사이트를 원활히 크롤링·색인하도록 백엔드 구조를 다듬습니다.

  • 사이트 속도: 페이지 로딩 시간 단축(이미지 최적화, 캐싱, CDN 등)
  • 모바일 최적화: 반응형 디자인 또는 동적 서빙으로 모바일 우선 인덱싱 지원
  • HTTPS 보안: SSL 인증서 적용으로 신뢰도 및 랭킹 개선
  • 사이트맵·robots.txt: XML 사이트맵 제출, robots.txt로 크롤링 제어 및 색인 가이드

4. 키워드 리서치 & 콘텐츠 품질

  • 키워드 리서치: 사용자가 실제 검색하는 용어를 조사해 롱테일부터 주요 키워드까지 우선순위 설정
  • 고품질 콘텐츠: 사용자 의도에 맞고, E-A-T(전문성·권위성·신뢰성)를 충족하는 정보 제공
  • 최신성 유지: 정기 업데이트로 검색엔진이 사이트를 자주 재방문하도록 유도

5. 성과 모니터링 및 개선

  • Google Search Console: 색인 커버리지, 검색 성능(클릭수·노출수·평균순위), 크롤링 오류 확인
  • Google Analytics: 페이지별 이탈률, 체류 시간 등 사용자 행동 데이터 분석
  • A/B 테스트: 제목·메타 설명·콘텐츠 구조 변경 후 성과 비교

Next.js 프로젝트에 SEO 적용하는 법

1. 페이지 별 메타태그 설정

Pages Router ( pages/ )

import Head from 'next/head'

export default function Home() {
  return (
    <>
      <Head>
        <title>홈 | 내서비스</title>
        <meta name="description" content="내서비스에 오신 것을 환영합니다." />
        <meta name="robots" content="index,follow" />
        {/* Open Graph */}
        <meta property="og:title" content="홈 | 내서비스" />
        <meta property="og:description" content="내서비스에 오신 것을 환영합니다." />
        <meta property="og:image" content="https://example.com/og-image.png" />
        <meta property="og:url" content="https://example.com/" />
        {/* Twitter Card */}
        <meta name="twitter:card" content="summary_large_image" />
      </Head>
      <main>{/* … */}</main>
    </>
  )
}

App Router ( app/ )

Next.js 13부터 제공하는 metadata API를 사용하면, 레이아웃이나 페이지 단위로 객체를 export만 해주면 됩니다.

export const metadata = {
  title: '홈 | 내서비스',
  description: '내서비스에 오신 것을 환영합니다.',
  robots: {
    index: true,
    follow: true
  },
  openGraph: {
    title: '홈 | 내서비스',
    description: '내서비스에 오신 것을 환영합니다.',
    url: 'https://example.com/',
    siteName: '내서비스',
    images: [
      {
        url: 'https://example.com/og-image.png',
        width: 1200,
        height: 630,
      },
    ],
    locale: 'ko_KR',
    type: 'website',
  },
  twitter: {
    card: 'summary_large_image',
  }
}

export default function RootLayout({ children }) {
  return (
    <html lang="ko">
      <body>{children}</body>
    </html>
  )
}

동적 라우트의 경우, 페이지 컴포넌트에 generateMetadata 함수를 정의할 수 있습니다:

export async function generateMetadata({ params }) {
  const post = await getPost(params.id)
  return {
    title: post.title,
    description: post.excerpt,
    openGraph: { title: post.title, description: post.excerpt, /* … */ }
  }
}

export default function PostPage({ params }) { /* … */ }

2. next-seo 라이브러리 활용

간단 설정으로 공통 SEO 옵션을 관리할 수 있습니다.

npm install next-seo
export default {
  titleTemplate: '%s | 내서비스',
  defaultTitle: '내서비스',
  description: '내서비스에 오신 것을 환영합니다.',
  openGraph: {
    type: 'website',
    locale: 'ko_KR',
    url: 'https://example.com/',
    site_name: '내서비스',
  },
  twitter: {
    handle: '@myservice',
    site: '@myservice',
    cardType: 'summary_large_image',
  },
}
import { DefaultSeo } from 'next-seo'
import SEO from '../next-seo.config'

export default function App({ Component, pageProps }) {
  return (
    <>
      <DefaultSeo {...SEO} />
      <Component {...pageProps} />
    </>
  )
}

각 페이지에서 NextSeo 컴포넌트를 사용해 개별 설정을 덮어쓸 수 있습니다.


3. Sitemap & robots.txt 생성

  • robots.txt:

    public/robots.txt

    User-agent: *
    Allow: /
    Sitemap: https://example.com/sitemap.xml
  • sitemap.xml:
    npm install next-sitemap

    module.exports = {
      siteUrl: 'https://example.com',
      generateRobotsTxt: true,
    }
    npx next-sitemap

4. 구조화된 데이터 (JSON-LD)

검색결과에 리치 스니펫이 나오도록 <Head>나 App Router의 <Script>로 삽입합니다.

<Head>
  <script
    type="application/ld+json"
    dangerouslySetInnerHTML={{
      __html: JSON.stringify({
        "@context": "https://schema.org",
        "@type": "Organization",
        name: "내서비스",
        url: "https://example.com",
        logo: "https://example.com/logo.png"
      }),
    }}
  />
</Head>

5. 그 외 권장 사항

  1. Canonical 태그: 중복 URL 방지를 위해 <link rel="canonical" href="https://example.com/현재경로" />.
  2. 언어/지역 설정: <html lang="ko">, hreflang 태그로 다국어 처리.
  3. 프리렌더링: getStaticProps/getStaticPaths 또는 App Router의 SSG( export const revalidate )를 활용.
  4. 이미지 최적화: next/image 사용, priority 속성으로 LCP 개선.
  5. 성능 최적화: Lighthouse에서 FCP, LCP, CLS 점수 높이기.

profile
Dreamer

0개의 댓글