40 lines
1.3 KiB
TypeScript
40 lines
1.3 KiB
TypeScript
// 페이지별 SEO 메타 설정 — title/description/Open Graph/Twitter/canonical 일괄 처리
|
|
// 각 페이지에서 useSeo({ ... }) 한 번만 호출하면 된다.
|
|
|
|
interface SeoOptions {
|
|
title: string // 페이지 제목 (<title> + og:title)
|
|
description: string // 메타 설명 (검색결과/공유 미리보기)
|
|
path: string // 라우트 경로 (canonical·og:url 구성), 예: '/', '/coffee-chat'
|
|
image?: string // OG 이미지 경로 (기본 /og-image.jpg)
|
|
noindex?: boolean // 검색 노출 제외 여부
|
|
}
|
|
|
|
export function useSeo(opts: SeoOptions) {
|
|
const config = useRuntimeConfig()
|
|
// 끝 슬래시 제거 후 절대 URL 구성
|
|
const siteUrl = String(config.public.siteUrl || '').replace(/\/$/, '')
|
|
const url = siteUrl + opts.path
|
|
const image = siteUrl + (opts.image || '/og-image.jpg')
|
|
|
|
useSeoMeta({
|
|
title: opts.title,
|
|
description: opts.description,
|
|
ogTitle: opts.title,
|
|
ogDescription: opts.description,
|
|
ogUrl: url,
|
|
ogImage: image,
|
|
ogImageWidth: 1200,
|
|
ogImageHeight: 630,
|
|
ogImageAlt: opts.title,
|
|
twitterTitle: opts.title,
|
|
twitterDescription: opts.description,
|
|
twitterImage: image,
|
|
robots: opts.noindex ? 'noindex, nofollow' : 'index, follow',
|
|
})
|
|
|
|
// canonical 링크 — 중복 콘텐츠 방지
|
|
useHead({
|
|
link: [{ rel: 'canonical', href: url }],
|
|
})
|
|
}
|