🏗️ 레이어 02

사이트 구축 & 기술 SEO

기술적 기반 — 제대로 만들기 (0 → 1)

📖 14 분 읽기 🕑 업데이트 2026-06-22

사이트 구축 및 기술 SEO 레이어는 한 가지 문제를 해결합니다. 바로 검색 엔진이 당신의 페이지를 매끄럽게 찾고, 크롤링하고, 이해하고, 색인하도록 하는 것입니다. 이 레이어는 키워드 리서치 다음, 콘텐츠 제작 이전에 위치합니다. 리서치가 아무리 정밀하고 글을 아무리 잘 썼더라도, 크롤러가 페이지를 읽지 못하거나 URL이 엉망이거나 페이지가 3초 동안 빈 화면만 보여준다면 순위는 애초에 논외입니다.

좋은 소식은, 이 레이어가 코드를 작성하는 사람이 가장 큰 우위를 점하는 레이어라는 점입니다. 전문 용어를 걷어내고 보면 대부분의 “기술 SEO 문제”는 그저 설정 파일, HTTP 헤더, HTML 태그, 그리고 성능 작업일 뿐입니다. 당신이 매일 하는 일들이죠. 크롤러를 JavaScript에 대한 인내심이 없고 엄격한 시간 예산을 가진, 약간 성급한 HTTP 클라이언트라고 생각하세요. 당신의 임무는 그 클라이언트에게 깨끗하고, 빠르고, 라벨이 잘 붙은 HTML을 제공하는 것입니다. 이 페이지는 복사해서 바로 쓸 수 있는 코드와 함께 모든 조각을 하나씩 짚어 나갑니다.

도메인과 호스팅

콘텐츠의 단 한 바이트가 의미를 갖기 전에, 요청이 먼저 빠르게 해석(resolve)되고, 연결되고, 응답되어야 합니다. 그것이 바로 도메인과 호스팅입니다.

도메인 선택. 짧고, 기억하기 쉽고, 주제적으로 그럴듯한 것을 고르세요. 몇 가지 실용적인 규칙:

  • 갓 등록한 도메인은 “연식(age)” 보너스를 받지 못하지만, 동시에 유해한 백링크 이력도 없습니다. 깨끗한 출발선이라면 괜찮습니다.
  • 하이픈으로 잔뜩 채운 정확 일치 키워드 도메인(best-cheap-seo-tools-2026.com)은 피하세요. 스팸처럼 보이고 순위가 더 나아지기는커녕 더 나빠집니다.
  • **하나의 정규 호스트(canonical host)**를 정하고 거기에 고정하세요. www냐 비-www냐를 한 번 결정한 뒤, 나머지 하나는 영원히 리디렉트하세요.

HTTPS는 타협 불가입니다. 이는 (가볍지만) 확인된 순위 신호이며, 최신 브라우저는 일반 HTTP를 “안전하지 않음”으로 표시합니다. 301 리디렉트와 HSTS 헤더로 모든 곳에서 HTTPS를 강제하여 브라우저가 다시는 HTTP를 시도조차 하지 않도록 하세요:

# nginx: redirect all HTTP to HTTPS, then enforce HSTS
server {
  listen 80;
  server_name example.com www.example.com;
  return 301 https://example.com$request_uri;
}
server {
  listen 443 ssl;
  server_name www.example.com;
  return 301 https://example.com$request_uri;   # consolidate www -> apex
}
server {
  listen 443 ssl;
  server_name example.com;
  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
  # ... your site ...
}

위 패턴은 네 개의 주소 — http://, https://, www 포함, www 미포함 — 를 하나의 정규 오리진으로 합칩니다. 이를 건너뛰면 검색 엔진은 이들을 최대 네 개의 별개 사이트로 취급하여 동일한 권위(authority)를 나눠 갖게 할 수 있습니다.

TTFB와 서버 응답 시간. Time To First Byte는 요청 이후 서버가 첫 바이트를 보내기까지 걸리는 시간입니다. Google은 느린 응답을 크롤링 효율성 문제로 봅니다. 굼뜬 서버는 방문 한 번당 크롤링되는 페이지 수가 줄어든다는 뜻이죠. 캐시/정적 응답은 약 200ms 미만, 동적 응답은 약 600ms 미만의 TTFB를 목표로 하세요.

