Files
web-temp/layers/utils/localeUtil.ts
2025-09-19 19:11:01 +09:00

167 lines
5.1 KiB
TypeScript

import { DEFAULT_LOCALE_CODE, DEFAULT_COVERAGES } 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
}
export const getFinalLanguage = (path = '', defaultLocale: string, coverages: string[]) => {
// const nuxtApp = useNuxtApp()
let finalLocale = ''
let requestedLocale
let acceptLanguage: string
let defaultLang = 'en'
let defaultLangEn: string
if (defaultLocale) {
defaultLangEn = defaultLocale
} else {
defaultLangEn = 'en'
}
requestedLocale = path?.split('/')[1]?.toLowerCase() ?? 'undefined'
if (import.meta.server) {
const headers = useRequestHeaders(['accept-language'])
acceptLanguage = headers['accept-language'] || defaultLangEn
defaultLang =
coverages.find((locale: string) => getPreferredLanguage(acceptLanguage)?.startsWith(locale)) || defaultLangEn
}
// const DEFAULT_COVERAGES = i18n.locales.map((locale) => locale.code)
const DEFAULT_COVERAGES = coverages
const requestedPage = path?.split('/')[2]?.toLowerCase() ?? undefined
const localeMap: Record<string, string> = {
'zh-tw': 'zh-TW',
'zh-cn': 'zh-CN'
}
if (localeMap[requestedLocale]) {
requestedLocale = localeMap[requestedLocale]
}
if (requestedLocale !== undefined && DEFAULT_COVERAGES.includes(requestedLocale)) {
finalLocale = requestedLocale
} else if (
requestedLocale === undefined ||
requestedLocale === '' ||
path !== '' ||
(requestedLocale !== undefined && !DEFAULT_COVERAGES.includes(requestedLocale) && requestedPage !== undefined)
) {
// 요청된 언어가 없을 때 or 잘못된 언어코드로 요청 시 브라우저 언어로 설정
finalLocale = defaultLang
} else {
// 그 외의 경우 기본 언어로 설정 (중국어 번체)
finalLocale = defaultLangEn
}
return finalLocale.toLowerCase()
}
/**
* 우선순위에 따른 언어 조회 (CSR)
*
* @param {string} path - 현재 URL 경로
*/
export const csrGetFinalLocale = (path = '') => {
let finalLocale = DEFAULT_LOCALE_CODE // 기본값 설정
const localeMap: Record<string, string> = {
'zh-tw': 'zh-TW',
'zh-cn': 'zh-CN'
}
// 1. URL 패스에 포함된 언어
if (path && path !== '' && path.split('/').length > 1) {
const pathLocal = path.split('/')[1]
// URL 패스에 포함된 언어가 지원하는 언어인지 체크
if (pathLocal && pathLocal !== '' && DEFAULT_COVERAGES.includes(pathLocal)) {
finalLocale = pathLocal // .toLowerCase()
if (localeMap[pathLocal]) {
finalLocale = localeMap[pathLocal]
}
}
return finalLocale
}
// 2. 브라우저 언어
const browserLanguage = navigator.language || navigator.languages[0]
if (browserLanguage && browserLanguage !== '' && DEFAULT_COVERAGES.includes(browserLanguage)) {
finalLocale = browserLanguage // .toLowerCase()
if (localeMap[browserLanguage]) {
finalLocale = localeMap[browserLanguage]
}
return finalLocale
}
// 3. 서비스 기본 언어
finalLocale = DEFAULT_LOCALE_CODE
return finalLocale
}
/**
* 우선순위에 따른 언어 조회 (SSR)
*
* @param {string} path - 현재 URL 경로
* @param {any} headers - 요청 헤더
*/
export const ssrGetFinalLocale = (path = '', headers: any) => {
let finalLocale = DEFAULT_LOCALE_CODE // 기본값 설정
try {
// 1. URL path에 포함된 언어 정보
if (path && path !== '' && path.split('/').length > 1) {
const pathLocale = path.split('/')[1]
// URL path에 포함된 언어 정보가 지원하는 언어인지 체크
if (pathLocale && pathLocale !== '' && DEFAULT_COVERAGES.includes(pathLocale)) {
finalLocale = pathLocale // .toLowerCase()
return finalLocale
}
}
// 2. 요청 헤더의 브라우저 언어 (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 = DEFAULT_COVERAGES.find((locale: string) =>
preferredLocale.toLowerCase().startsWith(locale.toLowerCase())
)
if (matchedLocale) {
finalLocale = matchedLocale
// return matchedLocale.toLowerCase()
return finalLocale
}
}
}
}
// 3. 서비스 기본 언어
finalLocale = DEFAULT_LOCALE_CODE
} catch (e) {
console.error('[Exception] localeUtil.ssrGetFinalLocale: ', e)
finalLocale = DEFAULT_LOCALE_CODE
}
return finalLocale
}