refactor: 언어 정책 쿠키 i18n에서 설정, gameData External 제거

This commit is contained in:
“hyeonggkim”
2025-11-13 18:46:03 +09:00
parent 4698efc225
commit 4b7ccd8f4f
7 changed files with 98 additions and 83 deletions

View File

@@ -50,22 +50,26 @@ const getI18n = (allowedLangCodes?: string[]): NuxtI18nOptions => {
)
return {
baseUrl: process.env.BASE_URL,
strategy: 'prefix',
vueI18n: 'custom',
locales: DEFAULT_LOCALE_COVERAGES_SET,
defaultLocale: DEFAULT_LOCALE_CODE || 'ko',
defaultLocale: DEFAULT_LOCALE_CODE,
detectBrowserLanguage: {
fallbackLocale: DEFAULT_LOCALE_CODE || 'ko',
useCookie: false,
fallbackLocale: DEFAULT_LOCALE_CODE,
useCookie: true,
cookieKey: 'LOCALE',
cookieDomain: process.env.BASE_DOMAIN,
redirectOn: 'root',
},
langDir: '../i18n/locales',
compilation: {
strictMessage: false,
escapeHtml: false,
},
debug: false,
// 동적으로 언어 제외 설정을 위한 pages 설정
customRoutes: 'config',
// customRoutes: 'config',
// pages:
// allowedLangCodes && allowedLangCodes.length > 0
// ? generatePageExclusions(allowedLangCodes)
@@ -75,20 +79,20 @@ const getI18n = (allowedLangCodes?: string[]): NuxtI18nOptions => {
}
// gameData.lang_codes를 기반으로 언어 제외 설정을 생성하는 함수
const generatePageExclusions = (
allowedLangCodes: string[]
): Record<string, any> => {
const exclusions: Record<string, any> = {}
// const generatePageExclusions = (
// allowedLangCodes: string[]
// ): Record<string, any> => {
// const exclusions: Record<string, any> = {}
// 모든 기본 언어에 대해 제외 설정 생성
DEFAULT_COVERAGES.forEach(langCode => {
if (!allowedLangCodes.includes(langCode)) {
// 해당 언어가 허용되지 않으면 모든 페이지에서 제외
exclusions[langCode] = false
}
})
// // 모든 기본 언어에 대해 제외 설정 생성
// DEFAULT_COVERAGES.forEach(langCode => {
// if (!allowedLangCodes.includes(langCode)) {
// // 해당 언어가 허용되지 않으면 모든 페이지에서 제외
// exclusions[langCode] = false
// }
// })
return exclusions
}
// return exclusions
// }
export { DEFAULT_LOCALE_CODE, DEFAULT_COVERAGES, getI18n }

View File

@@ -186,7 +186,7 @@ const switchLanguage = async () => {
maxAge: 60 * 60 * 24 * 365, // 1년 (초 단위)
sameSite: 'lax',
})
localeCookie.value = selectedLocale.value.toUpperCase()
localeCookie.value = selectedLocale.value.toLowerCase()
// 페이지 데이터 초기화 (새로운 언어로 다시 로드되도록)
pageDataStore.clearPageData()

View File