CDN. 콘텐츠 전송 네트워크(CDN)는 사용자와 물리적으로 가까운 서버에 페이지를 캐싱하여, 전 세계 사용자를 위한 지연 시간을 대폭 줄이고 트래픽 급증을 흡수합니다. 정적 사이트의 경우 이는 거의 공짜이면서 거의 마법에 가깝습니다. HTML, CSS, 이미지가 대륙 하나 너머가 아니라 방문자로부터 수백 킬로미터 떨어진 엣지 노드에서 제공되기 때문입니다.

🧑‍💻 개발자 관점: curl로 실제 응답을 점검하세요. 200이 맞는지, strict-transport-security가 존재하는지, 그리고 의도치 않은 x-robots-tag: noindex가 없는지 확인하세요:

curl -sI https://example.com | grep -iE 'http/|strict-transport|x-robots'

사이트 아키텍처

아키텍처는 URL과 링크가 어떻게 구성되어 있는가입니다. 제대로 하면 권위가 매끄럽게 흐르고 크롤러가 모든 것에 도달하며, 잘못하면 중요한 페이지들이 아무도 링크하지 않는 서브폴더 세 단계 깊이에 고아처럼 방치됩니다.

깔끔하고 의미 있는 URL. URL은 빵 부스러기(breadcrumb)처럼 읽혀야 합니다. 비교해 보세요:

Good:  example.com/seo/technical/canonical-tags
Bad:   example.com/index.php?p=482&cat=7&ref=nav

원칙: 소문자, 단어 사이에는 (밑줄이나 공백이 아닌) 하이픈, 파일 확장자 없음, 정규 경로에 세션 ID나 추적용 쓰레기 없음, 그리고 사람이 실제로 입력할 법한 단어. URL은 사람도 읽고, 크롤러도 읽고, SERP에서 당신의 링크를 클릭할지 말지 결정하는 누구나가 읽습니다. 설명적으로 유지하세요. URL이 검색 결과에서 어떻게 렌더링되는지 보고 싶다면 이 사이트의 SERP 미리보기 도구를 사용하세요.

평평한 계층 구조. 모든 중요한 페이지가 홈페이지로부터 약 세 번의 클릭 이내에 도달 가능하도록 유지하세요. 트리가 얕을수록 더 많은 “링크 자산(link equity)“이 깊은 페이지에 도달하고 크롤러가 그 페이지들을 더 쉽게 찾습니다. 도달하는 데 일곱 번의 클릭이 필요한 페이지는, 당신이 그 페이지를 중요하게 여기지 않는다는 신호를 (정확하게) 보냅니다.

내부 링크와 토픽 클러스터 모델. 내부 링크는 두 가지 일을 합니다. 크롤러를 사이트 곳곳으로 안내하고, 페이지 간에 권위를 전달합니다. 가장 효과적인 구조는 토픽 클러스터입니다:

  • 하나의 **필러 페이지(pillar page)**가 큰 주제를 넓게 다룹니다(/seo/technical-seo).
  • 여러 개의 **클러스터 페이지(cluster pages)**가 각각 하나의 세부 주제를 파고듭니다(/seo/technical-seo/robots-txt, /seo/technical-seo/sitemaps).
  • 모든 클러스터 페이지는 필러로 올라가는 링크를 걸고, 필러는 각 클러스터로 내려가는 링크를 겁니다.

이는 검색 엔진에게 “이 사이트는 robots.txt에 대한 페이지가 하나 있다”가 아니라 “이 사이트는 기술 SEO에 대한 권위자다”라고 말해 줍니다. click here 대신 항상 설명적인 앵커 텍스트(robots.txt 설정)를 사용하세요. 앵커 텍스트는 링크 대상 페이지의 순위 신호입니다.

💡 팁: 사이트를 나무로 그려 보세요. 홈페이지가 뿌리, 카테고리가 가지, 글이 잎입니다. 크롤러는 내부 링크를 따라 나무를 타고 오릅니다. 들어오는 내부 링크가 하나도 없는 고아 페이지는 공중에 떠 있는 잎이며, 영영 크롤링되지 않을 수도 있습니다.

기술 SEO

여기가 이 레이어의 핵심이자 당신의 홈그라운드입니다. 아래의 모든 것은 파일이거나, 태그이거나, 헤더입니다.

robots.txt

