fix: 클라이언트 전용 코드로 변경하여 서버 사이드 렌더링 지원

This commit is contained in:
“hyeonggkim”
2025-11-14 16:21:24 +09:00
parent 7adb2ced25
commit ffa89ffbb6
9 changed files with 166 additions and 23 deletions

View File

@@ -52,6 +52,8 @@ const pathMatches = (base: string, current: string) => {
/** 자식 중 활성 링크 존재 여부 */
const hasActiveChild = (children?: GameDataMenuChildren) => {
if(!import.meta.client) return false
const cur = currentPath.value
return formatToArray(children).some(child => {
if (!child?.url_path || !isInternalUrl(child.url_path)) return false
@@ -61,6 +63,8 @@ const hasActiveChild = (children?: GameDataMenuChildren) => {
/** 1Depth 활성화 여부 */
const isNavItemActive = (gnbItem: GameDataMenu): boolean => {
if(!import.meta.client) return false
const cur = currentPath.value
const base = gnbItem?.url_path
const selfActive =
@@ -241,13 +245,13 @@ onBeforeUnmount(() => {
<header class="header">
<BlocksStoveGnbNew class="h-[48px]" />
<div :class="['game-wrap', { 'is-fixed': isPassedStoveGnb }]">
<AtomsLocaleLink to="/brand" class="mx-auto md:hidden">
<NuxtLinkLocale to="/brand" class="mx-auto md:hidden router-link-active router-link-exact-active">
<img
:src="getImageHost(gnbData?.bi_path)"
:alt="gameData?.game_name"
class="h-[30px]"
/>
</AtomsLocaleLink>
</NuxtLinkLocale>
<button class="btn-open" @click="handleMenuOpen">
<AtomsIconsMenuBoldLine class="mx-auto" />
<span class="sr-only">menu open</span>
@@ -255,13 +259,13 @@ onBeforeUnmount(() => {
<div :class="['nav-wrap', { 'is-open': isMenuOpen }]">
<div ref="navAreaRef" class="nav-area">
<div class="nav-logo">
<AtomsLocaleLink to="/brand" @click="handleMenuClose">
<NuxtLinkLocale to="/brand" class="router-link-active router-link-exact-active" @click="handleMenuClose">
<img
:src="getImageHost(gnbData?.bi_path)"
:alt="gameData?.game_name"
class="h-[30px]"
/>
</AtomsLocaleLink>
</NuxtLinkLocale>
</div>
<nav class="nav-list">
<div v-if="gnbData?.menus" class="official">

View File

@@ -95,6 +95,8 @@ const findValueFromOption = (target: string, { options = {} }: any) => {
* @param {object} options
*/
const sendGA = (analytics: AnalyticsDetailType, { options = {} }: any) => {
if (!import.meta.client) return
try {
const { gtag } = useGtag()
@@ -126,6 +128,8 @@ const sendSA = (
analytics: AnalyticsDetailType,
{ mcode = '', options = {} }: any
) => {
if (!import.meta.client) return
const gameDataStore = useGameDataStore()
const { gameData } = storeToRefs(gameDataStore)
@@ -198,8 +202,8 @@ const sendSA = (
const amplitudeActionInfo = {
...actionInfo,
url: `${location?.href || ''}`,
agent: `${navigator?.userAgent || ''}`,
url: import.meta.client ? `${location?.href || ''}` : '',
agent: import.meta.client ? `${navigator?.userAgent || ''}` : '',
}
const amplitudeActionParams: {
@@ -249,6 +253,8 @@ const sendLog = (locale: string, analytics: AnalyticsDetailType) => {
* @param {string} gaEventName
*/
const sendGAEventOnly = (gaEventName: string) => {
if (!import.meta.client) return
try {
const { gtag } = useGtag()
@@ -267,6 +273,8 @@ const sendGAEventOnly = (gaEventName: string) => {
* @description 수집 대상 페이지에 useHead({ meta: [loadMetaPixelMeta()] }) 선언
*/
const sendMetaPixel = (fbEventName: string) => {
if (!import.meta.client) return
try {
const { $fbq } = useNuxtApp()
if (typeof $fbq === 'function') {
@@ -284,6 +292,8 @@ const sendMetaPixel = (fbEventName: string) => {
* @description 수집 대상 페이지에 useHead({ script: [loadTwitterPixelScript()] }) 선언
*/
const sendTwitterPixel = (twEventName: string) => {
if (!import.meta.client) return
try {
twq('event', twEventName, {})
} catch (e) {
@@ -298,6 +308,8 @@ const sendTwitterPixel = (twEventName: string) => {
* @description 수집 대상 페이지에 onMounted(() => { loadTikTokPixelScript() }) 선언
*/
const sendTiktokPixel = (ttEventName: string) => {
if (!import.meta.client) return
try {
ttq.track(ttEventName)
} catch (e) {

View File

@@ -100,7 +100,9 @@ export default defineNuxtRouteMiddleware(async (to, _from) => {
if (response?.code === 91003) {
// return navigateTo(`/${langCode}/error`, { external: false })
//클릭한 주소는 주소표시줄에 표시하도록 수정
window.history.replaceState({}, '', to.path)
if (import.meta.client) {
window.history.replaceState({}, '', to.path)
}
// 뒤로가기 이동 시 이전 페이지로 이동되도록 수정
showError(
createError({

View File

@@ -25,6 +25,8 @@ export const useModalStore = defineStore('modalStore', () => {
* @param state - 모달 바디 상태
*/
const handleControlDimmed = (state: boolean) => {
if (!import.meta.client) return
if (state) {
document.body.classList.add('dimmed')
} else {

View File

@@ -23,6 +23,8 @@ export const useScrollStore = defineStore('scrollStore', () => {
}
const controlScrollLock = (state: boolean) => {
if (!import.meta.client) return
if (state) {
document.body.classList.add('scroll-lock')
} else {

View File

@@ -72,15 +72,17 @@ export const csrGetFinalLocale = (path = '', coveragesLocales: string[]) => {
}
// 3. 브라우저 언어
const browserLanguage =
`${navigator.language || navigator.languages[0]}`.toLowerCase()
if (
browserLanguage &&
browserLanguage !== '' &&
coveragesLocales.includes(browserLanguage)
) {
finalLocale = browserLanguage
return finalLocale
if (import.meta.client) {
const browserLanguage =
`${navigator.language || navigator.languages[0]}`.toLowerCase()
if (
browserLanguage &&
browserLanguage !== '' &&
coveragesLocales.includes(browserLanguage)
) {
finalLocale = browserLanguage
return finalLocale
}
}
// 3. 서비스 기본 언어

View File

@@ -9,6 +9,8 @@ import { csrFormatJWT } from '#layers/utils/formatUtil'
* Stove 로그인
*/
export const csrGoStoveLogin = () => {
if (!import.meta.client) return
const runtimeConfig = useRuntimeConfig()
const gameDataStore = useGameDataStore()