next-simple-i18n
v2.0.1
Published
A small React/Next i18n helper focused on simple string lookup and an optional in-app translation mode.
Readme
next-simple-i18n
A small React/Next i18n helper focused on simple string lookup and an optional in-app translation mode.
Install
bun add next-simple-i18nExports
import {
I18N,
I18NProvider,
I18NTranslatorPlugin,
useI18NContext,
createConstContext,
createContextFromHook,
} from 'next-simple-i18n'Translation data shape
const translations = {
en: {
hello: 'Hello',
welcome_user: 'Welcome, $name',
},
vi: {
hello: 'Xin chao',
welcome_user: 'Xin chao, $name',
},
}Basic usage
import { I18N, I18NProvider } from 'next-simple-i18n'
export default function App() {
return (
<I18NProvider language_id="en" data={translations}>
<main>
<h1><I18N>hello</I18N></h1>
<p>
<I18N variables={{ name: 'Ba' }}>welcome_user</I18N>
</p>
</main>
</I18NProvider>
)
}children is used as the translation key.
If no translation is found, the key itself is rendered.
Dynamic translations
Use json when the translated value is only known at render time.
<I18N
json={{
en: 'Draft',
vi: 'Ban nhap',
}}
>
status_label
</I18N>HTML rendering
<I18N html>{'article_body'}</I18N>When html is enabled the resolved string is rendered with dangerouslySetInnerHTML, so only use trusted content.
Translation mode
When translating is enabled, each I18N node is wrapped with a visible border. Right click on desktop or long press on touch devices to edit a translation.
<I18NProvider
language_id="vi"
data={translations}
translating
promptForTranslating
push={(payload) => {
socket.send(JSON.stringify({
event: 'translation',
data: payload,
}))
}}
>
<Page />
</I18NProvider>push receives:
type OnTranslateProps = {
language_id: string
key: string
value: string
namespace?: string
dynamic?: boolean
}Using the provider context
'use client'
import { useI18NContext } from 'next-simple-i18n'
export function LanguageSwitcher() {
const { language_id, set_language_id, translator } = useI18NContext()
return (
<div>
<button disabled={language_id === 'en'} onClick={() => set_language_id('en')}>
EN
</button>
<button disabled={language_id === 'vi'} onClick={() => set_language_id('vi')}>
VI
</button>
<button onClick={translator.toggle}>Toggle translate mode</button>
</div>
)
}translator exposes on, off, toggle, edit, key, and value.
Vite plugin
The Vite plugin listens for websocket messages shaped like:
{
event: 'translation',
data: OnTranslateProps
}and writes the translated value into ./<path>/<language_id>.json.
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { I18NTranslatorPlugin } from 'next-simple-i18n'
export default defineConfig({
plugins: [
react(),
I18NTranslatorPlugin('messages'),
],
})With this setup the plugin writes to files like ./messages/en.json and ./messages/vi.json.
Notes
I18NProvideris a thin wrapper around the client provider.- This package does not load files for you; you provide the translation database.
- The Vite plugin is intended for local development workflows where the dev server can write to your translation files.
