개발 slecs

SEO 컴포넌트 분리와 사이트 상수 단일화로 메타 관리 구조 정비

목차

표준 SEO 컴포넌트를 별도 파일로 분리하고, 사이트 전역 상수를 consts.ts로 뽑아낸 작업이다.

왜 이 타이밍에 SEO 구조를 정리했나

프로젝트 초반엔 레이아웃 파일 하나에 <title>, <meta name="description">, OG 태그가 인라인으로 박혀 있는 경우가 많다. 돌아가기만 하면 되니까. 그런데 페이지가 늘어나면 레이아웃이 점점 무거워지고, 메타 정보를 바꾸고 싶을 때 Base.astro를 열어야 하는 상황이 반복된다. 지금 딱 그 시점이었다.

팀 입장에서 더 큰 문제는 사이트 이름, 기본 설명, URL 같은 상수값이 여러 파일에 흩어져 있을 때 발생하는 수정 누락이다. 한 곳을 바꿨는데 다른 곳이 구버전 값을 그대로 들고 있는 상황 — SEO에서 그 에러는 검색 엔진이 엉뚱한 정보를 캐시해가는 결과로 이어진다.

그래서 이번에 세 파일을 한 묶음으로 정리했다.

파일 이전 역할 이번 변경
src/layouts/Base.astro SEO 메타 직접 인라인 작성 <Seo /> 컴포넌트 위임
src/components/Seo.astro 없거나 기초 수준 표준 SEO 컴포넌트로 분리
src/consts.ts 없거나 산발적 사이트 전역 상수 단일 소스

표준 SEO 컴포넌트의 범위

Seo.astro가 담당하는 범위를 정리하면 대략 이렇다.

---
// src/components/Seo.astro
const {
  title,
  description,
  ogImage,
  canonicalURL,
} = Astro.props;
---

<title>{title}</title>
<meta name="description" content={description} />
<link rel="canonical" href={canonicalURL} />

<!-- OG -->
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={ogImage} />
<meta property="og:type" content="website" />

<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />

기본 패턴은 이렇고, props 기본값은 consts.ts에서 끌어온다. 페이지별로 override가 필요하면 레이아웃 호출부에서 prop을 넘기면 된다.

// src/consts.ts
export const SITE_TITLE = "ssul";
export const SITE_DESCRIPTION = "...";
export const SITE_URL = "https://...";
export const OG_IMAGE = "/og-default.png";

이 파일이 있으면 이후 리브랜딩이든 도메인 변경이든 한 파일만 열면 된다. 팀원이 새 페이지를 추가할 때도 어디서 기본값을 가져오는지 명확하다. 온보딩 비용도 줄어든다.

레이아웃에서 위임하는 방식

Base.astro는 이제 직접 메타를 관리하지 않는다.

---
// src/layouts/Base.astro
import Seo from "../components/Seo.astro";
import { SITE_TITLE, SITE_DESCRIPTION } from "../consts";

const {
  title = SITE_TITLE,
  description = SITE_DESCRIPTION,
} = Astro.props;
---

<html lang="ko">
  <head>
    <Seo title={title} description={description} />
  </head>
  <body>
    <slot />
  </body>
</html>

레이아웃의 책임이 명확해진다. 페이지 골격을 잡는 곳이 SEO 세부 구현까지 알 필요가 없어지는 거다. 관심사 분리의 교과서적인 예시지만, 실제로 이렇게 해두면 나중에 SEO 태그를 추가/수정할 때 Seo.astro 하나만 건드리면 된다는 게 체감상 훨씬 편하다.

회고

작업 규모 자체는 크지 않다. 파일 세 개, 각자 수십 줄 수준. 그런데 이런 구조 정비를 언제 하느냐가 팀 생산성에 은근히 영향을 준다. 너무 늦게 하면 이미 여러 페이지에 인라인 메타가 박혀 있어서 마이그레이션 비용이 커지고, 너무 이르면 컴포넌트 API가 자주 바뀌어 오히려 혼란스럽다.

페이지가 3~5개 정도 생기면서 "이거 패턴화해야겠다"는 감이 올 때가 딱 맞는 타이밍인 것 같다. 이번엔 그 타이밍을 놓치지 않았다.

consts.ts 분리는 어떤 프로젝트든 초반에 잡아두면 편한 습관이다. 상수 파일이 없으면 마법의 문자열이 코드베이스 전체에 퍼지고, 어느 순간 어디서 왔는지 추적이 안 된다. TypeScript라면 as const나 타입 좁히기도 같이 얹으면 더 좋다.

다음엔 JSON-LD 구조화 데이터를 Seo.astro에 추가하는 게 자연스러운 수순이다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.