Merge branch 'feature/20260327_gil_nitroLog' into feature/20260331_all

This commit is contained in:
“hyeonggkim”
2026-03-31 17:13:46 +09:00
9 changed files with 502 additions and 26 deletions

View File

@@ -1,4 +1,6 @@
<script setup lang="ts">
const route = useRoute()
const requestURL = useRequestURL()
const { locale } = useI18n()
const gameDataStore = useGameDataStore()
const modalStore = useModalStore()
@@ -91,7 +93,99 @@ const setupGameHead = () => {
}
}
// Schema.org 구조화된 데이터 설정
const setupStructuredData = () => {
if (!gameName.value) return
try {
// SEO용 URL은 설정 도메인이 아닌 실제 요청 호스트 기준 (SSR/CSR 모두 useRequestURL)
const baseUrl = requestURL.origin
const currentLocale = locale.value ?? defaultLangCode.value ?? 'ko'
// Organization Schema
const organizationSchema: Record<string, any> = {
'@context': 'https://schema.org',
'@type': 'Organization',
name: gameName.value,
url: baseUrl,
}
// 로고 이미지 추가 (favicon 중 PNG 우선)
if (faviconJson.value) {
const logoUrl = faviconJson.value[2] || faviconJson.value[0]
if (logoUrl) {
organizationSchema.logo = formatPathHost(logoUrl)
}
}
// SNS 링크 추가
const snsData = gameDataStore.snsJson
if (snsData) {
const sameAs: string[] = []
if (snsData.youtube?.use_yn === 1 && snsData.youtube?.url) {
sameAs.push(snsData.youtube.url)
}
if (snsData.twitter?.use_yn === 1 && snsData.twitter?.url) {
sameAs.push(snsData.twitter.url)
}
if (snsData.facebook?.use_yn === 1 && snsData.facebook?.url) {
sameAs.push(snsData.facebook.url)
}
if (snsData.discord?.use_yn === 1 && snsData.discord?.url) {
sameAs.push(snsData.discord.url)
}
if (snsData.instagram?.use_yn === 1 && snsData.instagram?.url) {
sameAs.push(snsData.instagram.url)
}
if (snsData.tiktok?.use_yn === 1 && snsData.tiktok?.url) {
sameAs.push(snsData.tiktok.url)
}
if (sameAs.length > 0) {
organizationSchema.sameAs = sameAs
}
}
// WebSite Schema - 사이트 정보
const websiteSchema: Record<string, any> = {
'@context': 'https://schema.org',
'@type': 'WebSite',
name: gameName.value,
url: baseUrl,
inLanguage: currentLocale,
}
// 설명 추가 (있는 경우)
if (gameMetaTag.value?.page_desc) {
websiteSchema.description = gameMetaTag.value.page_desc
}
useHead({
script: [
{
type: 'application/ld+json',
innerHTML: JSON.stringify(organizationSchema),
},
{
type: 'application/ld+json',
innerHTML: JSON.stringify(websiteSchema),
},
],
link: [
{
rel: 'canonical',
href: `${baseUrl}${route.path}`,
},
],
})
} catch (error) {
// eslint-disable-next-line no-console
console.error('[setupStructuredData] Failed to setup schema:', error)
}
}
setupGameHead()
setupStructuredData()
let rafId: number | null = null
onMounted(() => {