@cheetah-labs/i18n
v3.0.2
Published
Locale-aware Angular router, switcher, SEO helpers and fallback util shared across cheetah sites.
Readme
@cheetah-labs/i18n
Locale-aware Angular utilities shared across all cheetah customer sites — router prefix guard, language switcher, SEO helpers and a fallback util.
公開 npm package(npmjs, scope
@cheetah-labs)。 不處理 CMS 內容、不負責翻譯字串管理;只解決 i18n 共用邏輯。
Install
pnpm add @cheetah-labs/i18n公開套件可直接安裝,不需要額外設定私有 registry。
版本相容表 (Compatibility)
| @cheetah-labs/i18n | Angular (peer) | rxjs (peer) | Node (engines) |
|---|---|---|---|
| 3.x | >=22.0.0 <23.0.0 | ^7.8.0 | >=22.0.0 |
| 2.x | >=21.0.0 <22.0.0 | ^7.8.0 | >=22.0.0 |
每個 Angular major 對應本套件一個 major:Angular 23 支援將以下一個 major 版本提供。engines 對消費端保持寬鬆(
>=22);本 repo 開發環境使用 Node 26(.nvmrc)。
API
provideI18n(config)
import { provideI18n, withLocaleRouting } from '@cheetah-labs/i18n';
import { provideRouter } from '@angular/router';
export const appConfig: ApplicationConfig = {
providers: [
provideI18n({
locales: ['zh-TW', 'en'],
defaultLocale: 'zh-TW',
fallbackLocale: 'zh-TW',
strategy: 'prefix',
}),
provideRouter(withLocaleRouting(routes)),
],
};withLocaleRouting(routes)
把路由樹包裝為「每個 top-level route 都會跑 localePrefixGuard」。
/about→ 重導/<defaultLocale>/about/fr/about(fr 不在 locales)→ 重導/<defaultLocale>/about/zh-TW/about(合法)→ 通過
<i18n-switcher />
<i18n-switcher />Standalone component,列出所有 locale,點擊切換 URL;自帶 aria-label="Language switcher" / aria-current。
取得目前語系
import { CURRENT_LOCALE, LocaleResolver } from '@cheetah-labs/i18n';
// 注入時快照 — 不會隨後續導航更新
const locale = inject(CURRENT_LOCALE);
// reactive — 瀏覽器端切換語系後會跟著變
const locale$ = inject(LocaleResolver).current$();
CURRENT_LOCALE是注入當下解析的一次性快照。SSR 每個 request 一個 injector,直接用即可;瀏覽器端長駐應用中,之後切換語系不會改變已注入的值,reactive 場景請改用LocaleResolver.current$()。
pickLocalized(field, locale, fallback)
import { pickLocalized } from '@cheetah-labs/i18n';
pickLocalized({ 'zh-TW': '你好', en: 'Hello' }, 'en', 'zh-TW'); // 'Hello'
pickLocalized({ 'zh-TW': '你好' }, 'en', 'zh-TW'); // '你好'
pickLocalized('plain string', 'en', 'zh-TW'); // 'plain string'
pickLocalized(undefined, 'en', 'zh-TW'); // undefined限制:
pickLocalized以「值是否為 plain object」判斷 i18n 欄位。若T本身是物件(非 locale map),會被誤判為 i18n map 而回傳undefined;物件型內容請自行依 locale key 存取。
SEO
import { HreflangService, CanonicalService } from '@cheetah-labs/i18n';
constructor() {
inject(HreflangService).set('https://example.com/{locale}/about');
inject(CanonicalService).set('https://example.com/zh-TW/about');
}HreflangService 自動加入 x-default,下次呼叫前會清掉舊 tag。
SSR locale resolver
// server.ts (Express)
import { withSsrLocaleResolver, provideI18n } from '@cheetah-labs/i18n';
app.use('*', (req, res) => {
bootstrapApplication(AppComponent, {
providers: [
provideI18n({ locales: ['zh-TW', 'en'], defaultLocale: 'zh-TW' }),
withSsrLocaleResolver(req),
],
});
});CURRENT_LOCALE 解析優先序:
- SSR(
withSsrLocaleResolver):URL prefix →Accept-Language→ defaultLocale - 瀏覽器(
provideI18n內建):URL prefix → defaultLocale
Develop
pnpm install
pnpm test
pnpm lint
pnpm type-check
pnpm build # ng-packagr → ./distPublish
版本管理由 release-please 自動化:
- conventional commits merge 進
main - release-please 自動開 / 更新 Release PR(version bump +
CHANGELOG.md) - Release PR merge 後自動打
vX.Y.Ztag 並建立 GitHub Release - tag 觸發
.github/workflows/publish.yml→ 驗證 tag 與package.json版本一致 → publish 到 npmjs
不手動 bump version、不手動編輯 CHANGELOG.md、不手動打 tag。發佈驗證使用 npm Trusted Publishing(OIDC,需在 npmjs 套件設定對應此 repo/workflow 的 Trusted Publisher);workflow 未接 token fallback,OIDC 是唯一發佈憑證。本 repo 為 private、npm 套件為 public——npm 對 private repo 不會產生 provenance attestations,此為專案定案的發佈模式。
License
Apache-2.0
