Files
web-temp/app/app.vue

143 lines
3.5 KiB
Vue

<script setup lang="ts">
import { useNuxtApp } from 'nuxt/app'
import LoadingFull from '#layers/components/blocks/loading/Full.vue'
import LoadingLocal from '#layers/components/blocks/loading/Local.vue'
import BlocksModalYouTube from '#layers/components/blocks/modal/YouTube.vue'
import type { GameDataMetaTag, GameDataValue } from '#layers/types/api/gameData'
const nuxtApp = useNuxtApp()
const gameDataStore = useGameDataStore()
const modalStore = useModalStore()
const { youtube, handleResetYoutube } = modalStore
const { setGameData } = gameDataStore
const { gameData } = storeToRefs(gameDataStore)
const metaData = ref<GameDataMetaTag | null>(null)
// SSR에서 게임 데이터 가져오기
const getGameDataFromServer = (): GameDataValue | null => {
return import.meta.server
? (nuxtApp.ssrContext?.event.context.gameData ?? null)
: null
}
// 통합 메타데이터 설정
const setupAllMetaData = (data: GameDataValue) => {
const meta = data.meta_tag
const faviconPath = data.favicon_path
const theme = data.design_theme === 1 ? 'dark' : 'light'
// 파비콘 링크 생성
const faviconLinks = [
{
rel: 'icon',
type: 'image/x-icon',
sizes: '16x16',
href: faviconPath['16_16'],
},
{
rel: 'icon',
type: 'image/x-icon',
sizes: '32x32',
href: faviconPath['32_32'],
},
{
rel: 'icon',
type: 'image/png',
sizes: '72x72',
href: faviconPath['72_72'],
},
{
rel: 'apple-touch-icon',
sizes: '180x180',
href: faviconPath['180_180'],
},
{
rel: 'icon',
type: 'image/png',
sizes: '192x192',
href: faviconPath['192_192'],
},
]
// 색상 CSS 변수 생성
const cssVariables = Object.entries(data.key_code_codes)
.map(([key, value]) => `--${key}: ${value};`)
.join('\n ')
const cssContent = `
:root {
${cssVariables}
}
`
useHead({
title: meta.page_title,
meta: [
{ name: 'description', content: meta.page_desc },
{ property: 'og:title', content: meta.og_title },
{ property: 'og:description', content: meta.og_desc },
{ property: 'og:image', content: meta.og_image },
{ name: 'twitter:title', content: meta.x_title },
{ name: 'twitter:description', content: meta.x_desc },
{ name: 'twitter:image', content: meta.x_image },
],
htmlAttrs: {
'data-game': data.game_name || '',
'data-theme': theme,
lang: data.default_lang_code || 'ko',
},
link: faviconLinks,
style: [
{
innerHTML: cssContent,
id: 'game-color-variables',
},
],
})
}
// 메타 데이터 설정
const setupMetaData = (data: GameDataValue) => {
metaData.value = data.meta_tag
setupAllMetaData(data)
}
// 초기화 로직 실행
const serverGameData = getGameDataFromServer()
if (serverGameData) {
setGameData(serverGameData)
setupMetaData(serverGameData)
}
const { gtag, initialize } = useGtag()
initialize(gameData.value.ga_code)
gtag('event', 'screen_view', {
app_name: 'My App',
screen_name: 'Home'
})
</script>
<template>
<h1 class="sr-only">{{ gameData?.game_name }}</h1>
<NuxtPage />
<!-- 공통 모달 컴포넌트 -->
<BlocksModalYouTube
:is-open="youtube.storeIsOpen"
:youtube-url="youtube.storeYoutubeUrl"
:class-name="youtube.storeClassName"
@close-button-event="handleResetYoutube"
/>
<!-- 로딩 컴포넌트 -->
<LoadingFull />
<LoadingLocal />
</template>
<style>
@import '#layers/assets/css/app.css';
</style>