@basenative/i18n

中文文档
3.0.0发布于 2026/10/31Apache-2.0TypeScriptES Module构建来源已验证

ICU message formatting, locale detection, and @t template directive

原始使用文档
文档目录10 节
  1. Install
  2. Quick Start
  3. Lazy Loading
  4. Server Middleware
  5. Template Directive: @t
  6. API
  7. createI18n(options?)
  8. createLoader(options)
  9. i18nMiddleware(i18n, options?)
  10. License

@basenative/i18n

ICU-style internationalization with locale detection, lazy message loading, and middleware

Part of the BaseNative ecosystem — a signal-based web runtime over native HTML.

Install

npm install @basenative/i18n

Quick Start

import { createI18n } from '@basenative/i18n';

const i18n = createI18n({
  defaultLocale: 'en',
  messages: {
    en: {
      greeting: 'Hello, {name}!',
      itemCount: '{count, plural, one {# item} other {# items}}',
    },
    es: {
      greeting: 'Hola, {name}!',
      itemCount: '{count, plural, one {# elemento} other {# elementos}}',
    },
  },
});

i18n.t('greeting', { name: 'Alice' }); // "Hello, Alice!"
i18n.t('itemCount', { count: 3 });     // "3 items"

i18n.setLocale('es');
i18n.t('greeting', { name: 'Alice' }); // "Hola, Alice!"

Lazy Loading

import { createI18n } from '@basenative/i18n';
import { createLoader } from '@basenative/i18n';

const loader = createLoader({
  load: (locale) => import(`./locales/${locale}.json`, { assert: { type: 'json' } })
    .then(m => m.default),
});

const i18n = createI18n({ defaultLocale: 'en' });
await loader.load('fr', i18n);

Server Middleware

import { i18nMiddleware } from '@basenative/i18n';
import { createPipeline } from '@basenative/middleware';

const pipeline = createPipeline()
  .use(i18nMiddleware(i18n));
// ctx.state.locale and ctx.state.t are now available

Template Directive: @t

@basenative/i18n registers a @t template directive with @basenative/runtime's directive registry as a side effect of importing this package — it works anywhere render() (SSR) or hydrate() (client) runs, with no extra wiring:

<h1 @t="nav.home">Home</h1>

@t reads ctx.$i18n — an i18n instance from createI18n() — from the render/hydrate context, and replaces the element's text content with i18n.t(key, ctx). Passing the whole render context as params means any {name}-style placeholder in the message (i18n's own interpolation syntax — see i18n.t() below, not BaseNative's {{ }}) is filled from a same-named property already in scope, with no second templating syntax to learn:

import { createI18n } from '@basenative/i18n';
import { render } from '@basenative/server';

const i18n = createI18n({ defaultLocale: 'en', messages: { en: { 'nav.home': 'Home' } } });
const html = render(template, { ...data, $i18n: i18n });

On the client:

import { hydrate } from '@basenative/runtime';

hydrate(root, { ...data, $i18n: i18n });

@t re-renders on the client whenever i18n.setLocale() runs — createI18n() doesn't expose a @basenative/runtime signal for its locale, so the directive subscribes to onLocaleChange() internally and drives its own reactivity from that.

With no $i18n on context, @t leaves the element's existing content untouched (it does not blank it) and emits a BN_T_NO_PROVIDER diagnostic through options.onDiagnostic — so <h1 @t="nav.home">Home</h1> still renders "Home" as a static fallback. message.key is a literal key, not an expression (no quotes) — the same way @feature's flag name is (see @basenative/flags).

API

createI18n(options?)

Creates an i18n instance. Options: defaultLocale (default: 'en'), messages (locale keyed object).

Returns:

  • t(key, params?) — Translates a message key with optional interpolation params.
  • getLocale() — Returns the current locale string.
  • setLocale(locale) — Changes the active locale.
  • addMessages(locale, messages) — Merges additional messages into a locale.
  • onLocaleChange(fn) — Registers a listener called when the locale changes. Returns an unsubscribe function.

createLoader(options)

Creates a lazy message loader. Options: load(locale) — async function returning a messages object.

  • loadMessages(locale, i18n) — Loads messages for a locale into an i18n instance.

i18nMiddleware(i18n, options?)

Detects the request locale from Accept-Language header and attaches ctx.state.locale and ctx.state.t to the request context.

License

Apache-2.0

版本与发布记录

@basenative/i18n 共发布 11 个版本,首次发布于 2026/03/20;过去 12 个月发布了 11 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.0.0latest2026/10/313 天前
2.4.02026/10/268 天前
2.3.22026/10/2212 天前
2.3.12026/10/2212 天前
2.3.02026/10/2212 天前
2.2.02026/10/2113 天前

关于 @basenative/i18n 的常见问题

@basenative/i18n 是什么?

ICU消息格式化、语言环境检测和@t模板指令

如何安装 @basenative/i18n?

在项目目录运行 npm install @basenative/i18n,或使用 pnpm add / yarn add / bun add。

@basenative/i18n 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@basenative/i18n 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@basenative/i18n 可以商用吗?

@basenative/i18n 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@basenative/i18n 还在维护吗?

最新版本 3.0.0 发布于 2026/10/31(3 天前);至今共发布 11 个版本,其中过去 12 个月发布了 11 个;首次发布于 2026/03/20。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。