콘텐츠로 바로 가기
Angular i18n

Angular i18n 솔루션

Angular 애플리케이션을 위한 Standalone 컴포넌트, Signals, SSR 지원.

Setup

Angular에서 런타임 번역, 세 단계로

Angular의 내장 i18n은 로케일마다 번들을 컴파일합니다. 다시 빌드하지 않고 바뀌는 번역이 필요하다면 ngx-translate가 런타임에 Better I18N에서 읽어 옵니다.

loader 의존성 설치하기

ngx-translate는 pipe, service, loader 계약을 제공하고, core는 메시지를 가져와 캐시합니다.

terminalbash
npm install @ngx-translate/core @better-i18n/core

# @better-i18n/core ships zero dependencies —
# it is the same client our React SDKs are built on.

CDN을 사용하는 TranslateLoader 작성하기

TranslateLoader는 언어마다 Observable을 요구하므로, getMessages를 rxjs from()으로 감싸는 것이 어댑터의 전부입니다.

src/app/better-i18n.loader.tsts
import { Injectable } from '@angular/core'
import { TranslateLoader } from '@ngx-translate/core'
import { createI18nCore } from '@better-i18n/core'
import { from, Observable } from 'rxjs'

// Module scope: the 60s in-memory cache lives on the instance, so one
// client per app — not one per component.
const betterI18n = createI18nCore({
  projectId: 'your-org/your-project', // Settings → General → Project ID
  defaultLocale: 'en',
})

@Injectable({ providedIn: 'root' })
export class BetterI18nLoader implements TranslateLoader {
  // TranslateLoader's contract: one Observable of messages per language.
  getTranslation(lang: string): Observable<Record<string, unknown>> {
    return from(betterI18n.getMessages(lang))
  }
}

export { betterI18n }

등록하고 런타임에 전환하기

bootstrapApplication에 provider 하나만 등록하면, 이후 use()로 페이지를 새로 고치지 않고 로케일별 빌드 없이 언어를 바꿀 수 있습니다.

src/main.tsts
import { bootstrapApplication } from '@angular/platform-browser'
import { importProvidersFrom } from '@angular/core'
import { TranslateModule, TranslateLoader } from '@ngx-translate/core'
import { AppComponent } from './app/app.component'
import { BetterI18nLoader } from './app/better-i18n.loader'

bootstrapApplication(AppComponent, {
  providers: [
    importProvidersFrom(
      TranslateModule.forRoot({
        defaultLanguage: 'en',
        loader: { provide: TranslateLoader, useClass: BetterI18nLoader },
      })
    ),
  ],
})

How it works

Angular의 문자열은 어디에서 오는가

로케일별 번들이 필요 없습니다. loader가 런타임에 언어를 확인하고 엣지가 응답합니다.

Read path — every locale load

Your Angular app

The translate pipe reads what TranslateService already loaded.

0 network calls per render

@better-i18n/core

getMessages(lang) inside the TranslateLoader — cached per language.

60s TTL · 0 deps

CDN edge

Cloudflare worker answers from the nearest edge cache.

max-age=60 · always 200

R2 object store

The published translation files the sync worker wrote.

source of truth

Fallback chain — tried in order when a hop fails

1In-memory TTL cache
2CDN fetch, with timeout and one retry
3Persistent storage, if configured
4staticData bundled with the app
5Throw — after everything above missed

Write path — dashboard to app

AI or translator

Proposal reviewed in the dashboard, glossary enforced.

MCP · dashboard · CLI

Publish

Sync worker writes the locale files to R2.

better-i18n publish

CDN purge

Fire-and-forget purge of the affected keys and the manifest.

non-critical by design

Live in the app

The next getMessages() past the TTL returns the new copy.

~60s worst case

0dependencies in core
60scache TTL, client and edge
200CDN status, even on failure
5fallback layers before an error
Switching locale

빠른 시작

파이프와 서비스로 Angular 앱에 i18n을 추가하세요.

src/app/locale-switcher.component.tsts
import { Component, inject } from '@angular/core'
import { TranslateModule, TranslateService } from '@ngx-translate/core'
import { betterI18n } from './better-i18n.loader'

@Component({
  selector: 'app-locale-switcher',
  standalone: true,
  imports: [TranslateModule],
  template: `
    <select (change)="switchTo($any($event.target).value)">
      <option *ngFor="let l of languages" [value]="l.code">{{ l.name }}</option>
    </select>
  `,
})
export class LocaleSwitcherComponent {
  private translate = inject(TranslateService)
  languages: { code: string; name: string }[] = []

  async ngOnInit() {
    // Locales come from the project manifest, not a hardcoded array.
    this.languages = await betterI18n.getLanguages()
  }

  switchTo(lang: string) {
    // use() calls the loader, which hits the cache or the CDN.
    this.translate.use(lang)
  }
}
In a template

In a template

translate pipe와 service 모두 loader에서 읽으므로 컴포넌트는 CDN을 알 필요가 없습니다.

src/app/app.component.htmlhtml
<!-- app.component.html -->
<h1>{{ 'home.title' | translate }}</h1>
<p>{{ 'home.greeting' | translate: { name: 'World' } }}</p>

<!-- ICU plurals authored in the Better i18n dashboard -->
<p>{{ 'cart.items' | translate: { count: 3 } }}</p>

<app-locale-switcher />
Capabilities

기능

Standalone 컴포넌트 지원
Signals 지원
번역 파이프
i18n 디렉티브
주입 가능한 서비스
지연 로딩 모듈
Angular Universal SSR
AOT 컴파일 지원
Angular CLI 통합
Works with

인기 있는 Angular i18n 라이브러리와 호환

Better I18N은 Angular i18n 라이브러리를 보완합니다 — 번역을 시각적으로 관리하고, 번역자와 협업하고, CDN을 통해 배포하세요.

Better I18N + @ngx-translate/core

가장 널리 사용되는 Angular 번역 라이브러리. 파이프, 디렉티브, 서비스 인젝션을 통한 런타임 번역.Better I18N은 ngx-translate JSON 형식으로 내보냅니다. 대시보드에서 번역을 편집하고 레포지토리에 자동 동기화합니다.

Better I18N + Angular i18n (built-in)

AOT 컴파일, ICU 표현식, 빌드 타임 번역 추출을 갖춘 Angular의 공식 i18n 시스템.Angular XLIFF 형식으로 내보내기. Better I18N이 번역 워크플로를 관리하고, Angular CLI가 로케일별 번들을 빌드합니다.

Better I18N + Transloco

지연 로딩, 풍부한 플러그인, 뛰어난 TypeScript 지원을 갖춘 Angular용 현대적이고 가벼운 i18n 라이브러리.Better I18N의 GitHub 연동으로 Transloco JSON 형식에 번역을 동기화합니다. CDN 배포를 통한 실시간 업데이트.

다른 프레임워크 가이드 탐색

Get started

Angular i18n으로 개발을 시작하세요

무료 플랜 제공. 신용카드가 필요 없습니다.