Hono
Hono i18n
One middleware detects the request locale and hands every route handler a translator. Messages come from the CDN, so new copy ships without a redeploy.
Setup
Set up Hono with Better I18N
Install the packages
Add Hono and the server adapter. Nothing else is required.
terminal
npm install hono @better-i18n/serverCreate the i18n singleton
Build it once at module scope — the message cache is shared across every request.
src/i18n.ts
import { createServerI18n } from '@better-i18n/server';
// Module scope, not per request: the TtlCache is shared across requests.
export const i18n = createServerI18n({
project: 'your-org/your-project',
defaultLocale: 'en',
});Mount the middleware
After app.use, every handler can read locale and t from the context.
src/index.ts
import { Hono } from 'hono';
import { betterI18n } from '@better-i18n/server/hono';
import type { Translator } from '@better-i18n/server';
import { i18n } from './i18n';
const app = new Hono<{
Variables: { locale: string; t: Translator };
}>();
app.use('*', betterI18n(i18n));
app.get('/users/:id', (c) => {
const t = c.get('t');
return c.json({ error: t('errors.notFound') }, 404);
});
export default app;Capabilities
Why Hono teams choose Better I18N
One line of setup: app.use('*', betterI18n(i18n))
Built on Web Standards — request headers are read directly, with no adapter layer
Runs anywhere Hono runs: Cloudflare Workers, Bun, Deno and Node
A module-scope instance shares its message cache across requests
New messages arrive from the CDN in about 60 seconds, with no redeploy
Typed context variables for locale and t
Example
A localized Hono route
The middleware runs first, so the handler only reads what it needs.
import { OpenAPIHono } from '@hono/zod-openapi';
import { betterI18n } from '@better-i18n/server/hono';
import type { Translator } from '@better-i18n/server';
import { i18n } from './i18n';
const app = new OpenAPIHono<{
Variables: { locale: string; t: Translator };
}>();
// Detect locale + inject `locale` and `t` into every request context
app.use('*', betterI18n(i18n));
app.get('/greeting', (c) => {
const t = c.get('t');
const locale = c.get('locale');
return c.json({
locale,
message: t('greeting.hello'),
});
});
export default app;Other frameworks
Get started
Ship your Hono API in every language
Connect a project, add the middleware, and translate without touching the deploy pipeline.