Next.js 및 Nuxt.js에서의 국제화를 위한 모범 사례
James Reed
Infrastructure Engineer · Leapcell

소개
오늘날의 세계화된 디지털 환경에서 다양한 잠재고객에게 도달하는 것은 모든 성공적인 웹 애플리케이션에 있어 매우 중요합니다. 이를 달성하기 위한 중요한 단계는 국제화, 즉 i18n입니다. 이는 엔지니어링 변경 없이도 여러 언어와 지역을 지원하도록 애플리케이션을 설계하고 개발하는 프로세스입니다. Next.js 및 Nuxt.js와 같은 현대의 서버 렌더링 JavaScript 프레임워크를 사용하는 개발자에게 i18n을 효과적으로 구현하는 것은 선택 사항이 아니라 필수입니다. 이 글에서는 Next.js 및 Nuxt.js로 구축된 애플리케이션을 국제화하기 위한 모범 사례를 자세히 설명하고, 진정한 글로벌 사용자 경험을 만드는 데 도움이 되는 실제적인 지침과 코드 예제를 제공합니다.
국제화의 핵심 개념
구현 세부 사항을 살펴보기 전에 i18n 관련 핵심 개념에 대한 공통적인 이해를 정립해 보겠습니다.
- 국제화(i18n): 코드 변경 없이도 다양한 언어와 지역에 쉽게 적용할 수 있도록 애플리케이션을 설계하고 개발하는 프로세스입니다. 이는 애플리케이션을 현지화에 맞게 준비하는 것입니다.
- 현지화(l10n): 국제화된 애플리케이션을 특정 지역(언어와 지역 결합)에 맞게 조정하는 프로세스입니다. 여기에는 텍스트 번역, 날짜 및 숫자 서식 지정, 문화적 뉘앙스 처리 등이 포함됩니다.
- 지역: 사용자의 언어와 지역을 정의하는 문자열 식별자(예: 미국식 영어의
en-US
, 프랑스에서 사용되는 프랑스어의fr-FR
). - 메시지 파일/번역 사전: 키는 텍스트 문자열의 고유 식별자를 나타내고 값은 특정 지역의 번역된 문자열인 키-값 쌍 모음입니다. 일반적으로 JSON, YAML 또는 PO 파일입니다.
- 언어 협상: 종종 브라우저 설정, URL 매개변수 또는 사용자 선택을 기반으로 사용자 선호 언어를 결정하는 프로세스입니다.
- 동적 라우팅: 사용자가 선호하는 언어로 콘텐츠에 액세스할 수 있도록 로캘 정보를 포함하도록 URL을 구성하는 방법(예:
/en/about
대/fr/about
).
Next.js 및 Nuxt.js에서의 국제화 구현
Next.js와 Nuxt.js 모두 i18n을 훌륭하게 지원하며, 종종 Next.js의 react-i18next
와 Nuxt.js의 @nuxtjs/i18n
과 같은 인기 라이브러리를 활용합니다. 특정 구문은 다를 수 있지만, 기본 원리는 유사합니다.
i18n 라이브러리 선택
Next.js의 경우 react-i18next
가 사실상의 표준이며, 원활한 SSR 및 SSG 지원을 위해 next-i18next
패키지와 통합되는 경우가 많습니다. Nuxt.js의 경우 커뮤니티 유지 관리 모듈인 @nuxtjs/i18n
은 vue-i18n
을 기반으로 구축된 포괄적인 솔루션을 제공합니다.
구성 및 설정
Next.js의 next-i18next
와 Nuxt.js의 @nuxtjs/i18n
을 사용하여 설명하겠습니다.
next-i18next
를 사용한 Next.js
- 설치: ```bash npm install next-i18next react-i18next i18next
2. **`next-i18next.config.js`**: 프로젝트 루트에 구성 파일을 만듭니다. ```javascript
// next-i18next.config.js
module.exports = {
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr', 'es'],
},
localePath: typeof window === 'undefined' ? require('path').resolve('./public/locales') : '/locales',
reloadOnPrerender: process.env.NODE_ENV === 'development',
};
_app.js
통합:appWithTranslation
으로 애플리케이션을 감쌉니다. ```javascript // pages/_app.js import { appWithTranslation } from 'next-i18next'; import nextI18nConfig from '../next-i18next.config';
function MyApp({ Component, pageProps }) { return <Component {...pageProps} />; }
export default appWithTranslation(MyApp, nextI18nConfig);
4. **번역 파일**: `public/locales/[locale]/common.json`(또는 다른 네임스페이스)을 만듭니다. ```json
// public/locales/en/common.json
{
"welcome": "Welcome!",
"greeting": "Hello, {{name}}!"
}
// public/locales/fr/common.json
{
"welcome": "Bienvenue !",
"greeting": "Bonjour, {{name}} !"
}
@nuxtjs/i18n
을 사용한 Nuxt.js
- 설치: ```bash npm install @nuxtjs/i18n
2. **`nuxt.config.js` 구성**: 모듈을 추가하고 구성합니다. ```javascript
// nuxt.config.js
export default {
modules: [
'@nuxtjs/i18n',
],
i18n: {
locales: [
{ code: 'en', file: 'en.js', iso: 'en-US' },
{ code: 'fr', file: 'fr.js', iso: 'fr-FR' },
{ code: 'es', file: 'es.js', iso: 'es-ES' },
],
defaultLocale: 'en',
langDir: 'locales/', // 번역 파일 디렉토리
vueI18n: {
fallbackLocale: 'en',
},
strategy: 'prefix_and_default', // 'prefix_except_default', 'no_prefix', 'prefix'
},
};
- 번역 파일:
locales/[locale].js
를 만듭니다. ```javascript // locales/en.js export default { welcome: 'Welcome!', greeting: 'Hello, {name}!', };
// locales/fr.js export default { welcome: 'Bienvenue !', greeting: 'Bonjour, {name} !', };
### 콘텐츠 번역
구성 후에는 콘텐츠 번역이 간단합니다.
**Next.js (React 컴포넌트)**
```javascript
// pages/index.js
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
export default function Home() {
const { t } = useTranslation('common'); // 'common'은 네임스페이스입니다.
return (
<div>
<h1>{t('welcome')}</h1>
<p>{t('greeting', { name: 'Alice' })}</p>
</div>
);
}
export async function getStaticProps({ locale }) {
return {
props: {
...(await serverSideTranslations(locale, ['common'])),
},
};
}
Nuxt.js (Vue 컴포넌트)
<!-- pages/index.vue --> <template> <div> <h1>{{ $t('welcome') }}</h1> <p>{{ $t('greeting', { name: 'Alice' }) }}</p> </div> </template> <script> export default { // $i18n 인스턴스 액세스 mounted() { console.log(this.$i18n.locale); } } </script>
언어 전환
사용자가 언어를 변경할 수 있는 메커니즘을 제공하는 것이 중요합니다. 여기에는 일반적으로 i18n 라이브러리에서 현재 로캘을 업데이트하고, URL 접두사를 사용하는 경우 해당 지역화된 라우트로 이동하는 것이 포함됩니다.
Next.js (언어 전환 컴포넌트)
// components/LanguageSwitcher.js import { useRouter } from 'next/router'; import Link from 'next/link'; export default function LanguageSwitcher() { const router = useRouter(); const { locales, locale: currentLocale } = router; return ( <div> {locales.map((locale) => ( <Link key={locale} href={router.asPath} locale={locale}> <a style={{ fontWeight: locale === currentLocale ? 'bold' : 'normal', marginRight: '10px' }}> {locale.toUpperCase()} </a> </Link> ))} </div> ); }
Nuxt.js (언어 전환 컴포넌트)
<!-- components/LanguageSwitcher.vue --> <template> <div> <NuxtLink v-for="locale in availableLocales" :key="locale.code" :to="switchLocalePath(locale.code)" :class="{ 'font-bold': locale.code === $i18n.locale }" class="mr-2" > {{ locale.code.toUpperCase() }} </NuxtLink> </div> </template> <script> export default { computed: { availableLocales () { return this.$i18n.locales.filter(i => i.code !== this.$i18n.locale) } } } </script>
동적 라우팅 및 SEO
next-i18next
와 @nuxtjs/i18n
모두 지역화된 라우팅을 처리합니다. next-i18next
는 Next.js의 내장 국제화 라우팅과 직접 통합되며, @nuxtjs/i18n
은 /en/about
, /fr/about
, /about
(기본값)과 같은 URL 구조를 관리하기 위해 prefix_and_default
와 같은 다양한 전략을 제공합니다. SEO의 경우 각 지역화된 페이지 버전에 대해 자체적으로 가리키는 캐노니컬 URL과 다른 언어 버전을 참조하는 hreflang
태그가 있는지 확인하십시오. 이는 검색 엔진이 사이트의 국제 구조를 이해하는 데 도움이 됩니다.
날짜, 시간 및 숫자 서식 지정 처리
텍스트 번역 외에도 로캘은 날짜, 시간 및 숫자를 표시하는 방식에도 영향을 미칩니다. 강력한 이러한 요소의 현지화를 위해 Intl
API 또는 moment.js
또는 date-fns
와 같은 라이브러리를 i18n 라이브러리와 함께 사용하십시오.
Intl.DateTimeFormat
예시
const date = new Date(); const formattedDateEn = new Intl.DateTimeFormat('en-US').format(date); // 2023/1/1 const formattedDateFr = new Intl.DateTimeFormat('fr-FR').format(date); // 01/01/2023
서버 측 렌더링(SSR) 및 서버 측 생성(SSG) 고려 사항
Next.js와 Nuxt.js 모두 SEO 및 성능에 유익한 SSR/SSG에 뛰어나므로 i18n 설정을 클라이언트에서 올바르게 수화하고 서버에서 올바른 번역을 검색하는지 확인하십시오. next-i18next
의 serverSideTranslations
와 @nuxtjs/i18n
의 자동 로캘 감지 및 메시지 로딩은 이를 위해 설계되었습니다. 빌드 시에 생성된 페이지(SSG)는 모든 로캘에 대해 버전을 생성해야 합니다.
고급 사례 및 고려 사항
- 번역 관리 도구: 더 큰 프로젝트의 경우 Lokalise, Phrase 또는 Crowdin과 같은 번역 관리 시스템(TMS)을 고려하십시오. 이러한 도구는 번역 워크플로를 간소화하고, 협업 번역을 허용하며, 번역 파일을 가져오고 내보내기 위해 코드베이스와 직접 통합되는 경우가 많습니다.
- 번역 지연 로딩: 모든 로캘에 대한 모든 번역을 미리 로드하는 대신 필요한 언어 파일 또는 심지어 특정 네임스페이스만 필요할 때 지연 로딩하십시오. 이렇게 하면 초기 번들 크기가 크게 줄어듭니다.
- 대체 로캘: 기본 로캘에 번역 키가 누락된 경우를 대비하여 항상 대체 로캘(예:
en
)을 정의하십시오. - 복수형: 언어마다 복수형 규칙이 다릅니다. i18n 라이브러리는 일반적으로 이를 올바르게 처리하기 위한 메커니즘을 제공합니다.
react-i18next
: 번역 파일의 복수 규칙과 함께t('key', { count: 1 })
을 사용합니다.vue-i18n
:plural: 'Your item | Your items'
와 같은 특수 구문을 사용합니다.
- 오른쪽에서 왼쪽(RTL) 언어: 아랍어 또는 히브리어와 같은 언어의 경우 CSS를 조정하여 RTL 레이아웃을 지원하십시오.
html
태그에dir="rtl"
속성을 동적으로 적용하고 조건부로 다른 CSS 규칙을 로드해야 할 수 있습니다. - SEO 최적화:
hreflang
태그 외에도 페이지의 각 언어 버전에 대해 메타 설명, 제목 및 이미지 alt 텍스트도 지역화되었는지 확인하십시오. - 국제화 테스트: 텍스트 오버플로, 날짜/숫자 서식 지정 및 RTL 레이아웃에 주의를 기울여 다양한 로캘에서 지역화된 콘텐츠를 철저히 테스트합니다.
결론
국제화를 구현하는 것은 진정으로 글로벌 애플리케이션을 구축하기 위한 필수 단계입니다. Next.js 및 Nuxt.js의 강력한 기능과 전문 i18n 라이브러리 및 모범 사례를 활용함으로써 개발자는 원활하게 현지화된 사용자 경험을 만들 수 있습니다. 이러한 전략을 채택하면 애플리케이션이 기능적일 뿐만 아니라 문화적으로 관련성이 있고 전 세계 잠재 고객에게 접근 가능합니다. 국제화는 단순히 번역하는 것이 아니라 사용자의 언어와 문화적 맥락에서 연결하는 것입니다.