refactor. 게임 데이터 관련 상태 및 메타 태그 처리 개선

- 게임 데이터 스토어에서 상태 변수 이름 변경 및 추가
- 메타 태그 및 스타일 링크 생성 로직 간소화
- 코드 가독성 향상을 위한 함수 인자 제거
This commit is contained in:
clkim
2026-03-18 16:35:27 +09:00
parent f718b01b03
commit 02ef9f9aa5
4 changed files with 54 additions and 47 deletions

View File

@@ -1,11 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { useNuxtApp } from 'nuxt/app' import { useNuxtApp } from 'nuxt/app'
import type {
GameDataMetaTag,
GameDataValue,
GameDataKeyColors,
GameDataImg,
} from '#layers/types/api/gameData'
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
const { locale } = useI18n() const { locale } = useI18n()
@@ -15,15 +9,25 @@ const scrollStore = useScrollStore()
const { setGameData } = gameDataStore const { setGameData } = gameDataStore
const { confirm, alert } = modalStore const { confirm, alert } = modalStore
const { gameName, gaCode } = storeToRefs(gameDataStore) const {
gameName,
gaCode,
gameTheme,
gameMetaTag,
faviconJson,
defaultLangCode,
gameFontJson,
keyColorJson,
} = storeToRefs(gameDataStore)
const { scrollGnbPosition } = storeToRefs(scrollStore) const { scrollGnbPosition } = storeToRefs(scrollStore)
// favicon 링크 생성 헬퍼 // favicon 링크 생성 헬퍼
const createStyleLinks = (faviconJson: GameDataImg, fontPath: string = '') => { const createStyleLinks = () => {
const links = [] const links = []
const iconUrl = faviconJson[0] const iconUrl = faviconJson.value[0]
const appleTouchIconUrl = faviconJson[1] const appleTouchIconUrl = faviconJson.value[1]
const pngIconUrl = faviconJson[2] const pngIconUrl = faviconJson.value[2]
const fontPath = gameFontJson.value?.font_path
if (iconUrl) { if (iconUrl) {
links.push({ links.push({
@@ -56,21 +60,21 @@ const createStyleLinks = (faviconJson: GameDataImg, fontPath: string = '') => {
} }
// 메타 태그 생성 헬퍼 // 메타 태그 생성 헬퍼
const createMetaTags = (metaTag: Partial<GameDataMetaTag> = {}) => { const createMetaTags = () => {
if (!metaTag) return [] if (!gameMetaTag.value) return []
const metaList = [ const metaList = [
{ name: 'description', content: metaTag.page_desc }, { name: 'description', content: gameMetaTag.value.page_desc },
{ property: 'og:title', content: metaTag.og_title }, { property: 'og:title', content: gameMetaTag.value.og_title },
{ property: 'og:description', content: metaTag.og_desc }, { property: 'og:description', content: gameMetaTag.value.og_desc },
{ {
property: 'og:image', property: 'og:image',
content: formatPathHost(metaTag.og_image), content: formatPathHost(gameMetaTag.value.og_image),
}, },
{ name: 'twitter:title', content: metaTag.x_title }, { name: 'twitter:title', content: gameMetaTag.value.x_title },
{ name: 'twitter:description', content: metaTag.x_desc }, { name: 'twitter:description', content: gameMetaTag.value.x_desc },
{ {
name: 'twitter:image', name: 'twitter:image',
content: formatPathHost(metaTag.x_image), content: formatPathHost(gameMetaTag.value.x_image),
}, },
] ]
@@ -81,8 +85,8 @@ const createMetaTags = (metaTag: Partial<GameDataMetaTag> = {}) => {
} }
// CSS 변수 생성 헬퍼 // CSS 변수 생성 헬퍼
const createStyleCss = (keyColorJson: GameDataKeyColors) => { const createStyleCss = () => {
const colorVariables = Object.entries(keyColorJson) const colorVariables = Object.entries(keyColorJson.value)
.filter(([key, value]) => key && value != null) .filter(([key, value]) => key && value != null)
.map(([key, value]) => `--${key}: ${value};`) .map(([key, value]) => `--${key}: ${value};`)
.join('\n ') .join('\n ')
@@ -91,25 +95,20 @@ const createStyleCss = (keyColorJson: GameDataKeyColors) => {
} }
// 게임 헤드 설정 // 게임 헤드 설정
const setupGameHead = (data: GameDataValue) => { const setupGameHead = () => {
if (!gameMetaTag.value) return
try { try {
const metaTag: Partial<GameDataMetaTag> = data?.meta_tag_json ?? {} const styleCss = createStyleCss()
const designTheme = data.design_theme === 1 ? 'light' : 'dark'
const styleLinks = createStyleLinks(
data.favicon_json,
data?.game_font_json?.font_path
)
const styleCss = createStyleCss(data.key_color_json)
useHead({ useHead({
title: metaTag.page_title ?? '', title: gameMetaTag.value?.page_title ?? '',
meta: createMetaTags(metaTag), meta: createMetaTags(),
htmlAttrs: { htmlAttrs: {
'data-game': data.game_name ?? '', 'data-game': gameName.value ?? '',
'data-theme': designTheme, 'data-theme': gameTheme.value,
lang: locale.value ?? data.default_lang_code ?? 'ko', lang: locale.value ?? defaultLangCode.value ?? 'ko',
}, },
link: styleLinks, link: createStyleLinks(),
style: [ style: [
{ {
innerHTML: styleCss, innerHTML: styleCss,
@@ -127,12 +126,12 @@ if (import.meta.server) {
const gameData = nuxtApp.ssrContext?.event?.context?.gameData const gameData = nuxtApp.ssrContext?.event?.context?.gameData
if (gameData) { if (gameData) {
setGameData(gameData) setGameData(gameData)
setupGameHead(gameData)
} }
} }
let rafId: number | null = null setupGameHead()
let rafId: number | null = null
onMounted(() => { onMounted(() => {
useEventListener('scroll', scrollStore.updateScrollValue, { passive: true }) useEventListener('scroll', scrollStore.updateScrollValue, { passive: true })

View File

@@ -3,7 +3,7 @@ let mountedInstance: any = null
onMounted(() => { onMounted(() => {
const gameDataStore = useGameDataStore() const gameDataStore = useGameDataStore()
const { stoveGnbJson, defaultLangCode, langCodes, theme } = const { stoveGnbJson, defaultLangCode, langCodes, gameTheme } =
storeToRefs(gameDataStore) storeToRefs(gameDataStore)
const currentDomain = const currentDomain =
@@ -36,8 +36,8 @@ onMounted(() => {
}, },
mode: { mode: {
theme: { theme: {
support: [theme.value], support: [gameTheme.value],
default: theme.value, default: gameTheme.value,
}, },
mini: true, mini: true,
layout: 'wide', layout: 'wide',

View File

@@ -139,7 +139,7 @@ export default defineEventHandler(async event => {
let gameDataResponse: GameDataResponse | null = null let gameDataResponse: GameDataResponse | null = null
let gameDataLangCodes: string[] | null = null let gameDataLangCodes: string[] | null = null
let gameDataDefaultLocale: string | null = null let gameDataDefaultLangCode: string | null = null
let gameDataIntro: string | null = null let gameDataIntro: string | null = null
let finalLocale: string let finalLocale: string
@@ -156,7 +156,7 @@ export default defineEventHandler(async event => {
gameDataResponse = response gameDataResponse = response
gameDataLangCodes = response?.value?.lang_codes || null gameDataLangCodes = response?.value?.lang_codes || null
gameDataDefaultLocale = response?.value?.default_lang_code || null gameDataDefaultLangCode = response?.value?.default_lang_code || null
gameDataIntro = response?.value?.intro?.page_url || '' gameDataIntro = response?.value?.intro?.page_url || ''
event.context.gameDomain = gameDomain event.context.gameDomain = gameDomain
} catch (error) { } catch (error) {
@@ -195,7 +195,7 @@ export default defineEventHandler(async event => {
event?.node.req.url, event?.node.req.url,
event.node.req.headers, event.node.req.headers,
gameDataLangCodes, gameDataLangCodes,
gameDataDefaultLocale gameDataDefaultLangCode
) )
// 초기화 // 초기화
@@ -325,7 +325,7 @@ export default defineEventHandler(async event => {
event?.node.req.url, event?.node.req.url,
event.node.req.headers, event.node.req.headers,
gameDataLangCodes, gameDataLangCodes,
gameDataDefaultLocale gameDataDefaultLangCode
) )
} catch (e) { } catch (e) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console

View File

@@ -12,13 +12,17 @@ export const useGameDataStore = defineStore('gameData', () => {
gaCode: null as GameDataValue['ga_code'] | null, gaCode: null as GameDataValue['ga_code'] | null,
platformType: null as GameDataValue['platform_type'] | null, platformType: null as GameDataValue['platform_type'] | null,
osType: null as GameDataValue['os_type'] | null, osType: null as GameDataValue['os_type'] | null,
theme: null as 'light' | 'dark' | null, gameTheme: null as 'light' | 'dark' | null,
gameMetaTag: null as GameDataValue['meta_tag_json'] | null,
intro: null as GameDataValue['intro'] | null, intro: null as GameDataValue['intro'] | null,
imgJson: null as GameDataValue['img_json'] | null, imgJson: null as GameDataValue['img_json'] | null,
snsJson: null as GameDataValue['sns_json'] | null, snsJson: null as GameDataValue['sns_json'] | null,
urlJson: null as GameDataValue['url_json'] | null, urlJson: null as GameDataValue['url_json'] | null,
marketJson: null as GameDataValue['market_json'] | null, marketJson: null as GameDataValue['market_json'] | null,
faviconJson: null as GameDataValue['favicon_json'] | null,
gameFontJson: null as GameDataValue['game_font_json'] | null,
fontFamily: null as GameDataValue['game_font_json']['font_family'] | null, fontFamily: null as GameDataValue['game_font_json']['font_family'] | null,
keyColorJson: null as GameDataValue['key_color_json'] | null,
gnb: null as GameDataValue['gnb'] | null, gnb: null as GameDataValue['gnb'] | null,
eventBanner: null as GameDataValue['event_banner'] | null, eventBanner: null as GameDataValue['event_banner'] | null,
}) })
@@ -36,13 +40,17 @@ export const useGameDataStore = defineStore('gameData', () => {
state.gaCode = data?.ga_code state.gaCode = data?.ga_code
state.platformType = data?.platform_type state.platformType = data?.platform_type
state.osType = data?.os_type state.osType = data?.os_type
state.theme = data?.design_theme === 1 ? 'light' : 'dark' state.gameTheme = data?.design_theme === 1 ? 'light' : 'dark'
state.gameMetaTag = data?.meta_tag_json
state.intro = data?.intro state.intro = data?.intro
state.imgJson = data?.img_json state.imgJson = data?.img_json
state.snsJson = data?.sns_json state.snsJson = data?.sns_json
state.urlJson = data?.url_json state.urlJson = data?.url_json
state.marketJson = data?.market_json state.marketJson = data?.market_json
state.faviconJson = data?.favicon_json
state.gameFontJson = data?.game_font_json
state.fontFamily = data?.game_font_json?.font_family state.fontFamily = data?.game_font_json?.font_family
state.keyColorJson = data?.key_color_json
state.gnb = data?.gnb state.gnb = data?.gnb
state.eventBanner = data?.event_banner state.eventBanner = data?.event_banner
} }