개발 노트

Next.js 13 이상 국제화(i18n) 적용 본문

React

Next.js 13 이상 국제화(i18n) 적용

한츄 2024. 1. 19. 18:05

i18n(Internationalization)이란?

https://ko.wikipedia.org/wiki/%EA%B5%AD%EC%A0%9C%ED%99%94%EC%99%80_%EC%A7%80%EC%97%AD%ED%99%94

 

국제화와 지역화 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 대부분 중국어(번체)로 현지화된 TDE 소프트웨어 프로그램의 스크린샷 국제화와 지역화는 출판물이나 하드웨어 또는 소프트웨어 등의 제품을 언어 및 문화권

ko.wikipedia.org

 

 

 

시작하기

1. app하위에 i18n/settings.js 파일을 만들어서 다음과 같이 설정해줍니다.

// app/i18n/settings.js

export const fallbackLang = 'ko-KR'
export const languages = [fallbackLang,'ko', 'en']
export let cookieName = 'languages'

 

app 하위 항목에 렌더링하기위해서 설정해줍니다.

  • /news
  • /ko/news
  • /en/news

2. 폴더 구조를 app 하위항목을 다음과 같이 [lang]으로 감싸서 동적 라우팅이 될 수 있도록 변경해줍니다.

 

3. layout.js를 다음과 같이 수정해줍니다.

// app/[lang]/layout.js
import "./globals.css";
import { languages } from '../i18n/settings'

// meta tag 항목 생략

export async function generateStaticParams(){
  return languages.map((lang) => ({ lang }))
}

export default function RootLayout({ children, params : {lang} }) {
  return (
    <html lang={lang} >
      <body>
		/* 생략 */
      </body>
    </html>
  );
}

 

4. middleware.js 를 root경로에 만들어 줍니다.

import { NextResponse } from 'next/server'
import acceptLanguage from 'accept-language'
import { fallbackLang, languages, cookieName} from './app/i18n/settings'

// 적용언어 가져오기
acceptLanguage.languages(languages)

export function middleware(req) {
  let lng
  //쿠키에 저장된 langueges항목이 없을 경우 validation
  if (!languages) {
    throw new Error('쿠키에 등록된 언어설정을 찾지 못했어요.');
  }else{
  // langueges항목의 value값 가지고 오기
    if (req.cookies.has(languages)) lng = acceptLanguage.get(req.cookies.get(languages).value)
    if (!lng) lng = acceptLanguage.get(req.headers.get('Accept-Language'))
    if (!lng) lng = fallbackLang
  
  // redirect로 localhost:3000일때 언어에 맞게 세팅해주기
    if (
      !languages.some(loc => req.nextUrl.pathname.startsWith(`/${loc}`)) &&
      !req.nextUrl.pathname.startsWith('/_next')
    ) {
      return NextResponse.redirect(new URL(`/${lng}${req.nextUrl.pathname}`, req.url))
    }
  
    if (req.headers.has('referer')) {
      const refererUrl = new URL(req.headers.get('referer'))
      const lngInReferer = languages.find((l) => refererUrl.pathname.startsWith(`/${l}`))
      const response = NextResponse.next()
      if (lngInReferer) response.cookies.set(cookieName, lngInReferer)
      return response
    }
  
    return NextResponse.next()
  }
}


export const config = {
  // matcher: '/:lng*'
  matcher: ['/((?!api|_next/static|_next/image|assets|favicon.ico|sw.js).*)']
}

 

 

참고:

https://nextjs.org/docs/pages/building-your-application/routing/internationalization

 

Routing: Internationalization | Next.js

Next.js has built-in support for internationalized routing and language detection. Learn more here.

nextjs.org

 

https://locize.com/blog/next-app-dir-i18n/#step-2

 

i18n with Next.js 13/14 and app directory / App Router (an i18next guide)

Looking for a way to internationalize your Next.js 13/14 project with the new app directory / App Router paradigm? Then this guide is for you!

locize.com