Problems developers face when localizing Electron apps—and how IntlPull helps.
Electron has main and renderer processes. Translations must be available in both.
Native menus are built in main process before window loads. Timing matters.
Modern Electron uses context isolation. Translations need preload script bridge.
Why i18next-electron is a great choice for Electron localization.
Share translations between main and renderer processes. Consistent language across your app.
vs separate translation instances
Detect OS language via app.getLocale(). Match user's system preferences automatically.
vs manual detection
Localize native menus, dialogs, and system UI. Platform-appropriate translations.
vs web-only UI
Bundle translations with app. No network required. Perfect for offline desktop apps.
vs online-only translation
Use react-i18next or vue-i18n in renderer. Familiar patterns for web developers.
vs learning new APIs
Update translations without app update via IntlPull OTA. Ship translation fixes fast.
vs rebuilding for typos
Get i18next-electron running in your Electron project.
Add i18next packages for Electron.
npm install i18next i18next-fs-backend
# For React renderer:
npm install react-i18nextSet up locale files in resources.
// resources/locales/en/translation.json
{
"app": {
"name": "My App",
"version": "Version {{version}}"
},
"menu": {
"file": "File",
"edit": "Edit",
"view": "View",
"quit": "Quit"
},
"welcome": "Welcome to {{appName}}"
}
// resources/locales/es/translation.json
{
"app": {
"name": "Mi App",
"version": "Version {{version}}"
},
"menu": {
"file": "Archivo",
"edit": "Editar",
"view": "Ver",
"quit": "Salir"
},
"welcome": "Bienvenido a {{appName}}"
}Initialize i18next in main process.
// main/i18n.ts
import i18next from 'i18next';
import Backend from 'i18next-fs-backend';
import { app } from 'electron';
import path from 'path';
const isDev = !app.isPackaged;
export async function initI18n() {
const locale = app.getLocale().split('-')[0]; // 'en-US' -> 'en'
await i18next.use(Backend).init({
lng: locale,
fallbackLng: 'en',
backend: {
loadPath: isDev
? path.join(__dirname, '../resources/locales/{{lng}}/{{ns}}.json')
: path.join(process.resourcesPath, 'locales/{{lng}}/{{ns}}.json'),
},
});
return i18next;
}
export { i18next };Expose i18n to renderer via preload.
// preload/index.ts
import { contextBridge, ipcRenderer } from 'electron';
contextBridge.exposeInMainWorld('i18n', {
t: (key: string, options?: object) => ipcRenderer.invoke('i18n:translate', key, options),
changeLanguage: (lng: string) => ipcRenderer.invoke('i18n:changeLanguage', lng),
getLanguage: () => ipcRenderer.invoke('i18n:getLanguage'),
});
// main/index.ts (add IPC handlers)
import { ipcMain } from 'electron';
import { i18next } from './i18n';
ipcMain.handle('i18n:translate', (_, key, options) => i18next.t(key, options));
ipcMain.handle('i18n:changeLanguage', (_, lng) => i18next.changeLanguage(lng));
ipcMain.handle('i18n:getLanguage', () => i18next.language);Build localized application menu.
// main/menu.ts
import { Menu, app } from 'electron';
import { i18next } from './i18n';
export function createMenu() {
const template: Electron.MenuItemConstructorOptions[] = [
{
label: i18next.t('menu.file'),
submenu: [
{ label: i18next.t('menu.quit'), role: 'quit' },
],
},
{
label: i18next.t('menu.edit'),
submenu: [
{ label: 'Undo', role: 'undo' },
{ label: 'Redo', role: 'redo' },
],
},
];
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
}Connect IntlPull to manage translations professionally.
Add the CLI for translation management.
npm install -D @intlpull/cliSet up the project configuration.
{
"projectId": "your-project-id",
"format": "json",
"sourceLocale": "en",
"localesDir": "./resources/locales",
"filePattern": "{locale}/translation.json"
}Download translations before build.
npx intlpull pullIntegrate with electron-builder.
// package.json
{
"scripts": {
"i18n:pull": "intlpull pull",
"build": "npm run i18n:pull && electron-builder"
},
"build": {
"extraResources": [
{
"from": "resources/locales",
"to": "locales"
}
]
}
}Complete guide to React localization with react-i18next. Setup, lazy loading, namespaces, SSR, and IntlPull integration for production i18n.
Complete guide to Vue 3 localization with vue-i18n. Composition API, lazy loading, and IntlPull integration for production i18n.