작가:
    생성:2026-08-23마지막 업데이트:2026-08-24

    Intlayer를 사용하여 Elysia 백엔드 웹사이트 국제화 (i18n)

    elysia-intlayer는 Elysia 애플리케이션을 위한 강력한 국제화 (i18n) 플러그인으로, 클라이언트의 선호도에 따라 지역화된 응답을 제공함으로써 백엔드 서비스를 전 세계적으로 접근 가능하게 만들도록 설계되었습니다.

    GitHub에서 패키지 구현 보기: https://github.com/aymericzip/intlayer/tree/main/packages/elysia-intlayer

    실제 사용 사례

    • 사용자의 언어로 백엔드 오류 표시: 오류가 발생했을 때 메시지를 사용자의 모국어로 표시하면 이해도를 높이고 좌절감을 줄일 수 있습니다. 이는 토스트나 모달과 같은 프론트엔드 컴포넌트에 표시될 수 있는 동적 오류 메시지에 특히 유용합니다.
    • 다국어 콘텐츠 검색: 데이터베이스에서 콘텐츠를 가져오는 애플리케이션의 경우, 국제화를 통해 여러 언어로 이 콘텐츠를 제공할 수 있습니다. 이는 제품 설명, 기사 및 기타 콘텐츠를 사용자가 선호하는 언어로 표시해야 하는 전자 상거래 사이트나 콘텐츠 관리 시스템과 같은 플랫폼에 필수적입니다.
    • 다국어 이메일 전송: 거래 이메일, 마케팅 캠페인 또는 알림이든 수신자의 언어로 이메일을 보내면 참여도와 효과를 크게 높일 수 있습니다.
    • 다국어 푸시 알림: 모바일 애플리케이션의 경우, 사용자가 선호하는 언어로 푸시 알림을 보내면 상호 작용과 유지율을 향상시킬 수 있습니다. 이러한 개인화된 접근은 알림이 더 관련성 있고 실행 가능하게 느껴지도록 할 수 있습니다.
    • 기타 커뮤니케이션: SMS 메시지, 시스템 경고 또는 사용자 인터페이스 업데이트와 같은 백엔드로부터의 모든 형태의 커뮤니케이션은 사용자의 언어로 이루어지면 명확성을 보장하고 전체 사용자 경험을 향상시킵니다.

    백엔드를 국제화함으로써 애플리케이션은 문화적 차이를 존중할 뿐만 아니라 글로벌 시장의 요구에 더 잘 맞춰지므로, 전 세계적으로 서비스를 확장하는 데 있어 핵심 단계입니다.

    시작하기

    ide.intlayer.org

    GitHub에서 Application Template을 참조하세요.

    설치

    elysia-intlayer를 사용하기 시작하려면 npm을 사용하여 패키지를 설치하세요:

    bash
    npx intlayer init --interactive
    
    --interactive 플래그는 선택 사항입니다. AI 에이전트인 경우 intlayer-cli init을 사용하세요.
    이 명령은 환경을 감지하고 필요한 패키지를 설치합니다. 예를 들어:
    bash
    npm install intlayer elysia-intlayer
    
    Elysia는 Bun 런타임을 대상으로 합니다. elysia-intlayer가 (Node 기반 Intlayer 플러그인이 사용하는 cls-hooked 라이브러리 대신) AsyncLocalStorage에 의존하는 이유는 바로 Bun이 async_hooks.createHook을 구현하지 않기 때문입니다.

    설정

    프로젝트 루트에 intlayer.config.ts를 생성하여 국제화 설정을 구성합니다:

    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    
    const config: IntlayerConfig = {
      internationalization: {
        locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
        /**
         * 요청한 로케일을 찾을 수 없을 때 fallback으로 사용되는 기본 로케일입니다.
         */
        defaultLocale: Locales.ENGLISH,
      },
    };
    
    export default config;
    

    콘텐츠 선언하기

    번역을 저장하기 위한 콘텐츠 선언을 생성하고 관리합니다:

    src/index.content.ts
    import { t, type Dictionary } from "intlayer";
    
    const indexContent = {
      key: "index",
      content: {
        exampleOfContent: t({
          ko: "영어로 반환된 콘텐츠의 예",
          en: "Example of returned content in English",
          fr: "Exemple de contenu renvoyé en français",
          es: "Ejemplo de contenido devuelto en español",
        }),
      },
    } satisfies Dictionary;
    
    export default indexContent;
    
    콘텐츠 선언은 contentDir 디렉토리(기본값: ./src)에 포함되고 콘텐츠 선언 파일 확장자(기본값: .content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml})와 일치하는 한 애플리케이션의 어느 곳에서나 정의할 수 있습니다.
    더 자세한 내용은 콘텐츠 선언 문서를 참조하세요.

    Elysia Application Setup

    elysia-intlayer를 사용하도록 Elysia 애플리케이션을 설정합니다:

    src/index.ts
    import { Elysia } from "elysia";
    import { intlayer } from "elysia-intlayer";
    
    const app = new Elysia()
      // 국제화 플러그인 로드
      .use(intlayer())
      // Routes
      .get("/", ({ intlayer }) => ({
        // 이 요청에 사용된 로케일, `Accept-Language` 협상 또는 스토리지에서 읽음
        locale: intlayer!.locale,
        greeting: intlayer!.t({
          ko: "안녕하세요",
          en: "Hello",
          fr: "Bonjour",
          es: "Hola",
        }),
        content: intlayer!.getIntlayer("index").exampleOfContent,
      }))
      .listen(3000);
    
    console.log(
      `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`
    );
    
    플러그인은 전역 derive를 통해 컨텍스트를 등록하며, Elysia는 이를 Partial<{ intlayer: IntlayerContext }>로 타이핑합니다. .use(intlayer()) 이후에 등록된 라우트에서는 런타임에 값이 항상 존재하므로, strict 모드의 TypeScript를 만족시키려면 non-null 어서션(intlayer!.locale) 또는 옵셔널 체이닝을 사용하세요.

    라우트 컨텍스트는 다음을 노출합니다:

    속성 설명
    locale 이 요청에 사용할 로케일이며, locale_storagelocale_detected보다 우선합니다.
    locale_storage 쿠키 또는 헤더를 통해 클라이언트가 명시적으로 요청한 로케일.
    locale_detected 요청 헤더에서 협상된 로케일.
    defaultLocale intlayer.config.ts에 폴백으로 설정된 로케일.
    t 번역 함수.
    getIntlayer 키로 사전을 가져오는 함수.
    getDictionary 사전 객체를 처리하는 함수.

    동일한 헬퍼는 독립(standalone) export로도 제공됩니다. AsyncLocalStorage를 통해 현재 요청을 해석하므로 컨텍스트를 구조 분해하지 않고 호출할 수 있습니다:

    src/index.ts
    import { Elysia } from "elysia";
    import { intlayer, t, getDictionary, getIntlayer } from "elysia-intlayer";
    import dictionaryExample from "./index.content";
    
    const app = new Elysia()
      .use(intlayer())
      .get("/t_example", () =>
        t({
          ko: "영어로 반환된 콘텐츠의 예",
          en: "Example of returned content in English",
          fr: "Exemple de contenu renvoyé en français",
          es: "Ejemplo de contenido devuelto en español",
        })
      )
      .get("/getIntlayer_example", () => getIntlayer("index").exampleOfContent)
      .get(
        "/getDictionary_example",
        () => getDictionary(dictionaryExample).exampleOfContent
      )
      .listen(3000);
    
    요청 컨텍스트는 응답이 매핑되면 해제되므로, 독립 헬퍼가 이미 종료된 요청에 대해 해석되는 일은 없습니다. 플러그인이 처리하는 요청 외부에서 호출되면 설정된 기본 로케일로 폴백합니다.

    애플리케이션 실행하기

    package.json에 Intlayer 스크립트를 추가하세요. intlayer build는 콘텐츠 선언을 .intlayer 디렉터리로 컴파일하고 TypeScript 타입을 생성합니다:

    package.json
    {
      "scripts": {
        "dev": "intlayer build && bun run --watch src/index.ts",
        "build": "intlayer build",
        "start": "bun run src/index.ts",
        "i18n:fill": "intlayer fill",
        "i18n:test": "intlayer test"
      }
    }
    

    그런 다음 서버를 시작하세요:

    bash
    bun run dev
    

    Accept-Language로 로케일 협상을 테스트해 보세요:

    bash
    curl -H "Accept-Language: fr" http://localhost:3000/
    # {"locale":"fr","greeting":"Bonjour","content":"Exemple de contenu renvoyé en français"}
    
    curl -H "Accept-Language: es" http://localhost:3000/
    # {"locale":"es","greeting":"Hola","content":"Ejemplo de contenido devuelto en español"}
    
    bun run src/index.ts 전에 intlayer build가 반드시 필요한 것은 아닙니다. 플러그인은 Elysia 앱이 부팅될 때도 사전을 준비합니다. 미리 실행해 두면 에디터용 생성 타입이 동기화된 상태로 유지되고 첫 요청에서의 빌드 비용을 피할 수 있습니다.

    호환성

    elysia-intlayer는 다음과 완전히 호환됩니다:

    또한 브라우저 및 API 요청을 포함한 다양한 환경에서 모든 국제화 솔루션과 원활하게 작동합니다.

    기본적으로 플러그인은 다음 순서로 로케일을 결정합니다:

    1. INTLAYER_LOCALE 쿠키.
    2. x-intlayer-locale 헤더.
    3. Accept-Language 헤더 협상.

    로케일 감지에 사용되는 쿠키와 헤더를 커스터마이즈할 수 있습니다:

    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    
    const config: IntlayerConfig = {
      // ... 기타 구성 옵션
      routing: {
        storage: [
          { type: "header", name: "my-locale-header" },
          { type: "cookie", name: "my-locale-cookie" },
        ],
      },
    };
    
    export default config;
    
    구성 및 고급 주제에 대한 자세한 정보는 문서를 방문하세요.

    TypeScript 구성

    elysia-intlayer는 국제화 프로세스를 강화하기 위해 TypeScript의 강력한 기능을 활용합니다. TypeScript의 정적 타이핑은 모든 번역 키가 고려되도록 보장하여 누락된 번역의 위험을 줄이고 유지보수성을 향상시킵니다.

    자동 생성된 타입(기본값: ./types/intlayer.d.ts)이 tsconfig.json 파일에 포함되어 있는지 확인하세요.

    tsconfig.json
    {
      // ... 기존 TypeScript 구성
      "include": [
        // ... 기존 TypeScript 구성
        ".intlayer/**/*.ts", // 자동 생성된 타입 포함
      ],
    }
    

    VS Code Extension

    Intlayer 개발 경험을 개선하기 위해 공식 Intlayer VS Code Extension을 설치할 수 있습니다.

    VS Code Marketplace에서 설치

    이 extension은 다음을 제공합니다:

    • Autocompletion 번역 키용
    • 실시간 오류 감지 누락된 번역용
    • 인라인 미리보기 번역된 콘텐츠용
    • 빠른 작업 번역을 쉽게 생성하고 업데이트할 수 있음

    extension 사용 방법에 대한 자세한 내용은 Intlayer VS Code Extension 문서를 참조하세요.

    Git 구성

    Intlayer에서 생성된 파일을 무시하는 것이 좋습니다. 이를 통해 Git 저장소에 커밋하지 않을 수 있습니다.

    이를 위해 .gitignore 파일에 다음 지시사항을 추가할 수 있습니다:

    .gitignore
    # Intlayer에서 생성된 파일 무시
    .intlayer