개발 slecs

Astro 정적 사이트에 DB 기반 SEO 메타 관리 도입

목차

Astro 기반 정적 사이트에 데이터베이스 기반 SEO 메타 패턴을 도입했다. getSiteSeo 함수로 메타 정보를 중앙화하고, 런타임에 동적으로 로드하는 구조를 만들게 됐는데, 이게 생각보다 흥미로운 트레이드오프 경험이었다.

SEO 메타, 왜 DB에서 관리해야 했나

사이트가 작을 땐 메타 정보를 하드코딩하거나 마크다운 frontmatter에 박아두는 것도 괜찮다. 그런데 페이지가 수십 개를 넘어가고, OG 이미지나 설명 같은 정보가 콘텐츠 관리 시스템과 동기화되어야 할 시점이 오면 문제가 생긴다. 손으로 계속 업데이트하면 휴먼에러는 늘어나고, 마케팅팀 요청도 대응이 느려진다. 특히 동적 랜딩 페이지나 AB 테스트 관점에서 메타 정보를 빠르게 변경해야 할 때, 매번 빌드/배포하는 건 현실적이지 않다.

그래서 "어차피 Astro도 런타임 API 호출은 지원하니까, SEO 메타를 데이터베이스에서 동적으로 가져오자" 정도로 생각했던 거다.

astro.config.mjs와 Base.astro의 역할 분리

구성 요소 역할 왜 여기서?
astro.config.mjs 빌드 시 기본 SEO 설정 정의 (기본값, 도메인 등) Astro 설정 단계에서 글로벌 메타 정보 주입
getSiteSeo 함수 DB에서 실제 메타 데이터 조회 런타임 호출로 페이지별 동적 메타 로드
Base.astro 모든 페이지가 상속받는 레이아웃, getSiteSeo 호출 위치 중앙화된 메타 렌더링 지점

핵심은 레이아웃 컴포넌트 한 곳에서만 getSiteSeo를 호출하도록 강제했다는 거다. 개별 페이지에서 각자 DB 조회하게 놔두면 쿼리 중복이 생기고, 캐싱 전략도 엉망이 된다. Base.astro가 래퍼 역할을 하니까, 페이지 작성자는 단순히 props.seoData를 믿고 쓰면 된다.

// Base.astro 패턴 (개념)
---
import { getSiteSeo } from '@/lib/seo'

const seoData = await getSiteSeo({
  pageType: Astro.props.pageType,
  identifier: Astro.props.identifier, // slug, productId 등
})
---

<head>
  <title>{seoData.title}</title>
  <meta name="description" content={seoData.description} />
  <meta property="og:image" content={seoData.ogImage} />
</head>

이런 식으로 구성하면, 나중에 메타 데이터 출처를 바꾼다 해도 (DB → API → 캐시 등) Base.astro는 건드릴 필요가 없다.

일반적 SEO 메타 관리의 함정들

정적/동적 하이브리드 구조를 쓸 때 자주 빠지는 실수들:

  • 1. 중복 쿼리: 페이지마다 getSiteSeo를 호출하면, 같은 데이터를 여러 번 조회한다. 빌드 시간이 길어진다. → 캐싱(로컬, Redis) 필수.
  • 2. 폴백 처리: DB가 다운되거나 데이터가 없을 때 어떻게 할 것인가. hardcoded 기본값이 필수다. astro.config.mjs 에서 정의하는 이유.
  • 3. OG 이미지 CDN: og:image는 생성/CDN 경로 관리가 별도인데, DB에 URL만 저장하면 나중에 CDN 변경 시 마이그레이션 고생한다. 가능하면 함수로 경로를 생성하도록.
  • 4. 빌드 vs 런타임: Astro는 정적 빌드 시점에 메타를 고정시키는 게 기본인데, DB 조회를 런타임으로 미루려면 SSR/Hydration 전략을 명확히 해야 한다.

왜 이 타이밍에 도입했나 (팀 관점)

사실 "완벽하게 준비되면 시작하자"는 생각도 했지만, 마케팅팀에서 "이번 주내에 OG 이미지 3개 변경 부탁"이라는 요청이 들어온 순간 우선순위가 바뀌었다. 그동안 매번 코드 수정 → 배포 사이클을 돌았는데, 이걸 자동화하지 않으면 팀의 속도가 계속 떨어질 거였다.

더 중요한 건, 이렇게 만들어놓으면 다음 번 유사한 기능 요청은 훨씬 빨리 대응할 수 있다는 거다. 상품 페이지 메타, 카테고리 페이지 메타, 검색 결과 메타 — 모두 같은 getSiteSeo 패턴으로 확장할 수 있다. 초기 투자가 조금 들지만, 이후 운영 효율은 크게 올라간다.

기억할 만한 것들

  • 정적 빌드와 동적 데이터를 섞을 때는 "어느 시점에 어떤 데이터를 로드할 것인가"가 가장 중요하다.
  • 중앙화 지점(Base.astro)을 명확히 하면 나중에 구현 세부를 바꾸기가 훨씬 쉽다.
  • 메타 정보 같은 것도 빌드 초반부터 확장성을 생각해둬야, 나중에 "메타 한 개 바꾸려면 배포해야 한다"는 불평을 안 듣는다.

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

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

댓글 0

첫 댓글 달아줘.