--- createdAt: 2026-06-14 updatedAt: 2026-06-14 title: 새로운 Intlayer v9 - 무엇이 달라졌나요? description: Intlayer v9의 새로운 기능을 알아보세요. 인기 있는 i18n 라이브러리를 위한 드롭인 호환성 패키지와 컬렉션(Collections), 베리언트(Variants), 동적 레코드(Dynamic Records) 지원을 소개합니다. keywords: - Intlayer - 호환성 - 마이그레이션 - 컬렉션 - 베리언트 - 동적 레코드 - i18next - next-intl - vue-i18n slugs: - doc - releases - v9 author: aymericzip --- # 새로운 Intlayer v9 - 무엇이 달라졌나요? Intlayer v9에 오신 것을 환영합니다! 이번 메이저 릴리스는 주요 i18n 라이브러리(`react-i18next`, `next-intl`, `vue-i18n` 등)를 위한 **호환 어댑터 패키지(Compat Adapter Packages)**를 통해 Intlayer로의 마이그레이션 경로를 획기적으로 단순화하고, **컬렉션(Collections)**, **베리언트(Variants)**, **동적 레코드(Dynamic Records)**와 같은 풍부한 콘텐츠 구조 지원을 추가하는 큰 이정표를 세웠습니다. ## 목차 --- ## 호환 어댑터 패키지 (Compat Adapter Packages) 인기 있는 i18n 라이브러리에서 Intlayer로 마이그레이션하는 것이 그 어느 때보다 쉬워졌습니다. 표준 i18n 라이브러리와 **완전히 동일한 공개 API**를 노출하면서 런타임 시 모든 번역 작업을 Intlayer에 위임하는 5개의 호환 패키지를 출시했습니다. ### 엄격한 타입 지정을 통한 동일한 공개 API 노출 임포트(import) 경로를 바꾸는 것만으로, 최소한의 코드 변경을 통해 실제 딕셔너리에 대한 컴파일 타임 타입 안전성을 포함한 Intlayer의 모든 이점을 누릴 수 있습니다: - `@intlayer/i18next` - `@intlayer/react-i18next` - `@intlayer/next-intl` - `@intlayer/next-i18next` - `@intlayer/vue-i18n` 예를 들어, 다음과 같이 간단히 변경하면 됩니다: ```ts import { useTranslation } from "react-i18next"; ``` 을 다음과 같이 변경합니다: ```ts import { useTranslation } from "@intlayer/react-i18next"; ``` 이제 키는 Intlayer 딕셔너리에 대해 **엄격하게 타입 지정(strictly typed)**되어 IDE에서 완전한 점 표기법(dot-path) 자동 완성을 제공합니다! ### 번들러 에일리어스 플러그인 (Vite, Next.js, Turbopack) 모든 임포트 문을 수동으로 다시 작성하지 않고도 마이그레이션할 수 있도록, 각 호환 어댑터 패키지에는 `/plugin` 서브패스 아래에 **커스텀 번들러 플러그인**(Vite 또는 Next.js)이 포함되어 있습니다. 이 플러그인들은 빌드 타임에 기존 임포트(예: `react-i18next` 또는 `next-intl`)를 그에 해당하는 `@intlayer/*` 패키지로 자동 변환합니다. #### Next.js (Webpack / Turbopack) 예시 `withIntlayer` 대신, Next.js 설정을 호환 플러그인으로 감싸세요: ```ts fileName="next.config.ts" import { createNextI18nPlugin } from "@intlayer/next-i18next/plugin"; import type { NextConfig } from "next"; const withIntlayer = createNextI18nPlugin(); const nextConfig: NextConfig = {}; export default withIntlayer(nextConfig); ``` #### Vite (React, Vue, Solid, Svelte) 예시 ```ts fileName="vite.config.ts" import vueI18nVitePlugin from "@intlayer/vue-i18n/plugin"; export default defineConfig({ plugins: [vueI18nVitePlugin()], }); ``` --- ## 통합 런타임 리졸버 (Mutualized Runtime Resolver) 모든 호환 어댑터는 이제 고도로 최적화된 단일 런타임 파서인 `@intlayer/core/messageFormat`을 통해 번역 해석을 라우팅합니다. - **메시지 보간 (Interpolate Message)**: 표준 `{{var}}` (공백 및 점 표기법 경로), ICU 포맷 인수 (`{v, number, percent}` 등), 그리고 기본 `{var}` 템플릿을 해석합니다. - **메시지 노드 리졸버 (Message Node Resolver)**: 중첩된 노드들을 해석합니다: `insert()`, `plural()` (CLDR 복수형 규칙), `enu()` (열거형), `gender()`, HTML 태그, 배열, 그리고 호출 가능한 함수 노드. - **토큰화된 태그 파서 (Tokenized Tag Parser)**: 인라인 XML/HTML 태그 및 번호가 매겨진 태그(예: `<1>children`)를 지원하여 서식 있는 텍스트(rich-text) 렌더링을 기본적으로 지원합니다. --- ## 기능 사양: 컬렉션, 베리언트 및 동적 레코드 Intlayer v9은 정적인 키-값 객체를 넘어, 딕셔너리가 처음부터 끝까지 완전히 타입 지정된 동적 레이아웃 구조를 선언할 수 있도록 확장되었습니다. ### 1. 컬렉션 (Collections) CMS에서 관리하는 순서가 있는 아이템 목록(예: FAQ, 제품 또는 블로그 목록)을 정의합니다: ```ts fileName="faq.content.ts" import { t, type Dictionary } from "intlayer"; export default { key: "faq", content: [ { question: t({ ko: "Intlayer가 무엇인가요?", en: "What is Intlayer?", fr: "Qu'est-ce qu'Intlayer ?", }), answer: t({ ko: "i18n 툴킷입니다.", en: "An i18n toolkit.", fr: "Une boîte à outils i18n.", }), }, ], } satisfies Dictionary; ``` #### 사용법: ```ts // 모든 아이템 가져오기 const allFaqs = useIntlayer("faq"); // -> { question: string, answer: string }[] // 인덱스로 단일 아이템 가져오기 const faq = useIntlayer("faq", { item: 1 }); // -> { question: string, answer: string } ``` ### 2. 베리언트 (Variants) A/B 테스트, 시즌별 헤더, 피처 플래그(feature flags) 또는 커스텀 랜딩 페이지를 제공합니다: ```ts fileName="hero.content.ts" import { t, type Dictionary } from "intlayer"; export default { key: "hero-banner", variant: "default", content: { control: t({ ko: "환영합니다", en: "Welcome", fr: "Bienvenue" }), black_friday: t({ ko: "지금 쇼핑하기", en: "Shop now", fr: "Acheter maintenant", }), }, } satisfies Dictionary; ``` #### 사용법: ```ts const banner = useIntlayer("hero-banner", { variant: "black_friday" }); ``` ### 3. 동적 레코드 (Dynamic Records) 쿼리 ID를 통해 런타임에 동적으로 로드되는 항목을 가진 딕셔너리를 정의합니다: ```ts fileName="product.content.ts" import { t, type Dictionary } from "intlayer"; export default { key: "product-copy", meta: { id: "prod_123", category: "books", }, content: { title: t({ ko: "클린 코드", en: "Clean Code", fr: "Code Propre" }), }, } satisfies Dictionary; ``` #### 사용법: ```ts // 요청된 아이템만 동적으로 가져옵니다 (Suspense 필요) const product = useIntlayer("product-copy", { id: "prod_123", category: "books", }); ``` --- ## 동적 로딩 및 번들 크기 최적화 번들 크기를 극도로 작게 유지하기 위해, Intlayer v9은 동적 지연 로딩(dynamic lazy loading)을 지원합니다. 설정에서 `importMode`를 `'dynamic'` 또는 `'fetch'`로 설정하세요: ```ts fileName="intlayer.config.ts" export default { dictionary: { importMode: "dynamic", // "static" | "dynamic" | "fetch" }, }; ``` 빌드 타임에 `@intlayer/swc` 및 `@intlayer/babel`이 파일을 스캔하여 `useIntlayer` / `getIntlayer` 호출을 트리 쉐이킹(tree-shaking)이 가능한 래퍼(`useDictionary` / `useDictionaryDynamic`)로 대체합니다. 선택한 컬렉션 아이템, 베리언트 또는 로케일에 필요한 콘텐츠만 로드되므로, 프로덕션 번들에 사용되지 않는 번역이 포함되는 것을 방지합니다. --- ## v8에서의 마이그레이션 노트 v8에서 업그레이드하는 경우, v9에는 하위 호환성을 깨뜨리는 변경 사항(breaking changes)이 포함되어 있지 않습니다. 하지만 다음과 같은 주요 변경 사항이 있습니다: - **로케일 및 다이얼렉트 (Locales & Dialects)**: 외부 i18n 의존성을 사용하는 경우, 설정 또는 번들러 구성에 해당 호환 어댑터 플러그인을 추가하여 임포트를 자동으로 변환하세요. - **커스텀 셀렉터 (Custom Selectors)**: `useIntlayer`를 호출할 때 두 번째 매개변수는 이제 `{ locale, item, variant, id }`를 포함하는 옵션 객체 전용으로 예약됩니다. 이전에 로케일 문자열을 직접 전달했다면 여전히 그렇게 사용할 수 있지만, 고급 선택을 위해서는 옵션 객체를 사용하는 것을 권장합니다. --- ## 유용한 링크 - [호환 어댑터 패키지 가이드](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/compat/index.md) - [동적 딕셔너리 - 컬렉션, 베리언트 및 동적 레코드](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dynamic_dictionaries/index.md) - [설정 레퍼런스](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/configuration.md)