WebPiki
tutorial

개발자를 위한 SEO 완벽 가이드 — 기술적 SEO 중심으로

마케터가 아닌 개발자 관점의 SEO. 크롤링, 메타 태그, 사이트맵, Core Web Vitals까지 코드로 구현하는 기술적 SEO 정리.

검색 엔진 순위를 올라가는 사다리

SEO 관련 글을 검색하면 대부분 마케터 시점이다. "키워드를 잘 넣어라", "백링크를 확보해라" 같은 내용. 틀린 말은 아닌데, 개발자한테는 좀 뜬구름 잡는 느낌이 있다. 개발자가 실제로 컨트롤할 수 있는 건 **기술적 SEO(Technical SEO)**다. 코드와 인프라 레벨에서 검색 엔진이 사이트를 제대로 이해하고 평가할 수 있게 만드는 작업.

이 글은 그 부분에 집중한다.

검색 엔진이 사이트를 읽는 과정

구글이 내 사이트를 검색 결과에 보여주기까지 세 단계를 거친다.

  1. 크롤링 — Googlebot이 페이지를 방문해서 HTML을 가져감
  2. 인덱싱 — 가져간 HTML을 분석해서 검색 데이터베이스에 저장
  3. 랭킹 — 검색어에 맞는 페이지를 관련도 순으로 정렬

개발자가 기술적으로 영향을 줄 수 있는 건 주로 1번과 2번이다. 크롤러가 사이트를 잘 돌아다닐 수 있게 만들고, 각 페이지의 내용을 검색 엔진이 제대로 파악할 수 있게 만드는 거다.

메타 태그 — 기본 중의 기본

<head>
  <title>페이지 제목 — 사이트명</title>
  <meta name="description" content="120자 내외의 페이지 설명" />
  <link rel="canonical" href="https://example.com/page" />
  <meta name="robots" content="index, follow" />
</head>

title — 검색 결과에 파란 링크로 표시되는 그거. 60자 내외가 적당하다. 핵심 키워드를 앞쪽에 넣되, 자연스러운 문장으로 만들어야 한다. "Next.js | React | 프레임워크 | 웹개발" 이런 식으로 키워드를 나열하는 건 역효과다.

description — 검색 결과에서 제목 아래 회색 텍스트로 나오는 부분. 클릭률에 직접 영향을 주니까 대충 쓰면 안 된다. 120~155자 사이로, 해당 페이지에서 사용자가 얻을 수 있는 가치를 명확하게 적는다.

canonical — 같은 콘텐츠가 여러 URL로 접근 가능할 때 "이게 원본이야"라고 지정하는 태그. ?sort=price 같은 쿼리 파라미터로 여러 URL이 생기는 경우에 특히 중요하다. 안 넣으면 검색 엔진이 중복 콘텐츠로 판단해서 랭킹이 깎일 수 있다.

Open Graph & 트위터 카드

SNS에 링크를 공유했을 때 미리보기로 표시되는 정보다. SEO 랭킹에 직접 영향을 주지는 않지만, 공유를 통한 트래픽 유입에 영향을 주니까 무시할 건 아니다.

<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/page" />
<meta property="og:type" content="article" />

<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="페이지 제목" />

OG 이미지 사이즈는 1200×630px이 표준이다. 이걸 빠뜨리면 SNS에 링크를 공유했을 때 썸네일이 안 뜨거나 깨진 이미지가 나온다.

사이트맵과 robots.txt

sitemap.xml — 사이트의 모든 페이지 목록을 검색 엔진에 알려주는 파일이다.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://example.com/</loc>
    <lastmod>2026-03-18</lastmod>
  </url>
  <url>
    <loc>https://example.com/blog/my-post</loc>
    <lastmod>2026-03-15</lastmod>
  </url>
</urlset>

Next.js에서는 app/sitemap.ts 파일을 만들면 자동으로 생성할 수 있다. 블로그 글이 추가될 때마다 수동으로 수정할 필요 없이, 데이터 소스에서 읽어서 동적으로 만드는 게 좋다.

robots.txt — 크롤러에게 "여기는 오지 마" 또는 "사이트맵은 여기 있어"를 알려주는 파일.

User-agent: *
Allow: /
Disallow: /api/
Sitemap: https://example.com/sitemap.xml

/api/ 같은 경로는 검색 결과에 나올 필요가 없으니까 Disallow로 막아두는 게 일반적이다.

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

