Files
uniare.sori.studio/script/page-i18n.js

76 lines
2.2 KiB
JavaScript

/**
* data-i18n 속성 기반 페이지 번역
*/
(function initPageI18n() {
const SUPPORTED_LANGUAGES = new Set(['ko', 'ja', 'en']);
/**
* @returns {Promise<string>}
*/
function getLang() {
const fromQuery = new URLSearchParams(window.location.search).get('lang');
const selected = fromQuery || localStorage.getItem('lang') || 'ko';
return SUPPORTED_LANGUAGES.has(selected) ? selected : 'ko';
}
/**
* @param {string} lang
* @returns {Promise<object>}
*/
async function loadTranslations(lang) {
try {
const res = await fetch(`/i18n/translations.${lang}.json`);
if (!res.ok) return {};
return await res.json();
} catch {
return {};
}
}
let cachedTranslations = {};
/**
* @param {string} key
* @param {string} [fallback]
* @returns {string}
*/
function t(key, fallback = '') {
return cachedTranslations[key] || fallback;
}
/**
* @param {object} translations
*/
function applyTranslations(translations) {
document.querySelectorAll('[data-i18n]').forEach((el) => {
const key = el.dataset.i18n;
if (translations[key]) el.textContent = translations[key];
});
document.querySelectorAll('[data-i18n-html]').forEach((el) => {
const key = el.dataset.i18nHtml;
if (translations[key]) el.innerHTML = translations[key];
});
document.querySelectorAll('[data-i18n-placeholder]').forEach((el) => {
const key = el.dataset.i18nPlaceholder;
if (translations[key]) el.placeholder = translations[key];
});
if (window.UaPageHelp?.bindPageHelp) {
window.UaPageHelp.bindPageHelp(translations);
}
}
async function applyPageI18n() {
const lang = await getLang();
document.documentElement.lang = lang;
cachedTranslations = await loadTranslations(lang);
applyTranslations(cachedTranslations);
return cachedTranslations;
}
document.addEventListener('DOMContentLoaded', () => {
applyPageI18n();
});
window.UaPageI18n = { applyPageI18n, getLang, loadTranslations, t };
})();