@@ -1,7 +1,8 @@
<script setup lang="ts">
import type { GameDataValue } from '#layers/types/api/gameData'
let mountedInstance: any = null
const runtimeConfig = useRuntimeConfig()
const baseDomain = `${runtimeConfig.public.baseDomain}`
onMounted(() => {
const gameDataStore = useGameDataStore()
const gameData = gameDataStore.gameData as GameDataValue
@@ -15,7 +16,7 @@ onMounted(() => {
if (typeof window !== 'undefined' && (window as any).StoveGnb) {
const stoveGnbOptions = {
logArea: currentDomain,
useLanguageCodeFromPath: true,
useLanguageCodeFromPath: false,
serviceTitle: {
pc: '',
mobile: '',
@@ -53,8 +54,22 @@ onMounted(() => {
stoveGnbOptions
)
}
if(mountedInstance){
//Stove GNB에서도 쿠키를 굽고 있어 소문자로 통일
//LOCALE 쿠키를 가져온 후 소문자로 변경해서 다시 LOCALE 쿠키를 설정
nextTick(() => {
const localeCookie = useCookie('LOCALE', {
domain: baseDomain,
path: '/',
maxAge: 60 * 60 * 24 * 365, // 1년 (초 단위)
})
localeCookie.value = localeCookie.value.toLowerCase()
})
}
})
onBeforeUnmount(() => {
if (mountedInstance && typeof mountedInstance.destroy === 'function') {
mountedInstance.destroy()

View File

@@ -1,15 +1,27 @@
import type { GameDataRequest, GameDataValue } from '#layers/types/api/gameData'
export default defineNuxtRouteMiddleware(async (to, _from) => {
const nuxtApp = useNuxtApp()
const getGameDataFromServer = (): GameDataValue | null => {
return import.meta.server
? (nuxtApp.ssrContext?.event.context.gameData ?? null)
: null
}
const serverGameData = getGameDataFromServer()
const gameDataStore = useGameDataStore()
const { setGameData } = gameDataStore
if (serverGameData) {
setGameData(serverGameData)
}
try{
// 서버 사이드에서는 스킵
if (import.meta.server) {
if (!import.meta.client) {
return
}
// 현재 경로에서 언어 코드 추출
const gameDataStore = useGameDataStore()
const gameData = gameDataStore.gameData as GameDataValue
const langCodes = gameData?.lang_codes
const currentLangCode = csrGetFinalLocale(to.path, langCodes)
@@ -17,28 +29,28 @@ export default defineNuxtRouteMiddleware(async (to, _from) => {
const pageUrl = getPathAfterLanguage(to.path)
//현재 url에서 게임 도메인만 추출
const currentDomain = window.location.hostname
const runtimeConfig = useRuntimeConfig()
// const currentDomain = window.location.hostname
// const runtimeConfig = useRuntimeConfig()
// 쿼리스트링에서 f 파라미터 값 추출 (CSR용)
const fValue = (to.query.f as string) || ''
// const fValue = (to.query.f as string) || ''
// 미리보기 API 호출 처리
let finalGameDomain = currentDomain
if (fValue === 'preview') {
finalGameDomain = 'samplegame.onstove.com'
}
// let finalGameDomain = currentDomain
// if (fValue === 'preview') {
// finalGameDomain = 'samplegame.onstove.com'
// }
const req: GameDataRequest = {
gameDomain: `${finalGameDomain}`,
langCode: `${currentLangCode}`,
game_alias: '',
lang_code: `${currentLangCode}`,
baseApiUrl: `${runtimeConfig.public.stoveApiUrl}`,
gameId: '',
}
const { getGameDataExternal } = useGetGameDataExternal()
await getGameDataExternal(req)
// const req: GameDataRequest = {
// gameDomain: `${finalGameDomain}`,
// langCode: `${currentLangCode}`,
// game_alias: '',
// lang_code: `${currentLangCode}`,
// baseApiUrl: `${runtimeConfig.public.stoveApiUrl}`,
// gameId: '',
// }
// const { getGameDataExternal } = useGetGameDataExternal()
// await getGameDataExternal(req)
// error 페이지는 API 호출하지 않음

View File

@@ -16,16 +16,17 @@ export default defineNuxtRouteMiddleware(async (to, _from) => {
const store = usePageDataStore()
const gameDomain = useGetGameDomain()
const { getPathAfterLanguage } = usePathResolver()
const headers = useRequestHeaders()
const gameDataStore = useGameDataStore()
const gameData = gameDataStore.gameData as GameDataValue
console.log("🚀 ~ gameDomain:", gameDomain)
const langCode = ssrGetFinalLocale(
const langCode = csrGetFinalLocale(
to.path,
headers,
gameData?.lang_codes,
gameData?.default_lang_code
)
console.log("🚀 ~ to.path:", to.path)
console.log("🚀 ~ langCode:", gameData?.lang_codes)
console.log("🚀 ~ langCode:", langCode)
try {
@@ -35,17 +36,18 @@ export default defineNuxtRouteMiddleware(async (to, _from) => {
}
const pageUrl = getPathAfterLanguage(to.path)
// error 페이지는 API 호출하지 않음
if (pageUrl === '/error' || to.path.includes('/error')) {
return
}
console.log("🚀 ~ pageUrl:", pageUrl)
// pageUrl이 빈값이거나 null이면 /brand로 리다이렉트
if (!pageUrl || pageUrl === '' || pageUrl === '/' || pageUrl === `/${langCode}/`) {
return navigateTo(`/${langCode}/brand`, { external: false })
}
// error 페이지는 API 호출하지 않음
if (pageUrl === '/error' || to.path.includes('/error')) {
return
}
const accessToken = csrGetAccessToken()
const headers = {
@@ -53,16 +55,16 @@ export default defineNuxtRouteMiddleware(async (to, _from) => {
}
// 쿼리스트링에서 f 파라미터 값 추출 (CSR용)
const fValue = (to.query.f as string) || ''
// const fValue = (to.query.f as string) || ''
// 미리보기 API 호출 처리
let finalGameDomain = gameDomain
if (fValue === 'preview') {
finalGameDomain = 'samplegame.onstove.com'
}
// // 미리보기 API 호출 처리
// let finalGameDomain = gameDomain
// if (fValue === 'preview') {
// finalGameDomain = 'samplegame.onstove.com'
// }
const queryParams: Record<string, string> = {
game_domain: finalGameDomain,
game_domain: gameDomain,
lang_code: langCode,
page_url: pageUrl,
_t: Date.now().toString(), // 캐시 무효화를 위한 타임스탬프

View File

@@ -68,8 +68,7 @@ const cache = new LRUCache({
* @param baseDomain - 기본 도메인
*/
function setFinalLocaleCookie(event: any, finalLocale: string, baseDomain: string) {
console.log("🚀 ~ 구어 구어 setFinalLocaleCookie:============", finalLocale)
setCookie(event, 'LOCALE', finalLocale.toUpperCase(), {
setCookie(event, 'LOCALE', finalLocale.toLowerCase(), {
domain: baseDomain,
path: '/',
maxAge: 60 * 60 * 24 * 365, // 1년 (초 단위)
@@ -191,7 +190,7 @@ export default defineEventHandler(async event => {
initLangCodes = initResponse?.value?.lang_codes || null
initDefaultLocale = initResponse?.value?.default_lang_code || null
console.log('🚀 ~ 000111 initLangCodes:', initLangCodes)
console.log('🚀 ~ initLangCodes:===========', initLangCodes)
} catch (error) {
console.error('init gameData load error:', error)
}

View File

@@ -95,18 +95,10 @@ export const csrGetFinalLocale = (path = '', coveragesLocales: string[]) => {
* @param {string} path - 현재 URL 경로
* @param {any} headers - 요청 헤더
*/
export const ssrGetFinalLocale = (path = '', headers: any, coveragesLocales: string[], defaultLocale: string) => {
let finalLocale // 기본값 설정
try {
// coveragesLocales가 빈 배열이거나 유효하지 않은 경우 기본 언어 반환
if (
!coveragesLocales ||
!Array.isArray(coveragesLocales) ||
coveragesLocales.length === 0
) {
return finalLocale
}
export const ssrGetFinalLocale = (path, headers: any, coveragesLocales: string[], defaultLocale: string) => {
let finalLocale = defaultLocale // 기본값 설정
try {
// 1. URL path에 포함된 언어 정보
if (path && path !== '' && path.split('/').length > 1) {
// 쿼리스트링 제거한 순수 path 검사
@@ -115,12 +107,9 @@ export const ssrGetFinalLocale = (path = '', headers: any, coveragesLocales: str
}
const pathLocalee = `${path.split('/')[1]}`.toLowerCase()
// URL path에 포함된 언어 정보가 지원하는 언어인지 체크
if (
pathLocalee &&
pathLocalee !== '' &&
coveragesLocales.includes(pathLocalee)
) {
if (pathLocalee && pathLocalee !== '' && coveragesLocales.includes(pathLocalee)) {
finalLocale = pathLocalee
return finalLocale
}
}
@@ -128,14 +117,8 @@ export const ssrGetFinalLocale = (path = '', headers: any, coveragesLocales: str
// 2. LOCALE 쿠키 언어 (SSR에서는 headers에서 직접 파싱)
const cookieHeader = headers.cookie || ''
const cookies = parseCookies(cookieHeader)
const cookieLanguage = cookies.LOCALE
? `${cookies.LOCALE}`.toLowerCase()
: ''
if (
cookieLanguage &&
cookieLanguage !== '' &&
coveragesLocales.includes(cookieLanguage)
) {
const cookieLanguage = cookies.LOCALE ? `${cookies.LOCALE}`.toLowerCase() : ''
if (cookieLanguage && cookieLanguage !== '' && coveragesLocales.includes(cookieLanguage)) {
finalLocale = cookieLanguage
return finalLocale
}
@@ -163,7 +146,7 @@ export const ssrGetFinalLocale = (path = '', headers: any, coveragesLocales: str
// 3. 서비스 기본 언어
finalLocale = defaultLocale
} catch {
} catch (e) {
finalLocale = defaultLocale
}
return finalLocale