구글 검색 결과에서 별점, FAQ, 레시피 카드 같은 **리치 스니펫(Rich Snippet)**을 본 적 있을 거다. 이걸 만들어내는 게 구조화된 데이터다. JSON-LD 형식으로 페이지 정보를 검색 엔진에 전달한다.

<script type="application/ld+json">
{JSON.stringify({
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "글 제목",
  "datePublished": "2026-03-18",
  "author": {
    "@type": "Person",
    "name": "작성자"
  }
})}
</script>

넣는다고 무조건 리치 스니펫이 표시되는 건 아니지만, 검색 엔진이 페이지 내용을 더 정확하게 파악하는 데 도움이 된다. 블로그 글에는 Article, 도구 페이지에는 WebApplication, FAQ가 있으면 FAQPage 타입을 쓰는 식이다.

Core Web Vitals — 성능이 곧 SEO

구글은 2021년부터 페이지 성능을 랭킹 요소에 포함시켰다. 세 가지 지표가 핵심이다.

LCP (Largest Contentful Paint) — 화면에서 가장 큰 콘텐츠가 렌더링되는 시간. 2.5초 이내가 목표. 대부분 히어로 이미지나 큰 텍스트 블록이 대상이다.

개발자가 할 수 있는 것:

  • 이미지에 width, height 속성 명시 (레이아웃 시프트 방지)
  • Next.js의 <Image> 컴포넌트 활용 (자동 최적화, lazy loading)
  • 폰트에 font-display: swap 적용

INP (Interaction to Next Paint) — 사용자 인터랙션 후 화면이 업데이트되기까지의 시간. 200ms 이내가 목표. 예전의 FID를 대체한 지표다.

  • 메인 스레드를 오래 차지하는 작업 분리
  • 무거운 연산은 Web Worker로 오프로드
  • React.memo, useMemo 등으로 불필요한 리렌더링 방지

CLS (Cumulative Layout Shift) — 페이지 로드 중 요소가 밀리는 정도. 0.1 이하가 목표. 광고나 이미지가 뒤늦게 로드되면서 텍스트가 갑자기 밀리는 현상.

  • 이미지/비디오에 크기 사전 지정
  • 동적으로 삽입되는 콘텐츠에 공간 예약
  • 웹 폰트 로딩 전략 최적화

Lighthouse나 PageSpeed Insights로 현재 점수를 확인하고, 하나씩 잡아나가는 게 현실적인 접근이다.

렌더링 방식과 SEO의 관계

SSR (Server-Side Rendering) — 서버에서 HTML을 만들어서 보내니까 크롤러가 바로 콘텐츠를 읽을 수 있다. SEO에 가장 유리한 방식.

SSG (Static Site Generation) — 빌드 시점에 HTML을 미리 생성. SSR과 마찬가지로 SEO 친화적이고, 서버 부하도 없다. 블로그나 문서 사이트에 적합.

CSR (Client-Side Rendering) — 브라우저에서 JavaScript로 콘텐츠를 렌더링. 구글봇이 JavaScript를 실행할 수 있긴 하지만, 크롤링 예산(crawl budget)을 더 쓰고, 인덱싱이 지연될 수 있다. SEO가 중요한 페이지에는 피하는 게 좋다.

Next.js App Router를 쓴다면 기본이 서버 컴포넌트(SSR/SSG)라서 별도로 신경 쓸 게 적다. "use client" 컴포넌트에 핵심 콘텐츠를 넣지 않는 것만 주의하면 된다.

실전 체크리스트

새 페이지를 만들 때마다 확인할 항목들:

  • <title><meta description> 설정했는가
  • canonical URL 지정했는가
  • OG 태그 + OG 이미지 설정했는가
  • 이미지에 alt 텍스트 넣었는가
  • heading 태그 계층 구조가 맞는가 (h1 → h2 → h3 순서)
  • sitemap에 포함되는가
  • 모바일에서 제대로 보이는가

이걸 매번 수동으로 체크하는 건 현실적이지 않으니까, 메타데이터 유틸 함수를 하나 만들어서 공통 처리하는 게 낫다. Next.js의 generateMetadata를 래핑해서 기본값을 넣어두면 빠뜨릴 일이 줄어든다.

SEO는 한 번 세팅하고 끝나는 게 아니라 지속적으로 모니터링해야 하는 영역이다. Google Search Console에서 크롤링 에러, 인덱싱 상태, 검색 성능을 정기적으로 확인하는 습관이 결국 가장 중요하다.

#SEO#기술적SEO#웹개발#CoreWebVitals#검색엔진최적화

Related Posts