Welcome to i18n-keyless
Install i18n-keyless in less than 5 minutes.
Get an API key by visiting https://i18n-keyless.com/#get-api-key
Three ways to hand your assistant the whole of i18n-keyless:
- /llms.txt — the whole documentation as one Markdown file. Paste it into Claude / ChatGPT / Cursor / etc.
SKILL.md— an Agent Skill for Claude Code. Copyskills/i18n-keyless/into your project's.claude/skills/. It also ships insidei18n-keyless-reactandi18n-keyless-node, so an agent finds it innode_modulesonce you install.- Context7 — add
use context7to your prompt if you run the Context7 MCP server.
Getting Started
i18n-keyless is a JavaScript library that works across different environments. Choose your platform below to see the specific setup instructions:
- React
- React Native
- Node.js
Storage is required to cache translations.
- window.localStorage
- IndexedDB (idb-keyval)
You'll need to install the required dependency:
npm install i18n-keyless-react
import * as I18nKeyless from "i18n-keyless-react";
I18nKeyless.init({
API_KEY: "YOUR_API_KEY",
storage: window.localStorage, // or whatever has get/set/del methods, check the codebase below
languages: {
primary: "fr",
supported: ["en", "fr"],
},
});
You'll need to install the required dependency:
npm install i18n-keyless-react idb-keyval
import * as I18nKeyless from "i18n-keyless-react";
import { get, set, del } from 'idb-keyval';
// Create storage adapter for idb-keyval
const indexedDBStorage = {
getItem: async (key) => {
const value = await get(key);
return value || null;
},
setItem: async (key, value) => {
await set(key, value);
},
removeItem: async (key) => {
await del(key);
}
};
I18nKeyless.init({
API_KEY: "YOUR_API_KEY",
storage: indexedDBStorage,
languages: {
primary: "fr",
supported: ["en", "fr"],
},
});
You can check here for the methods that your storage item needs to have
Storage is required to cache translations.
- MMKV
- AsyncStorage
You'll need to install the required dependency:
npx expo install i18n-keyless-react react-native-mmkv
npx expo prebuild
import * as I18nKeyless from "i18n-keyless-react";
import { MMKV } from 'react-native-mmkv'
const storage = new MMKV()
I18nKeyless.init({
API_KEY: "YOUR_API_KEY",
storage: storage,
languages: {
primary: "fr",
supported: ["en", "fr"],
},
});
You'll need to install the required dependency:
npx expo install i18n-keyless-react @react-native-async-storage/async-storage
npx expo prebuild
import * as I18nKeyless from "i18n-keyless-react";
import AsyncStorage from "@react-native-async-storage/async-storage";
I18nKeyless.init({
API_KEY: "YOUR_API_KEY",
storage: AsyncStorage,
languages: {
primary: "fr",
supported: ["en", "fr"],
},
});
You'll need to install the required dependency:
npm install i18n-keyless-node
import * as I18nKeyless from "i18n-keyless-node";
I18nKeyless.init({
API_KEY: "YOUR_API_KEY",
languages: {
primary: "fr",
supported: ["en", "fr"],
},
});
Usage
Once you've initialized i18n-keyless for your platform, you can start translating text immediately:
- React
- React Native
- Node.js
import { I18nKeylessText, useTranslation, getTranslation } from "i18n-keyless-react";
import { TabBar, Tab } from "whatever-tab-bar-system";
// Three ways to get text: `I18nKeylessText` component / `useTranslation` hook / `getTranslation` function
// `I18nKeylessText` component
function Header() {
return (
<h1><I18nKeylessText>Bonjour le monde</I18nKeylessText></h1>
);
}
// `useTranslation` hook — inside a component, for a prop that needs a plain string
function MyTabs() {
const first = useTranslation("Premier onglet");
const second = useTranslation("Deuxième onglet");
return (
<TabBar>
<Tab label={first} />
<Tab label={second} />
</TabBar>
);
}
// `getTranslation` function — outside a component: a route loader, a utility
export const loader = () => ({ title: getTranslation("Premier onglet") });
import { I18nKeylessText, useTranslation, getTranslation } from "i18n-keyless-react";
import { TabBar, Tab } from "whatever-tab-bar-system";
import { Text } from "react-native";
// Three ways to get text: `I18nKeylessText` component / `useTranslation` hook / `getTranslation` function
// `I18nKeylessText` component
function Header() {
return (
<Text><I18nKeylessText>Bonjour le monde</I18nKeylessText></Text>
);
}
// `useTranslation` hook — inside a component, for a prop that needs a plain string
function MyTabs() {
const first = useTranslation("Premier onglet");
const second = useTranslation("Deuxième onglet");
return (
<TabBar>
<Tab label={first} />
<Tab label={second} />
</TabBar>
);
}
// `getTranslation` function — outside a component: a route loader, a utility
export const loader = () => ({ title: getTranslation("Premier onglet") });
awaitForTranslationOrFallbackToOriginal NEED to be awaited, to prevent 429 to happen.
import { awaitForTranslationOrFallbackToOriginal, type Lang } from 'i18n-keyless-node';
async function sendNotificationsToUsers() {
const users = await fetchUsers()
for (const user of users) {
const notification = {
title: await awaitForTranslationOrFallbackToOriginal("Viens voir l'application", user.lang as Lang);
body: await awaitForTranslationOrFallbackToOriginal("Il y a des supers choses !", user.lang as Lang);
}
}
}
Pick by call site: in a request handler — a route, a server component, an email or
notification send — use
awaitForTranslationOrFallbackToOriginal
(it never rejects). In a script or a build step, use
awaitForTranslationOrThrow (an ignored rejection
crashes the process on purpose, so a broken run fails loudly).