Next.js 애플리케이션에서 원활한 국제화(i18n)를 구현하여 글로벌 사용자에게 다가가는 방법을 알아보세요. 라우팅, 콘텐츠 번역 및 모범 사례를 다룹니다.
Next.js 국제화: 글로벌 사용자를 위한 다국어 앱 구축하기
오늘날과 같이 서로 연결된 세상에서, 글로벌 사용자를 만족시키는 애플리케이션을 구축하는 것은 더 이상 사치가 아닌 필수입니다. 강력한 React 프레임워크인 Next.js는 국제화(i18n) 구현을 위한 견고한 기능을 제공하여, 전 세계 사용자에게 현지화된 경험을 제공하는 다국어 애플리케이션을 만들 수 있도록 지원합니다. 이 종합 가이드는 국제화된 Next.js 애플리케이션을 구축하기 위한 필수 개념, 기술 및 모범 사례를 안내합니다.
국제화(Internationalization)와 현지화(Localization)의 이해
Next.js i18n의 세부 사항을 살펴보기 전에 주요 용어를 명확히 해보겠습니다.
- 국제화(Internationalization, i18n): 엔지니어링 변경 없이 다양한 언어와 지역에 쉽게 적응할 수 있도록 애플리케이션을 설계하고 개발하는 과정입니다. 이는 텍스트, 서식 및 기타 로케일별 요소를 추상화하는 작업을 포함합니다.
- 현지화(Localization, l10n): 특정 언어와 지역에 맞게 애플리케이션을 조정하는 과정입니다. 여기에는 텍스트 번역, 날짜 및 시간 형식 조정, 통화 기호 변경 등이 포함됩니다.
본질적으로 i18n은 애플리케이션의 현지화를 준비하는 과정입니다. 언어 종속적인 요소를 핵심 코드에서 분리함으로써, 다양한 시장을 위해 애플리케이션을 더 쉽게 현지화할 수 있습니다.
Next.js에서 국제화를 구현해야 하는 이유
Next.js 애플리케이션에 i18n을 구현하면 다음과 같은 수많은 이점이 있습니다.
- 도달 범위 확장: 사용자가 선호하는 언어로 콘텐츠를 제공하여 더 넓은 고객층에 도달할 수 있습니다.
- 사용자 경험 개선: 다양한 지역의 사용자에게 더 개인화되고 매력적인 경험을 제공합니다.
- SEO 향상: 특정 지리적 지역을 대상으로 하는 현지화된 콘텐츠를 제공하여 검색 엔진 최적화(SEO)를 개선합니다.
- 전환율 증가: 사용자의 모국어로 정보를 제공하여 신뢰와 이해를 높이고 전환율을 증가시킵니다.
- 글로벌 브랜드 입지 강화: 포용성에 대한 의지를 보여주고 다양한 고객층을 만족시킴으로써 더 강력한 글로벌 브랜드 입지를 구축합니다.
Next.js i18n 기능 및 설정
Next.js는 라우팅 및 콘텐츠 관리 기능을 통해 i18n을 기본적으로 지원합니다. 다음은 주요 기능에 대한 설명입니다.
1. next.config.js에서 i18n 설정하기
i18n의 핵심 설정은 next.config.js
파일에 있습니다. 다음은 예시입니다.
/** @type {import('next').NextConfig} */
const nextConfig = {
i18n: {
locales: ['en', 'es', 'fr'], // 지원되는 로케일(언어 코드) 배열
defaultLocale: 'en', // 사용할 기본 로케일
localeDetection: true, // 브라우저 설정에 따른 자동 로케일 감지 활성화/비활성화 (선택 사항)
// domains: [
// {
// domain: 'example.com',
// defaultLocale: 'en',
// },
// {
// domain: 'example.es',
// defaultLocale: 'es',
// },
// ],
},
}
module.exports = nextConfig;
설명:
locales
: 애플리케이션에서 지원하는 언어의 언어 코드(예: 영어의 경우'en'
, 스페인어의 경우'es'
, 프랑스어의 경우'fr'
)를 포함하는 배열입니다. 일관성을 위해 ISO 639-1 언어 코드를 따르십시오.defaultLocale
: 애플리케이션이 사용할 기본 언어입니다. URL에 다른 언어가 지정되지 않았거나 사용자 브라우저 설정에서 감지되지 않은 경우 표시되는 언어입니다. 주 타겟 고객을 대표하는 언어를 선택하십시오.localeDetection
: Next.js가 사용자 브라우저 설정에 따라 선호 언어를 자동으로 감지할지 여부를 제어하는 불리언 값입니다.true
로 설정하면 Next.js는 사용자를 사이트의 적절한 언어 버전으로 리디렉션하려고 시도합니다.domains
(선택 사항): 로케일을 특정 도메인과 연결할 수 있게 해주는 배열입니다. 다른 언어에 대해 별도의 도메인을 사용하는 경우(예: 영어는example.com
, 스페인어는example.es
) 유용합니다.
2. 로케일 접두사를 사용한 라우팅
Next.js는 자동으로 경로에 로케일 접두사를 붙입니다. 예를 들어, /about
페이지가 있고 로케일이 'es'(스페인어)인 경우 URL은 /es/about
이 됩니다. 이를 통해 페이지의 다른 언어 버전을 제공하고 검색 엔진이 각 로케일에 대한 콘텐츠를 인덱싱할 수 있게 합니다. 프레임워크가 리디렉션과 라우팅을 자동으로 처리합니다.
3. useRouter
훅 활용하기
next/router
의 useRouter
훅은 현재 로케일 및 기타 라우팅 정보에 대한 접근을 제공합니다.
import { useRouter } from 'next/router';
function MyComponent() {
const router = useRouter();
const { locale, locales, defaultLocale } = router;
return (
Current locale: {locale}
Available locales: {locales.join(', ')}
Default locale: {defaultLocale}
);
}
export default MyComponent;
router
객체는 다음과 같은 주요 속성을 제공합니다.
locale
: 현재 선택된 로케일 (예: 'en', 'es', 'fr').locales
:next.config.js
에 정의된 모든 지원 로케일의 배열.defaultLocale
:next.config.js
에 설정된 기본 로케일.asPath
: 브라우저에 표시되는 경로로, 로케일 접두사를 포함합니다 (예:/es/about
).pathname
: 로케일 접두사가 없는 경로 (예:/about
).
콘텐츠 번역 전략
Next.js 애플리케이션을 i18n용으로 설정한 후에는 콘텐츠 번역 전략을 구현해야 합니다. 다음은 몇 가지 인기 있는 접근 방식입니다.
1. 전용 번역 관리 시스템(TMS) 사용하기
많은 언어를 다루는 대규모 프로젝트의 경우 TMS 사용을 적극 권장합니다. 인기 있는 옵션은 다음과 같습니다.
- Phrase: Next.js를 포함한 다양한 플랫폼과의 통합을 제공하는 클라우드 기반 TMS입니다. 협업 기능과 자동화된 워크플로우를 제공합니다.
- Localize: 다양한 파일 형식을 지원하고 번역 관리 기능을 제공하는 또 다른 클라우드 기반 TMS입니다.
- Crowdin: 오픈 소스 커뮤니티에서 매우 인기 있는 강력한 TMS로, Next.js와 잘 통합되어 팀이 효율적으로 콘텐츠를 번역할 수 있도록 합니다.
장점:
- 중앙 집중식 번역 관리.
- 번역가를 위한 협업 기능.
- 번역 워크플로우 자동화.
- 개발 워크플로우와의 통합.
2. JSON 번역 파일 생성하기
소규모 프로젝트의 경우 JSON 파일을 사용하여 번역을 저장하는 것이 간단하고 효과적인 방법입니다.
예시 디렉토리 구조:
/src
├── locales
│ ├── en.json
│ └── es.json
├── components
│ └── MyComponent.js
└── pages
└── index.js
예시 en.json
:
{
"greeting": "Hello, world!",
"welcomeMessage": "Welcome to our website."
}
예시 es.json
:
{
"greeting": "¡Hola, mundo!",
"welcomeMessage": "Bienvenido a nuestro sitio web."
}
예시 MyComponent.js
:
import { useRouter } from 'next/router';
import en from '../locales/en.json';
import es from '../locales/es.json';
function MyComponent() {
const { locale } = useRouter();
const t = locale === 'es' ? es : en;
return (
{t.greeting}
{t.welcomeMessage}
);
}
export default MyComponent;
이 접근 방식은 유연성을 제공하며 소규모 프로젝트에 간단합니다. 일반적으로 업데이트하고 유지 관리하기 쉽습니다.
3. 번역 라이브러리 사용하기
몇몇 JavaScript 라이브러리는 React 컴포넌트 내에서 콘텐츠 번역을 간소화합니다.
next-i18next
: Next.js를 위해 특별히 설계된 인기 있는 라이브러리입니다. 프레임워크와 잘 통합되며 서버 사이드 렌더링(SSR) 및 클라이언트 사이드 번역과 같은 기능을 제공합니다.react-i18next
: React를 위한 범용 i18n 라이브러리입니다. Next.js 애플리케이션에서 사용할 수 있지만,next-i18next
에 비해 더 많은 설정이 필요할 수 있습니다.
next-i18next
를 사용한 예시 (설치: npm install next-i18next i18next react-i18next
):
i18n 설정 파일을 생성합니다 (예: 루트 디렉토리에 i18n.js
).
// i18n.js
import { createServerSideHelpers } from 'next-i18next'
import { i18n } from './next-i18next.config'
export function initI18next(req, res, namespaces = ['common']) {
const helpers = createServerSideHelpers(
req,
res,
i18n,
namespaces
)
return helpers
}
export { appWithTranslation } from 'next-i18next'
export { i18n }
next-i18next를 위한 Next.js 설정을 생성합니다.
// next-i18next.config.js
const { i18n } = require('./next-i18next.config');
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
i18n: {
defaultLocale: 'en',
locales: ['en', 'es', 'fr'],
},
// other configuration
}
module.exports = nextConfig
_app.js
에 설정과 번역 import를 추가합니다:
import { appWithTranslation } from 'next-i18next';
import '../styles/globals.css';
function MyApp({ Component, pageProps }) {
return ;
}
export default appWithTranslation(MyApp);
폴더를 만들고 번역을 위한 로케일로 채웁니다.
/public
└── locales
├── en
│ └── common.json
├── es
│ └── common.json
└── fr
└── common.json
예시 en/common.json:
{
"greeting": "Hello, world!",
"welcomeMessage": "Welcome to our website."
}
컴포넌트에서 번역 사용하기:
import { useTranslation } from 'next-i18next';
function MyComponent() {
const { t } = useTranslation('common');
return (
{t('greeting')}
{t('welcomeMessage')}
);
}
export default MyComponent;
이 예제는 useTranslation
훅을 사용하여 현재 로케일에 따라 번역을 가져옵니다.
동적 경로 및 정적 사이트 생성(SSG) 처리하기
동적 경로(예: 블로그 포스트, 제품 페이지) 및 정적 사이트 생성(SSG)을 다룰 때 국제화는 더 복잡해집니다.
1. 동적 경로 (예: /blog/[slug])
동적 경로의 경우, 빌드 시점에 getStaticPaths
를 사용하여 각 로케일에 대한 올바른 경로를 생성해야 합니다. 이 함수는 Next.js가 미리 렌더링해야 할 경로 배열을 반환합니다.
export async function getStaticPaths() {
const paths = [];
const locales = ['en', 'es', 'fr'];
const posts = await fetchPosts(); // 블로그 포스트 데이터 가져오기
posts.forEach(post => {
locales.forEach(locale => {
paths.push({
params: {
slug: post.slug,
},
locale,
});
});
});
return {
paths,
fallback: false, // 또는 로딩 상태를 표시하려면 'blocking'
};
}
export async function getStaticProps({ params, locale }) {
const post = await getPostBySlug(params.slug, locale);
return {
props: {
post,
},
};
}
설명:
getStaticPaths
: 이 함수는 블로그 포스트를 순회하며 각 포스트와 각 로케일에 대한 경로를 생성합니다.params
객체는 경로 매개변수(예: 블로그 포스트의 슬러그)를 포함합니다.locale
: 이 매개변수는 현재 로케일을 제공하여 특정 로케일에 대한 번역된 콘텐츠를 가져올 수 있게 합니다.fallback
: Next.js가getStaticPaths
에 정의되지 않은 경로를 처리하는 방법을 결정합니다.fallback: false
는 정의되지 않은 경로에 대해 404 페이지를 생성합니다.fallback: 'blocking'
은 요청 시 페이지를 사전 렌더링합니다.
2. getStaticProps
를 사용한 정적 사이트 생성(SSG)
getStaticProps
에서 locale
매개변수를 기반으로 번역된 콘텐츠를 가져올 수 있습니다.
export async function getStaticProps({ params, locale }) {
// locale과 params를 기반으로 콘텐츠 가져오기
const { post } = await getPostBySlug(params.slug, locale);
return {
props: {
post,
},
};
}
getPostBySlug
함수는 주어진 슬러그와 로케일에 대한 번역된 콘텐츠를 가져와야 하며, 이는 번역 파일, 데이터베이스 또는 CMS에서 검색할 수 있습니다.
3. getServerSideProps
를 사용한 서버 사이드 렌더링(SSR)
요청 시에 가져와야 하는 콘텐츠의 경우 getServerSideProps
를 사용합니다. 이는 콘텐츠가 자주 변경되거나 각 사용자에 맞게 개인화되는 경우에 유용합니다.
export async function getServerSideProps({ params, locale, req, res }) {
// locale과 params를 기반으로 데이터 가져오기 (예: 데이터베이스에서)
const data = await fetchData(params.slug, locale);
return {
props: {
data,
},
};
}
Next.js 국제화 모범 사례
다음 모범 사례를 따르면 견고하고 유지보수 가능하며 사용자 친화적인 다국어 애플리케이션을 구축하는 데 도움이 됩니다.
- 조기 계획: 프로젝트 시작부터 국제화를 고려하십시오. 나중에 추가하는 것보다 초기에 구현하는 것이 훨씬 쉽습니다.
- 콘텐츠와 코드 분리: 모든 번역 가능한 텍스트를 별도의 파일(예: JSON 파일 또는 TMS)에 저장하고 컴포넌트에 텍스트를 직접 하드코딩하지 마십시오.
- 번역 관리 시스템(TMS) 사용: 대규모 프로젝트의 경우 TMS는 번역 프로세스를 간소화하고 협업을 개선할 수 있습니다.
- 철저한 테스트: 지원되는 모든 언어로 애플리케이션을 테스트하여 정확한 번역, 올바른 서식 및 다양한 브라우저와 장치에서의 적절한 렌더링을 확인하십시오. 에뮬레이터뿐만 아니라 실제 장치에서 테스트하십시오.
- 오른쪽에서 왼쪽으로 쓰는(RTL) 언어 고려: 아랍어나 히브리어와 같은 언어를 지원하는 경우 디자인과 레이아웃이 오른쪽에서 왼쪽으로 쓰는 텍스트 방향을 수용하도록 하십시오. Next.js는 이를 자동으로 처리하지 않으므로 CSS나 다른 해결책이 필요합니다.
- 날짜 및 시간 형식 처리: 라이브러리나 내장 함수를 사용하여 사용자 로케일에 따라 날짜와 시간의 서식을 지정하십시오. Moment.js와 date-fns는 도움이 되는 두 가지 인기 있는 라이브러리입니다.
- 숫자 및 통화 서식 관리: 사용자 로케일에 따라 숫자와 통화 기호를 올바르게 서식 지정하십시오.
- SEO 최적화: 언어별 메타 태그(
hreflang
)를 사용하여 검색 엔진이 콘텐츠를 올바르게 인덱싱하도록 돕습니다. URL에 언어 코드를 포함시키십시오. - 사용자 경험 우선: 사용자가 언어를 명확하고 직관적으로 전환할 수 있는 방법을 제공하십시오. 브라우저 설정에 기반한 자동 언어 감지를 제공하는 것을 고려하십시오.
- 최신 상태 유지: 최신 기능과 보안 패치의 이점을 누리려면 Next.js 버전과 i18n 라이브러리를 최신 상태로 유지하십시오.
- 접근성(a11y) 고려: 번역된 콘텐츠가 장애를 가진 사용자에게 접근 가능하도록 하십시오. 이미지에 대한 대체 텍스트를 제공하고 적절한 ARIA 속성을 사용하십시오. 스크린 리더를 사용하여 테스트하십시오.
국제화된 웹사이트의 SEO 고려 사항
국제화된 웹사이트를 검색 엔진에 최적화하는 것은 전 세계로부터의 유기적 트래픽을 유도하는 데 필수적입니다. 다음은 몇 가지 주요 SEO 모범 사례입니다.
hreflang
태그: HTML의<head>
에hreflang
태그를 구현하여 검색 엔진에 콘텐츠의 언어 및 지역적 변형을 알립니다. 이는 SEO에 매우 중요합니다. 예:<link rel="alternate" hreflang="en" href="https://example.com/en/" />
및<link rel="alternate" hreflang="es" href="https://example.com/es/" />
- 언어별 URL: URL에 언어 코드를 사용하십시오(예:
/en/about
,/es/acerca-de
). 이는 사용자와 검색 엔진 모두에게 콘텐츠의 언어를 명확하게 나타냅니다. - 현지화된 콘텐츠: 콘텐츠를 정확하고 자연스럽게 번역하십시오. 기계 번역은 원어민이 검토해야 합니다.
- 현지화된 메타 설명 및 제목: 검색 결과에서 클릭률을 높이기 위해 각 언어에 대해 독특하고 설득력 있는 메타 설명과 제목을 작성하십시오.
- XML 사이트맵: 페이지의 모든 언어 변형을 포함하는 XML 사이트맵을 생성하고 제출하십시오.
- 내부 링크: 콘텐츠의 언어 버전 간에 적절한 내부 링크를 사용하십시오.
- 국가별 키워드 연구: 각 언어로 키워드 연구를 수행하여 각 지역에서 사용자가 검색하는 용어를 식별하십시오.
예제: 간단한 다국어 블로그 구축하기
Next.js를 사용하여 간단한 다국어 블로그 예제를 만들어 보겠습니다. 이는 위에서 논의한 개념을 어떻게 적용하는지에 대한 더 구체적인 예시를 제공할 것입니다.
1. 프로젝트 설정
새 Next.js 프로젝트를 생성합니다:
npx create-next-app my-multi-lang-blog
cd my-multi-lang-blog
2. i18n 설정 (next.config.js
)
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
i18n: {
locales: ['en', 'es', 'fr'],
defaultLocale: 'en',
},
}
module.exports = nextConfig
3. 번역 파일 생성
루트 디렉토리에 locales
폴더를 만들고 다음 JSON 파일을 추가합니다:
locales/en.json
:
{
"title": "Welcome to My Blog",
"postTitle": "My First Post",
"postContent": "This is the content of my first blog post."
}
locales/es.json
:
{
"title": "Bienvenido a mi Blog",
"postTitle": "Mi Primer Post",
"postContent": "Este es el contenido de mi primer publicación de blog."
}
locales/fr.json
:
{
"title": "Bienvenue sur Mon Blog",
"postTitle": "Mon Premier Article",
"postContent": "Ceci est le contenu de mon premier article de blog."
}
4. 블로그 포스트 컴포넌트 생성 (예: components/BlogPost.js
)
import { useRouter } from 'next/router';
import en from '../locales/en.json';
import es from '../locales/es.json';
import fr from '../locales/fr.json';
function BlogPost() {
const router = useRouter();
const { locale } = router;
let translations;
switch (locale) {
case 'es':
translations = es;
break;
case 'fr':
translations = fr;
break;
default:
translations = en;
}
return (
{translations.postTitle}
{translations.postContent}
);
}
export default BlogPost;
5. 인덱스 페이지 생성 (pages/index.js
)
import { useRouter } from 'next/router';
import BlogPost from '../components/BlogPost';
import en from '../locales/en.json';
import es from '../locales/es.json';
import fr from '../locales/fr.json';
function HomePage() {
const router = useRouter();
const { locale, locales } = router;
let translations;
switch (locale) {
case 'es':
translations = es;
break;
case 'fr':
translations = fr;
break;
default:
translations = en;
}
return (
);
}
export default HomePage;
이 단순화된 예제는 Next.js 국제화의 기본 원칙을 보여줍니다. 이 기본 프레임워크를 확장하여 동적 경로 및 번역 관리 시스템과의 통합과 같은 더 복잡한 기능을 포함할 수 있습니다. 위의 링크를 Link
컴포넌트로 개선하고 적절한 locale
속성을 추가하는 것을 고려해 보세요.
6. 애플리케이션 실행
다음 명령어로 애플리케이션을 실행합니다:
npm run dev
이제 http://localhost:3000
(영어), http://localhost:3000/es
(스페인어), http://localhost:3000/fr
(프랑스어)에서 블로그에 접속할 수 있습니다. 선택된 로케일에 따라 제목과 블로그 포스트 내용이 번역되어 표시되는 것을 볼 수 있습니다.
결론
Next.js는 웹 애플리케이션에 국제화를 구현하기 위한 포괄적인 기능 세트를 제공합니다. 이 가이드에서 설명한 원칙과 기술을 따르면 전 세계 사용자에게 현지화된 경험을 제공하는 다국어 애플리케이션을 만들 수 있습니다. i18n 전략을 조기에 계획하고, 필요에 맞는 번역 방법을 선택하며, 사용자 경험을 우선시하는 것을 잊지 마십시오. 신중한 계획과 실행을 통해 글로벌 고객과 공감대를 형성하고 새로운 성장 기회를 열 수 있는 애플리케이션을 구축할 수 있습니다. 지속적인 학습, 최신 릴리스 및 모범 사례를 따르는 것은 도구와 기술을 효과적으로 활용하고 있음을 보장합니다.
기술이 발전함에 따라 더 진보된 i18n 기능이 등장할 것으로 예상됩니다. 다양한 문화와 언어 그룹의 사용자에게 다가갈 수 있는 능력은 전 세계 애플리케이션 개발자에게 계속해서 핵심 우선순위가 될 것입니다. 따라서 i18n의 기본을 마스터하는 것은 오늘날의 글로벌 개발 환경에서 당신의 가치를 높이는 귀중한 기술입니다.