Ask your question and get a summary of the document by referencing this page and the AI provider of your choice
Version History
- "Update Solid useIntlayer API usage to direct property access"v8.9.05/4/2026
- "Initial history"v8.4.103/31/2026
If you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
Translate your Vanilla JS website using Intlayer | Internationalization (i18n)
Table of Contents
What is Intlayer?
Intlayer is an innovative, open-source internationalization (i18n) library designed to simplify multilingual support in modern web applications.
With Intlayer, you can:
- Easily manage translations using declarative dictionaries at the component level.
- Dynamically localize metadata, routes, and content.
- Ensure TypeScript support with autogenerated types, improving autocompletion and error detection.
- Benefit from advanced features, like dynamic locale detection and switching.
This guide demonstrates how to use Intlayer in a Vanilla JavaScript application without using a package manager or a bundler (like Vite, Webpack, etc.).
If your application uses a bundler (like Vite), we recommend following the Vite + Vanilla JS Guide instead.
Using the standalone bundle, you can import Intlayer directly into your HTML files via a single JavaScript file, making it perfect for legacy projects or simple static sites.
Step-by-Step Guide to Set Up Intlayer in a Vanilla JS Application
Step 1: Install Dependencies
Install the necessary packages using npm:
Copy the code to the clipboard
# Generate a standalone bundle of intlayer and vanilla-intlayer# This file will be imported in to your HTML filenpx intlayer standalone --packages intlayer vanilla-intlayer --outfile intlayer.js# Initialize intlayer with config filenpx intlayer init --no-gitignore# Build the dictionariesnpx intlayer buildintlayer The core package that provides internationalization tools for configuration management, translation, content declaration, transpilation, and CLI commands.
vanilla-intlayer The package that integrates Intlayer with plain JavaScript / TypeScript applications. It provides a pub/sub singleton (
IntlayerClient) and callback-based helpers (useIntlayer,useLocale, etc.) so any part of your app can react to locale changes without depending on a UI framework.
The intlayer standalone CLI's bundling export produces an optimized build by tree-shaking unused packages, locales, and non-essential logic (such as redirection or prefixes) specific to your configuration.
Step 2: Configuration of your project
Create a config file to configure the languages of your application:
Copy the code to the clipboard
import { Locales, type IntlayerConfig } from "intlayer";
const config: IntlayerConfig = {
internationalization: {
locales: [
Locales.ENGLISH,
Locales.FRENCH,
Locales.SPANISH,
// Your other locales
],
defaultLocale: Locales.ENGLISH,
},
};
export default config;Through this configuration file, you can set up localized URLs, middleware redirection, cookie names, the location and extension of your content declarations, disable Intlayer logs in the console, and more. For a complete list of available parameters, refer to the configuration documentation.
Step 3: Import the bundle in your HTML
Once you have generated the intlayer.js bundle, you can import it in your HTML file:
Copy the code to the clipboard
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <!-- Import the bundle --> <script src="./intlayer.js" defer></script> <!-- Import your main script --> <script src="./src/main.js" defer></script> </head> <body> <h1 id="title"></h1> <p class="read-the-docs"></p> </body></html>The bundle exposes Intlayer and VanillaIntlayer as global objects on the window.
Step 4: Bootstrap Intlayer in your entry point
In your src/main.js, call installIntlayer() before any content is rendered so that the global locale singleton is ready.
Copy the code to the clipboard
const { installIntlayer } = window.VanillaIntlayer;// Must be called before rendering any i18n content.installIntlayer();If you also want to use the markdown renderer, call installIntlayerMarkdown():
Copy the code to the clipboard
const { installIntlayer, installIntlayerMarkdown } = window.VanillaIntlayer;installIntlayer();installIntlayerMarkdown();Step 5: Declare Your Content
Create and manage your content declarations to store translations:
Copy the code to the clipboard
import { insert, t, type Dictionary } from "intlayer";
const appContent = {
key: "app",
content: {
title: "Vite + Vanilla",
viteLogoLabel: t({
en: "Vite Logo",
fr: "Logo Vite",
es: "Logo Vite",
}),
count: insert(
t({
en: "count is {{count}}",
fr: "le compte est {{count}}",
es: "el recuento es {{count}}",
})
),
readTheDocs: t({
en: "Click on the Vite logo to learn more",
fr: "Cliquez sur le logo Vite pour en savoir plus",
es: "Haga clic en el logotipo de Vite para obtener más información",
}),
},
} satisfies Dictionary;
export default appContent;Your content declarations can be defined anywhere in your application as soon as they are included in the
contentDirdirectory (by default,./src). And match the content declaration file extension (by default,.content.{json,ts,tsx,js,jsx,mjs,cjs}).For more details, refer to the content declaration documentation.
Step 6: Use Intlayer in Your JavaScript
The window.VanillaIntlayer object provides API helpers: useIntlayer(key, locale?) returns the translated content for a given key.
Copy the code to the clipboard
const { installIntlayer, useIntlayer } = window.VanillaIntlayer;installIntlayer();// Get the initial content for the current locale.// Chain .onChange() to be notified whenever the locale changes.const content = useIntlayer("app").onChange((newContent) => { // Re-render or patch only the affected DOM nodes document.querySelector("h1").textContent = String(newContent.title); document.querySelector(".read-the-docs").textContent = String( newContent.readTheDocs );});// Initial renderdocument.querySelector("h1").textContent = String(content.title);document.querySelector(".read-the-docs").textContent = String( content.readTheDocs);Access leaf values as strings by wrapping them in
String(), which calls the node'stoString()method and returns the translated text.When you need the value for a native HTML attribute (e.g.
alt,aria-label), use.valuedirectly:javascriptCopy codeCopy the code to the clipboard
img.alt = content.viteLogoLabel.value;
(Optional) Step 7: Change the language of your content
To change the language of your content, use the setLocale function exposed by useLocale.
Copy the code to the clipboard
const { getLocaleName } = window.Intlayer;const { useLocale } = window.VanillaIntlayer;export function setupLocaleSwitcher(container) { const { locale, availableLocales, setLocale, subscribe } = useLocale(); const select = document.createElement("select"); select.setAttribute("aria-label", "Language"); const render = (currentLocale) => { select.innerHTML = availableLocales .map( (loc) => `<option value="${loc}"${loc === currentLocale ? " selected" : ""}> ${getLocaleName(loc)} </option>` ) .join(""); }; render(locale); container.appendChild(select); select.addEventListener("change", () => setLocale(select.value)); // Keep the dropdown in sync when locale changes from elsewhere return subscribe((newLocale) => render(newLocale));}(Optional) Step 8: Switch the HTML Language and Direction Attributes
Update the <html> tag's lang and dir attributes to match the current locale for accessibility and SEO.
Copy the code to the clipboard
const { getHTMLTextDir } = window.Intlayer;const { installIntlayer, useLocale } = window.VanillaIntlayer;installIntlayer();useLocale({ onLocaleChange: (locale) => { document.documentElement.lang = locale; document.documentElement.dir = getHTMLTextDir(locale); },});(Optional) Step 9: Lazy-load dictionaries per locale
If you want to lazy-load dictionaries per locale, you can use useDictionaryDynamic. This is useful if you don't want to bundle all translations in the initial intlayer.js file.
Copy the code to the clipboard
const { installIntlayer, useDictionaryDynamic } = window.VanillaIntlayer;installIntlayer();const unsubscribe = useDictionaryDynamic( { en: () => import("../.intlayer/dictionaries/en/app.mjs"), fr: () => import("../.intlayer/dictionaries/fr/app.mjs"), es: () => import("../.intlayer/dictionaries/es/app.mjs"), }, "app").onChange((content) => { document.querySelector("h1").textContent = String(content.title);});Note: useDictionaryDynamic requires the dictionaries to be available as separate ESM files. This approach is typically used if you have a web server serving the dictionaries.
Configure TypeScript
Ensure your TypeScript configuration includes the autogenerated types.
Copy the code to the clipboard
{ "compilerOptions": { // ... }, "include": ["src", ".intlayer/**/*.ts"],}VS Code Extension
To improve your development experience with Intlayer, you can install the official Intlayer VS Code Extension.
Install from the VS Code Marketplace
This extension provides:
- Autocompletion for translation keys.
- Real-time error detection for missing translations.
- Inline previews of translated content.
- Quick actions to easily create and update translations.
For more details on how to use the extension, refer to the Intlayer VS Code Extension documentation.
Go Further
To go further, you can implement the visual editor or externalize your content using the CMS.