develop

Next.js App Router 다국어 지원하기 i18n next-intl

방뎁 2024. 2. 3. 15:20
반응형

next js에서 다국어 (Internationalization)를 지원하려고 여러 라이브러리 적용하고 실패하고 실패해서 

적용가능한 법을 남겨야 할 것 같아 이렇게 글을 쓴다. 

 

우선 next-i18next 는 앱라우터를 지원하지 않는다고 한다. 

지금은 잘 모르겠다.

그래서 next-intl 라이브러리를 사용하여 적용하려고 했으나, 실패

https://github.com/amannn/next-intl/issues/250

 

Turbopack support · Issue #250 · amannn/next-intl

Description Running app with turbopack causes an error: Error during SSR Rendering I use next@13.3.0 and next-intl@2.14.0-beta.2 The setup is done using this guide https://next-intl-docs.vercel.app...

github.com

 

뭐, 그냥 포기해버렸읍니다. 

그러고 아래 사이트를 따라 해보기로 했다. 

https://i18nexus.com/tutorials/nextjs/react-i18next

 

Next.js 13/14 App Router with i18next (Tutorial)

A walkthrough for setting up the Next.js 13/14 App Router with internationalized routing and react-i18next.

i18nexus.com

 

근데 i18nexus 너무 싫었다.  다른 방법 찾아 적용하면 되는데, 넘 귀찮

제발 계정 만드는 거 멈춰,,,,

 

그래서 다시 돌아 next-intl 라이브러리를 썼습니다...ㅎㅎㅎ

https://next-intl-docs.vercel.app/docs/getting-started/app-router

 

Next.js App Router Internationalization (i18n) – Internationalization (i18n) for Next.js

 

next-intl-docs.vercel.app

 

next js i18n 적용하기

 

1. 폴더 구조

├── messages
│   ├── en.json
│   ├── ko.json
│   └── ...
├── next.config.mjs
└── src
    ├── i18n.ts
    ├── middleware.ts
    └── app
        └── [locale]
            ├── layout.tsx
            ├── page.tsx
            └── ...

 

2. messages/

// en.json
{
    "Index": {
        "title": "Hello world!"
    }
}
// ko.json
{
    "Index": {
        "title": "헬로 월드!"
    }
}

 

3. next.config.mjs

import createNextIntlPlugin from 'next-intl/plugin';

const withNextIntl = createNextIntlPlugin();

/** @type {import('next').NextConfig} */
const nextConfig = {};

export default withNextIntl(nextConfig);
반응형

4. i18n.ts

import { notFound } from 'next/navigation';
import { getRequestConfig } from 'next-intl/server';

// Can be imported from a shared config
const locales = ['en', 'ko'];

export default getRequestConfig(async ({ locale }) => {
    // Validate that the incoming `locale` parameter is valid
    if (!locales.includes(locale as any)) notFound();

	// 위치 확인
    return {
        messages: (await import(`../messages/${locale}.json`)).default 
    };
});

 

5. middleware.ts

import createMiddleware from 'next-intl/middleware';

export default createMiddleware({
    locales: ['en', 'ko'], // 지원 언어
    defaultLocale: 'en' // 기본 언어
});

export const config = {
    // Match only internationalized pathnames
    matcher: ['/', '/(ko|en)/:path*']
};

 

6. app/[locale]/layout.tsx

* 프로젝트를 처음 생성하면 src > app > layout 이렇게 기본으로 생성되는데, 다국어를 사용하기 위해서는 [id]처럼 인자를 받아 사용하기 때문에 모든 파일을 [locale] 폴더 내부로 넣어 사용해야 합니다. 

export default function LocaleLayout({
  children,
  params: { locale }
}: {
  children: React.ReactNode;
  params: { locale: string };
}) {
  return (
    <html lang={locale}>
     ...
    </html>
  );
}

 

사용하기

6. app/[locale]/page.tsx

import { useTranslations } from 'next-intl';


export default function Home() {
  const t = useTranslations('Index'); // json key 값

  return (
    <div>
      {t('title')}
    </div>
  );
}

 

 

이런식으로 적용하면 되는데, 왜 그렇게 돌아돌아왔는가..

 

반응형