import { DEFAULT_LOCALE_CODE } from '@/i18n.config' // 사용자 선호 언어 조회 export const getPreferredLanguage = (acceptLanguageHeader = '') => { const languages = acceptLanguageHeader .split(',') .map(lang => { const [code, priority = 'q=1'] = lang.trim().split(';q=') return { code, priority: parseFloat(priority) } }) .sort((a, b) => b.priority - a.priority) return languages.length > 0 ? languages[0].code : null } // 쿠키 파싱 유틸리티 함수 const parseCookies = (cookieHeader: string) => { const cookies: Record = {} if (cookieHeader) { cookieHeader.split(';').forEach(cookie => { const [name, value] = cookie.trim().split('=') if (name && value) { cookies[name] = decodeURIComponent(value) } }) } return cookies } /** * 우선순위에 따른 언어 조회 (CSR) * * @param {string} path - 현재 URL 경로 */ export const csrGetFinalLocale = (path = '', coveragesLocales: string[]) => { const runtimeConfig = useRuntimeConfig() const baseDomain = `${runtimeConfig.public.baseDomain}` let finalLocale = DEFAULT_LOCALE_CODE // 기본값 설정 // 1. URL 패스에 포함된 언어 if (path && path !== '' && path.split('/').length > 1) { // 쿼리스트링 제거한 순수 path 검사 if (path.includes('?')) { path = path.split('?')[0] } const pathLocale = `${path.split('/')[1]}`.toLowerCase() // URL 패스에 포함된 언어가 지원하는 언어인지 체크 if ( pathLocale && pathLocale !== '' && coveragesLocales.includes(pathLocale) ) { finalLocale = pathLocale return finalLocale } return finalLocale } // 2. LOCALE 쿠키 언어 const cookieLanguage = `${useCookie('LOCALE', { domain: baseDomain }).value}`.toLowerCase() if ( cookieLanguage && cookieLanguage !== '' && coveragesLocales.includes(cookieLanguage) ) { finalLocale = cookieLanguage return finalLocale } // 3. 브라우저 언어 const browserLanguage = `${navigator.language || navigator.languages[0]}`.toLowerCase() if ( browserLanguage && browserLanguage !== '' && coveragesLocales.includes(browserLanguage) ) { finalLocale = browserLanguage return finalLocale } // 3. 서비스 기본 언어 finalLocale = DEFAULT_LOCALE_CODE return finalLocale } /** * 우선순위에 따른 언어 조회 (SSR) * * @param {string} path - 현재 URL 경로 * @param {any} headers - 요청 헤더 */ 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 검사 if (path.includes('?')) { path = path.split('?')[0] } const pathLocalee = `${path.split('/')[1]}`.toLowerCase() // URL path에 포함된 언어 정보가 지원하는 언어인지 체크 if ( pathLocalee && pathLocalee !== '' && coveragesLocales.includes(pathLocalee) ) { finalLocale = pathLocalee return finalLocale } } // 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) ) { finalLocale = cookieLanguage return finalLocale } // 3. 요청 헤더의 브라우저 언어 (accept-language) if (headers && headers['accept-language']) { const acceptLanguage = Array.isArray(headers['accept-language']) ? headers['accept-language'][0] : headers['accept-language'] if (acceptLanguage && typeof acceptLanguage === 'string') { const preferredLocale = getPreferredLanguage(acceptLanguage) if (preferredLocale) { // 선호 언어의 기본 코드와 일치하는 지원 로케일 찾기 const matchedLocale = coveragesLocales.find((locale: string) => preferredLocale.toLowerCase().startsWith(locale.toLowerCase()) ) if (matchedLocale) { finalLocale = matchedLocale.toLowerCase() return finalLocale } } } } // 4. 서비스 기본 언어 finalLocale = defaultLocale } catch (e) { finalLocale = defaultLocale } return finalLocale }