비홈 페이지의 OG·Twitter 메타데이터 정합성 수정

이 글의 목차 7개 항목
  • 분야: FE
  • 기술 스택: TypeScript · vinext · Next.js 호환 Metadata API

문제와 원인

개인정보처리방침은 문서 title·description·canonical만 지정해 홈의 Open Graph와 Twitter 정보를 상속했다. 서비스 소개와 가이드 목록은 Open Graph 객체를 선언하면서 공통 이미지를 빠뜨렸고, Twitter 정보는 홈의 값을 유지했다.

수정 전 /privacy의 canonical은 /privacy였지만 og:url은 https://modumunje.com이었다. /about과 /guides의 og:image는 각각 0개였다. 중첩된 metadata 객체는 페이지에서 선언한 객체로 대체되므로 title이나 Open Graph 일부만 설정하면 다른 소셜 정보가 남거나 이미지가 빠졌다.

수정 전 코드

metadata

export const metadata: Metadata = {
  title: "개인정보처리방침 | 모두의 문제집",
  description: "모두의 문제집 계정, 학습·그룹 시험 기록, 제보, 방문 통계와 쿠키에 관한 처리 안내입니다.",
  alternates: { canonical: "/privacy" },
};

수정 후 코드

metadata

세 공개 페이지와 과정별 가이드에 적용했다. 개인정보처리방침의 호출은 다음과 같다.

export const metadata = publicPageMetadata({
  title: "개인정보처리방침 | 모두의 문제집",
  description: "모두의 문제집 계정, 학습·그룹 시험 기록, 제보, 방문 통계와 쿠키에 관한 처리 안내입니다.",
  path: "/privacy",
});

publicPageMetadata

publicPageMetadata가 title·description·path를 받아 canonical, Open Graph, Twitter를 함께 반환하도록 바꿨다. 공통 이미지 /brand/modu-social-preview-v2.jpg도 두 소셜 객체에 명시했다.

return {
  title,
  description,
  alternates: { canonical: path },
  robots: { index, follow },
  openGraph: {
    title, description, type, url: path,
    locale: "ko_KR", siteName: "모두의 문제집",
    images: [socialImage],
  },
  twitter: {
    card: "summary_large_image", title, description,
    images: [socialImage.url],
  },
};

검증 결과

macOS, Node.js, vinext에서 원본 전후 스냅샷의 root·page metadata를 mergeMetadata와 renderMetadataToHtml로 렌더링했다. 3경로를 버전마다 1회 실행하고, OG·Twitter title과 문서 title, OG·Twitter description과 문서 description, OG URL과 canonical의 일치 및 OG·Twitter 이미지 각 1개를 검사했다.

경로수정 전 일치 조건수정 후 일치 조건
/privacy2/7개7/7개
/about2/7개7/7개
/guides2/7개7/7개
합계6/21개21/21개

원본 metadata를 <head>에 적용한 로컬 fixture도 1280×720 CSS px, DPR 2에서 여섯 URL을 각 1회 열어 같은 결과를 얻었다. Swagger UI의 전후 /privacy GET 각 1회는 모두 HTTP 200이었다.

수정 전 privacy: 홈의 OG·Twitter 정보가 남은 HTML head원본 보기 (새 창)

수정 전 privacy: 홈의 OG·Twitter 정보가 남은 HTML head

100%원본 보기 (새 창)

확대한 이미지는 상하좌우로 이동할 수 있습니다. 키보드는 이미지 영역에 초점을 두고 방향키를 사용하세요. Esc로 닫습니다.

수정 후 privacy: 페이지 정보와 일치한 HTML head원본 보기 (새 창)

수정 후 privacy: 페이지 정보와 일치한 HTML head

100%원본 보기 (새 창)

확대한 이미지는 상하좌우로 이동할 수 있습니다. 키보드는 이미지 영역에 초점을 두고 방향키를 사용하세요. Esc로 닫습니다.

별도 로컬 Worker 빌드에는 비인증 합성 GET(User-Agent: Twitterbot/1.0, Accept: text/html)을 경로마다 1회 전달해 초기 <head>를 검사했다. 같은 빌드의 응답을 전달하는 로컬 HTTP 경로도 Swagger에서 각 1회 요청한 뒤 DOM을 읽었다.

경로Worker·로컬 HTTP 상태canonical 수일치 조건OG·Twitter 이미지 수
/privacy모두 2001개7/7개각각 1개
/about모두 2001개7/7개각각 1개
/guides모두 2001개7/7개각각 1개
/guides/sqld모두 2001개7/7개각각 1개
합계28/28개
Worker privacy 응답의 title·OG·Twitter·canonical원본 보기 (새 창)

Worker privacy 응답의 title·OG·Twitter·canonical

100%원본 보기 (새 창)

확대한 이미지는 상하좌우로 이동할 수 있습니다. 키보드는 이미지 영역에 초점을 두고 방향키를 사용하세요. Esc로 닫습니다.