사이트 루트(example.com/robots.txt)에 위치한 일반 텍스트 파일로, 크롤러가 어떤 경로를 요청해도 되는지 알려 줍니다. 결정적으로, 이것은 색인이 아니라 크롤링을 제어합니다. robots.txt에서 차단된 페이지라도 다른 사이트가 링크를 걸면 (스니펫 없이 맨 URL만으로) 검색 결과에 여전히 나타날 수 있습니다. 무언가를 색인에서 빼두려면 noindex가 필요합니다. 아래를 참고하세요.

User-agent: *
Allow: /
Disallow: /admin/
Disallow: /cart/
Disallow: /*?sort=          # block faceted/sort parameter URLs

Sitemap: https://example.com/sitemap.xml

⚠️ 주의: noindex로 색인에서도 빼고 싶은 페이지를 절대 Disallow하지 마세요. 크롤러가 페이지를 가져올 수 없으면 noindex 태그를 수도 없으므로, 그 페이지는 색인에 계속 묶여 있게 됩니다. 크롤링을 차단하거나, 아니면 크롤링을 허용하고 noindex를 거세요. 둘 다는 안 됩니다.

sitemap.xml

색인되기를 원하는 URL들의 XML 목록입니다. 색인을 보장하지는 않지만, Google에게 깔끔한 인벤토리를 건네는 방법입니다. 대형 사이트나 내부 링크가 적은 페이지에 매우 유용합니다. 정규(canonical)이고, 색인 가능하며, 200 상태인 페이지만 포함하세요(리디렉트 금지, noindex 금지, 중복 금지).

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://example.com/seo/technical-seo</loc>
    <lastmod>2026-06-22</lastmod>
  </url>
  <url>
    <loc>https://example.com/seo/technical-seo/robots-txt</loc>
    <lastmod>2026-06-20</lastmod>
  </url>
</urlset>

Google Search Console(Sitemaps 섹션)에서 제출하고 robots.txt에서 참조하세요. 이것을 손으로 관리하지 마세요. 이 사이트의 robots.txt 및 sitemap 생성기로 두 파일을 모두 생성하세요.

canonical

동일한 콘텐츠가 여러 URL(추적 파라미터, 끝의 슬래시, HTTP 대 HTTPS, 인쇄용 버전)에서 도달 가능할 때, canonical 태그는 권위가 나뉘는 대신 합쳐지도록 “진짜” URL을 지정합니다. <head>에 넣고, 선호 페이지에서는 **자기 참조(self-referential)**로 만드세요:

<!-- on https://example.com/shoes?color=red -->
<link rel="canonical" href="https://example.com/shoes" />

절대 URL을 사용하고, 페이지당 canonical은 하나만 두며, canonical URL 자체가 (리디렉트나 noindex가 아니라) 200을 반환하는지 확인하세요. canonical은 명령이 아니라 강력한 힌트입니다. 신호들을 일관되게 유지하고, 예를 들어 robots.txt에서 차단한 페이지로 canonical을 걸지는 마세요.

hreflang (다국어)

같은 콘텐츠를 여러 언어 또는 지역으로 제공한다면, hreflang이 Google에게 어떤 사용자에게 어떤 버전을 보여줄지 알려 줍니다. 모두가 걸려 넘어지는 규칙: 참조는 양방향이며 완전해야 합니다. 집합 내의 모든 페이지가 자기 자신을 포함해 모든 버전을 나열해야 합니다. 폴백용으로 x-default를 추가하세요.

<!-- in <head> of every page in the language set -->
<link rel="alternate" hreflang="en"    href="https://example.com/en/build" />
<link rel="alternate" hreflang="zh-CN" href="https://example.com/zh/build" />
<link rel="alternate" hreflang="x-default" href="https://example.com/en/build" />

영어 페이지가 중국어 페이지를 가리키는데 중국어 페이지가 되돌아오는 링크를 걸지 않으면, Google은 클러스터 전체를 무시합니다. ISO 언어 코드(en, zh-CN)를 사용하고, alternate에는 절대 robots.txt나 noindex를 걸지 마세요. 이들은 모두 크롤링 가능해야 합니다.

Schema 구조화 데이터

구조화 데이터는 페이지가 무엇인지 — 기사인지, 레시피인지, 제품인지, FAQ인지 — 를 설명하는 기계 판독 가능한 메타데이터입니다. Google은 이를 사용해 리치 결과(rich results)(별점, FAQ 아코디언, SERP의 브레드크럼)를 구동하며, 이는 순위가 바뀌지 않아도 클릭률을 높여 줍니다. <script> 태그 안에 JSON-LD를 사용하세요. Google이 권장하는 형식이며 마크업을 콘텐츠와 분리해 둘 수 있습니다:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "A Developer's Guide to Technical SEO",
  "author": { "@type": "Person", "name": "Jane Dev" },
  "datePublished": "2026-06-22",
  "dateModified": "2026-06-22",
  "image": "https://example.com/img/technical-seo.png"
}
</script>

페이지에 실제로 보이는 콘텐츠만 마크업하세요(가짜로 꾸미면 수동 페널티 위험이 있습니다). 그런 다음 Google의 Rich Results Test로 검증하세요. 이 사이트의 Schema 생성기로 Article, Breadcrumb, FAQ, Organization에 대한 유효한 JSON-LD를 생성하세요.

모바일 우선 색인(Mobile-first indexing)

Google은 데스크톱 버전이 아니라 페이지의 모바일 버전을 사용해 색인하고 순위를 매깁니다. 실무적 결과: 콘텐츠, 제목, 구조화 데이터를 “데스크톱 전용” 경로 뒤에 숨기지 마세요. 모바일 페이지가 동일한 본문 텍스트, 동일한 hreflang/canonical 태그, 동일한 Schema를 갖도록 하세요. 반응형 레이아웃(하나의 HTML 페이로드, CSS 기반 브레이크포인트)이 가장 안전한 패턴입니다. 동기화를 유지해야 할 버전이 하나뿐이기 때문입니다.

Core Web Vitals

실제 사용자 경험을 정량화하고 순위에 직접 반영되는 세 가지 지표입니다. 목표치는 “양호(good)” 임계값입니다:

지표측정 대상양호흔한 해결책
LCP (Largest Contentful Paint)가장 큰 요소가 렌더링되기까지의 시간≤ 2.5s히어로 이미지 최적화, 프리로드, 더 빠른 TTFB
INP (Interaction to Next Paint)사용자 입력에 대한 반응성≤ 200ms긴 JS 작업 쪼개기, JavaScript 적게 전송
CLS (Cumulative Layout Shift)시각적 안정성(튀어 오르지 않음)≤ 0.1이미지에 width/height 지정, 광고/임베드 공간 예약

CLS 측면에서 가장 큰 이득은 미디어에 치수를 지정해 브라우저가 로드 전에 공간을 예약하도록 하는 것입니다:

<!-- browser reserves the box immediately; nothing jumps when the image arrives -->
<img src="/hero.webp" width="1200" height="630" alt="Technical SEO diagram" />

Lighthouse(랩 데이터)와 Search Console의 Core Web Vitals 보고서(실제 사용자로부터 온 현장 필드 데이터)로 측정하세요. Google이 실제로 사용하는 것은 필드 데이터이므로, 필드 데이터에 맞춰 최적화하세요.

크롤 예산, 색인 관리, 그리고 중복 콘텐츠

**크롤 예산(crawl budget)**은 주어진 기간 동안 Google이 당신의 사이트에서 가져갈 URL의 유한한 개수입니다. 소형 사이트는 그 상한에 거의 닿지 않지만, 대형 사이트(URL 5만 개 이상, 대규모 이커머스 패싯)는 분명히 닿습니다. 크롤러가 쓰레기에 예산을 쓰면 예산을 낭비하게 됩니다. 무한한 파라미터 조합, 페이지네이션의 막다른 길, 리디렉트 체인, 소프트 404 같은 것들 말이죠.

중복 콘텐츠는 그 예산을 희석시키고 순위 판단을 혼란스럽게 합니다. 도구 모음:

  • 거의 동일한 페이지(필터링/정렬된 상품 목록)를 합치려면 canonical을 사용하세요.

  • 공개로 유지해야 하지만 순위에는 올리고 싶지 않은 빈약한(thin) 페이지(내부 검색 결과, 태그 아카이브)에는 **noindex**를 사용하세요:

    <meta name="robots" content="noindex, follow" />

    또는 HTML이 아닌 파일에는 헤더 형태로:

    X-Robots-Tag: noindex
  • SEO 가치가 전혀 없는 섹션 전체(/cart/, 패싯 파라미터 URL)에 크롤러가 예산을 낭비하지 않도록 robots.txt를 사용하세요.

  • 리디렉트 체인(A → B → C)을 단일 홉(A → C)으로 고치세요. 각 홉마다 예산을 태우고 권위를 조금씩 새어 나가게 합니다.

🧑‍💻 개발자 관점: “모든 URL은 크롤러가 비용을 치르는 요청”이라는 관점으로 생각하세요. 출시 전에 Screaming Frog 같은 도구로 직접 사이트를 크롤링하고 목록을 감사하세요. 보통 수백 개의 파라미터 URL, 달력 페이지, 또는 페이지네이션 아카이브가 조용히 예산을 갉아먹고 있는 것을 발견하게 됩니다.

스택 선택하기

당신이 선택하는 프레임워크나 CMS가 SEO를 얼마나 알아서 처리해 주는지, 아니면 얼마나 손으로 직접 배선해야 하는지를 결정합니다. 결정적 요인은 HTML이 크롤러에게 어떻게 도달하는가입니다. 서버 렌더링/정적 HTML(훌륭함) 대 클라이언트 측 렌더링 — 후자는 첫 응답이 빈 <div id="root"> 껍데기이고 JavaScript가 실행된 뒤에야 채워집니다(위험함 — 크롤러가 늦게 렌더링하거나 완전히 렌더링하지 않을 수 있음).

스택렌더링SEO 친화성비고
WordPress서버 렌더링높음, 플러그인 사용 시Yoast / Rank Math가 메타, sitemap, Schema를 처리. 성능은 캐싱 플러그인에 의존.
Webflow서버 렌더링/정적기본적으로 높음title/canonical/hreflang 필드가 내장된 비주얼 빌더. 커스텀 로직은 제한적.
Next.jsSSR 또는 SSG (또는 CSR)설정하면 높음완전한 제어가 가능하지만, generateMetadata와 동적 sitemap 라우트로 SEO를 직접 배선해야 함. 기본 CSR은 비친화적.
Astro기본적으로 정적(SSG)매우 높음기본적으로 JS를 0으로 전송 → 빠른 HTML, 자연스러운 Core Web Vitals 우위. 콘텐츠/문서/블로그에 이상적. 이 사이트는 Astro로 운영됩니다.

⚠️ 주의: 순수 클라이언트 측 렌더링 단일 페이지 앱은 첫 로드 때 빈 HTML 껍데기를 제공합니다. Google은 JavaScript를 렌더링할 있지만, 더 느리고 덜 안정적이며, 다른 크롤러(일부 소셜 및 AI 봇)는 아예 렌더링하지 않습니다. SEO가 중요하다면 첫 바이트에 이미 콘텐츠가 담기도록 SSG 또는 SSR을 선택하세요.

콘텐츠 중심 SEO 사이트를 맨바닥부터 구축하는 개발자에게는, 정적 우선(static-first) 생성기(Astro, 또는 SSG 모드의 Next.js)가 최고의 기본값을 제공합니다. 빠른 TTFB, 첫 응답에 담긴 깔끔한 HTML, 그리고 위에서 다룬 모든 태그에 대한 손쉬운 제어가 그것입니다.

요약

이 레이어를 위한 마음가짐: 크롤러에게 깨끗하고, 빠르고, 라벨이 잘 붙은 HTML을 제공하고, 절대 추측하게 만들지 마라. 모든 “기술 SEO 문제”는 파일, 태그, 헤더, 또는 밀리초로 환원됩니다. 그리고 그것은 바로 당신이 이미 해결할 줄 아는 종류의 문제입니다. 까다로운 파일들을 손으로 작성하지 마세요. 이 사이트의 robots/sitemapSchema 도구로 생성한 다음, 모든 것을 검증하세요.

✅ 체크리스트

  • 사이트 전체에 HTTPS를 강제하고, HSTS를 추가하며, 모든 도메인 변형(http, www)을 하나의 정규 오리진으로 301 리디렉트
  • 정규이고 200 상태인 페이지만 포함하여 robots.txtsitemap.xml을 생성하고 제출
  • 모든 중요한 페이지에 자기 참조 canonical 태그를 추가하고 중복/파라미터 URL을 정리
  • 여러 언어를 제공한다면 완전하고 양방향인 hreflang 태그(x-default 포함)를 설정
  • Article, Breadcrumb, Organization에 대한 JSON-LD 구조화 데이터를 추가한 뒤 Rich Results Test 통과
  • Lighthouse를 실행해 LCP ≤ 2.5s, INP ≤ 200ms, CLS ≤ 0.1을 확인 — Search Console의 필드 데이터로 검증
  • (예: Screaming Frog로) URL 목록을 감사하여 고아 페이지, 리디렉트 체인, 예산을 낭비하는 파라미터 URL을 점검