개발자를 위한 SEO 완벽 가이드 — 기술적 SEO 중심으로
마케터가 아닌 개발자 관점의 SEO. 크롤링, 메타 태그, 사이트맵, Core Web Vitals까지 코드로 구현하는 기술적 SEO 정리.
SEO 관련 글을 검색하면 대부분 마케터 시점이다. "키워드를 잘 넣어라", "백링크를 확보해라" 같은 내용. 틀린 말은 아닌데, 개발자한테는 좀 뜬구름 잡는 느낌이 있다. 개발자가 실제로 컨트롤할 수 있는 건 **기술적 SEO(Technical SEO)**다. 코드와 인프라 레벨에서 검색 엔진이 사이트를 제대로 이해하고 평가할 수 있게 만드는 작업.
이 글은 그 부분에 집중한다.
검색 엔진이 사이트를 읽는 과정
구글이 내 사이트를 검색 결과에 보여주기까지 세 단계를 거친다.
- 크롤링 — Googlebot이 페이지를 방문해서 HTML을 가져감
- 인덱싱 — 가져간 HTML을 분석해서 검색 데이터베이스에 저장
- 랭킹 — 검색어에 맞는 페이지를 관련도 순으로 정렬
개발자가 기술적으로 영향을 줄 수 있는 건 주로 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에서 크롤링 에러, 인덱싱 상태, 검색 성능을 정기적으로 확인하는 습관이 결국 가장 중요하다.