Next.js 국제화(i18n) with next-intl 및 Intlayer
next-intl과 Intlayer는 Next.js 애플리케이션을 위해 설계된 오픈 소스 국제화(i18n) 프레임워크입니다. 이들은 소프트웨어 프로젝트에서 번역, 지역화 및 언어 전환 관리를 위해 널리 사용됩니다.
이들은 세 가지 주요 개념을 공유합니다:
콘텐츠 선언: 애플리케이션의 번역 가능한 콘텐츠를 정의하는 방법입니다.
- Intlayer에서 content declaration file이라고 불리는 이 파일은 구조화된 데이터를 내보내는 JSON, JS 또는 TS 파일이 될 수 있습니다. 자세한 내용은 Intlayer 문서에서 확인하세요.
- next-intl에서는 일반적으로 JSON 파일에서 messages 또는 locale messages라고 불립니다. 자세한 내용은 next-intl 문서에서 확인하세요.
유틸리티: 애플리케이션 내에서 콘텐츠 선언을 구축하고 해석하기 위한 도구로, Intlayer의 useIntlayer() 또는 useLocale(), next-intl의 useTranslations() 등이 있습니다.
플러그인 및 미들웨어: URL 리디렉션 관리, 번들 최적화 등을 위한 기능 - 예를 들어, Intlayer의 intlayerMiddleware 또는 next-intl의 createMiddleware 등이 있습니다.
Intlayer vs. next-intl: 주요 차이점
Intlayer가 next.js의 다른 i18n 라이브러리(예: next-intl)와 어떻게 비교되는지에 대한 더 깊은 분석을 위해서는 next-i18next vs. next-intl vs. Intlayer 블로그 포스트를 확인하세요.
Intlayer로 next-intl 메시지 생성 방법
Intlayer를 next-intl과 함께 사용해야 하는 이유는 무엇인가요?
Intlayer 콘텐츠 선언 파일은 일반적으로 더 나은 개발자 경험을 제공합니다. 두 가지 주요 이점 때문에 더 유연하고 유지 관리가 용이합니다:
유연한 배치: Intlayer 콘텐츠 선언 파일을 애플리케이션의 파일 트리 어디에나 배치할 수 있습니다. 이를 통해 사용되지 않거나 남아 있는 메시지 파일 없이 구성 요소의 이름을 바꾸거나 삭제할 수 있습니다.
예시 파일 구조:
bash.└── src └── components └── MyComponent ├── index.content.ts # 콘텐츠 선언 파일 └── index.tsx
중앙집중식 번역: Intlayer는 모든 번역을 하나의 콘텐츠 선언에 저장하여 아무런 번역도 누락되지 않도록 합니다. TypeScript 프로젝트에서는 누락된 번역이 자동으로 타입 오류로 표시되어 개발자가 즉각적으로 피드백을 받을 수 있습니다.
설치
Intlayer와 next-intl을 함께 사용하려면 두 라이브러리를 모두 설치해야 합니다:
npm install intlayer next-intl
Intlayer를 구성하여 next-intl 메시지 내보내기
참고: Intlayer에서 next-intl용 메시지를 내보내면 구조에 약간의 차이가 발생할 수 있습니다. 가능하다면 Intlayer 전용 또는 next-intl 전용 플로우를 유지하여 통합을 간소화하세요. Intlayer에서 next-intl 메시지를 생성해야 하는 경우 아래 단계를 따르세요.
프로젝트의 루트에 있는 intlayer.config.ts 파일(또는 .mjs / .cjs)을 생성하거나 업데이트하세요:
import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = { internationalization: { locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], defaultLocale: Locales.ENGLISH, }, content: { dictionaryOutput: ["next-intl"], // next-intl 출력을 사용 nextIntlMessagesDir: "./intl/messages", // next-intl 메시지를 저장할 위치 },};export default config;
콘텐츠 선언
다음은 여러 형식의 콘텐츠 선언 파일 예시입니다. Intlayer는 이를 next-intl이 소비할 수 있는 메시지 파일로 컴파일합니다.
import { t, type DeclarationContent } from "intlayer";const content = { key: "my-component", content: { helloWorld: t({ en: "Hello World", fr: "Bonjour le monde", es: "Hola Mundo", }), },} satisfies DeclarationContent;export default content;
next-intl 메시지 빌드
next-intl용 메시지 파일을 빌드하려면 다음을 실행하세요:
npx intlayer build
이 명령은 ./intl/messages 디렉토리에 리소스를 생성합니다(이는 intlayer.config.*에 구성되어 있습니다). 예상 출력은 다음과 같습니다:
.└── intl └── messages └── ko └── my-content.json └── fr └── my-content.json └── es └── my-content.json
각 파일은 모든 Intlayer 콘텐츠 선언으로부터 컴파일된 메시지를 포함합니다. 최상위 키는 일반적으로 content.key 필드와 일치합니다.
다음.js 앱에서 next-intl 사용하기
더 자세한 내용은 공식 next-intl 사용 문서를 참조하세요.
미들웨어 생성 (선택 사항):
자동 언어 감지 또는 리디렉션을 관리하려면 next-intl의 createMiddleware를 사용하세요.middleware.tsimport createMiddleware from "next-intl/middleware";import { NextResponse } from "next/server";export default createMiddleware({ locales: ["en", "fr", "es"], defaultLocale: "en",});export const config = { matcher: ["/((?!api|_next|.*\\..*).*)"],};
메시지를 로드하기 위한 layout.tsx 또는 _app.tsx 생성:
App Router(Next.js 13+)를 사용하는 경우 레이아웃을 생성하세요:app/[locale]/layout.tsximport { NextIntlClientProvider } from 'next-intl';import { notFound } from 'next/navigation';import React, { ReactNode } from 'react';export const dynamic = 'force-dynamic';export default async function RootLayout({ children, params}: { children: ReactNode; params: { locale: string };}) { let messages; try { messages = (await import(`../../intl/messages/${params.locale}.json`)).default; } catch (error) { notFound(); } return ( <html lang={params.locale}> <body> <NextIntlClientProvider locale={params.locale} messages={messages}> {children} </NextIntlClientProvider> </body> </html> );}
페이지 라우터(Next.js 12 이하)를 사용하는 경우 _app.tsx에서 메시지를 로드하세요:
pages/_app.tsximport type { AppProps } from 'next/app';import { NextIntlProvider } from 'next-intl';function MyApp({ Component, pageProps }: AppProps) { return ( <NextIntlProvider locale={pageProps.locale} messages={pageProps.messages}> <Component {...pageProps} /> </NextIntlProvider> );}export default MyApp;
서버 측에서 메시지 가져오기 (페이지 라우터 예시):
pages/index.tsximport { GetServerSideProps } from "next";import HomePage from "../components/HomePage";export default HomePage;export const getServerSideProps: GetServerSideProps = async ({ locale }) => { const messages = (await import(`../intl/messages/${locale}.json`)).default; return { props: { locale, messages, }, };};
Next.js 구성 요소에서 콘텐츠 사용하기
메시지가 next-intl에 로드된 후, useTranslations() 후크를 통해 구성 요소에서 사용할 수 있습니다:
import type { FC } from "react";import { useTranslations } from 'next-intl';const MyComponent: FC = () => { const t = useTranslations('my-component'); // 'my-component'는 Intlayer의 콘텐츠 키에 해당합니다. return ( <div> <h1>{t('helloWorld')}</h1> </div> );};export default MyComponent;
그게 전부입니다! Intlayer 콘텐츠 선언 파일을 업데이트하거나 새로 추가할 때마다 intlayer build 명령을 다시 실행하여 next-intl JSON 메시지를 재생성하세요. next-intl은 업데이트된 콘텐츠를 자동으로 가져옵니다.
이 문서를 개선할 아이디어가 있으시면 GitHub에 풀 리퀘스트를 제출하여 자유롭게 기여해 주세요.
블로그에 대한 GitHub 링크