Framework Guide

Add Internationalization to Your Next.js Site Without Rebuilding Routing

Published May 14, 2026

Add Internationalization to Your Next.js Site Without Rebuilding Routing

Add Internationalization to Your Next.js Site Without Rebuilding Routing

Published on SiteLocaleAI Blog ---

Internationalization (i18n) is a must‑have for any site that wants to attract a global audience. In a typical Next.js project you might reach to create language‑specific routes (/en, /fr, …) or use next-i18next. That approach works, but it forces you to restructure your routing, which can be risky for mature apps.

SiteLocaleAI offers a different path: a framework‑agnostic, self‑hosted JavaScript library that translates page content on the fly, localizes prices with psychological rounding, and even pre‑renders translated pages for SEO. Because it runs entirely in the browser (or on the server via Node for CLI), you keep your existing Next.js routing untouched.

In this tutorial we’ll:
1. Install the SiteLocaleAI library.
2. Configure it to use your own LLM API key.
3. Add a simple language switcher.
4. Enable price localization.
5. Run the SEO pre‑render CLI so search engines index the translated pages.

Tip: All code snippets assume a fresh Next.js 14 project (n create-next-app@latest my‑intl‑app).


1. Install the SiteLocaleAI Package

SiteLocaleAI is distributed as an npm package that bundles the client‑side library. Run:

npm i @sitelocaleai/client

If you prefer Yarn or PNPM, the command is the same.


2. Create a Global Provider

Because the library is framework‑agnostic, we’ll wrap the whole app in a React context that loads the translation model once. Create lib/localeProvider.jsx:

// lib/localeProvider.jsx
import { createContext, useEffect, useState } from "react";
import { SiteLocaleAI } from "@sitelocaleai/client";

export const LocaleContext = createContext({
  locale: "en",
  setLocale: () => {},
  t: (key) => key,
});

export default function LocaleProvider({ children }) {
  const [locale, setLocale] = useState("en");
  const [translator, setTranslator] = useState(null);

  useEffect(() => {
    // Initialise the library with your LLM API key (e.g., Claude or GPT‑4o‑mini)
    const ai = new SiteLocaleAI({
      apiKey: process.env.NEXT_PUBLIC_SITELocaleAI_API_KEY,
      model: "gpt-4o-mini",
      defaultLocale: "en",
    });
    setTranslator(ai);
  }, []);

  // Simple translation helper that falls back to the original text
  const t = async (text) => {
    if (!translator) return text;
    return await translator.translate(text, locale);
  };

  return (
    <LocaleContext.Provider value={{ locale, setLocale, t }}>
      {children}
    </LocaleContext.Provider>
  );
}

Add the provider to pages/_app.jsx:

// pages/_app.jsx
import LocaleProvider from "../lib/localeProvider";
import "../styles/globals.css";

export default function MyApp({ Component, pageProps }) {
  return (
    <LocaleProvider>
      <Component {...pageProps} />
    </LocaleProvider>
  );
}

3. Build a Language Switcher

Create a tiny component that toggles the locale. Place it in components/LanguageSwitcher.jsx:

import { useContext } from "react";
import { LocaleContext } from "../lib/localeProvider";

export default function LanguageSwitcher() {
  const { locale, setLocale } = useContext(LocaleContext);

  const change = (e) => setLocale(e.target.value);

  return (
    <select value={locale} onChange={change} aria-label="Select language">
      <option value="en">English</option>
      <option value="fr">Français</option>
      <option value="es">Español</option>
      <option value="de">Deutsch</option>
    </select>
  );
}

Use it in your layout (e.g., components/Header.jsx):

import LanguageSwitcher from "./LanguageSwitcher";

export default function Header() {
  return (
    <header className="flex justify-between items-center p-4">
      <h1>My International Store</h1>
      <LanguageSwitcher />
    </header>
  );
}

4. Translate Text on the Fly

Inside any page you can call the t function from the context. Here’s an example for pages/index.jsx:

import { useContext, useEffect, useState } from "react";
import { LocaleContext } from "../lib/localeProvider";

export default function Home() {
  const { t } = useContext(LocaleContext);
  const [welcome, setWelcome] = useState("");

  useEffect(() => {
    // Translate once on mount or when locale changes
    const load = async () => {
      const txt = await t("Welcome to our global store!");
      setWelcome(txt);
    };
    load();
  }, [t]);

  return (
    <main className="p-8">
      <h2>{welcome}</h2>
      <p>{/* other content */}</p>
    </main>
  );
}

The library contacts the LLM you configured (Claude, GPT‑4o‑mini, etc.) and returns a translation in the selected language. Because the call is asynchronous, you can add a loading spinner if you wish.


5. Localize Prices with Psychological Rounding

SiteLocaleAI also offers a localizePrice helper that converts a numeric value to the target currency and applies psychological rounding (e.g., $9.99 → $9.95). Extend localeProvider.jsx:

// Inside the provider after translator is set
const localizePrice = async (amount, currency) => {
  if (!translator) return `${amount} ${currency}`;
  return await translator.localizePrice(amount, currency);
};

// Export via context
<LocaleContext.Provider value={{ locale, setLocale, t, localizePrice }}>

Use it in a component:

import { useContext } from "react";
import { LocaleContext } from "../lib/localeProvider";

export default function ProductCard({ priceUSD }) {
  const { localizePrice, locale } = useContext(LocaleContext);
  const [price, setPrice] = useState("");

  useEffect(() => {
    const fetchPrice = async () => {
      // Map locale to currency – simple example
      const currencyMap = { en: "USD", fr: "EUR", es: "EUR", de: "EUR" };
      const priceStr = await localizePrice(priceUSD, currencyMap[locale] || "USD");
      setPrice(priceStr);
    };
    fetchPrice();
  }, [priceUSD, locale, localizePrice]);

  return (
    <div className="card">
      <p>Price: {price}</p>
    </div>
  );
}

Now every visitor sees a price that feels natural for their market, without any server‑side calculations.


6. SEO‑Friendly Pre‑Rendering with the CLI

Search engines can’t execute client‑side translation scripts, so you need static HTML for each language. SiteLocaleAI ships a CLI that crawls your site, renders pages with the selected locale, and writes the output to a dist/ folder.

First, install the CLI globally (or as a dev dependency):

npm i -D @sitelocaleai/cli

Add a script to package.json:

"scripts": {
  "build": "next build",
  "prerender": "sitelocaleai prerender --locales en,fr,es,de --output ./dist"
}

Run it after a normal Next.js build:

npm run build && npm run prerender

The CLI will:
1. Spin up a headless Chromium instance.
2. Load each route (/, /product/42, …) with the Accept-Language header set to the target locale.
3. Capture the fully rendered HTML (including translated text and localized prices).
4. Save the files under dist/<locale>/….

You can now point your CDN or static host to the dist folder. Search engines will index the language‑specific pages, giving you the SEO boost of a fully localized site without changing your Next.js routing logic.

For more details, see the official docs: https://sitelocaleai.com/docs/seo-pre-rendering.


7. Deploy and Test

  1. Set environment variables – add NEXT_PUBLIC_SITELocaleAI_API_KEY to your Vercel/Netlify env.
  2. Run the pre‑render step – verify the HTML files contain the translated strings.
  3. Check price rounding – open a product page in each language and confirm the price looks natural.
  4. Validate SEO – use curl -H "Accept-Language: fr" https://yourdomain.com/ and inspect the returned HTML.

8. Wrap‑Up

You now have a fully internationalized Next.js site that:
- Keeps the original routing untouched.
- Translates content on the fly using your own LLM API key.
- Localizes prices with psychological rounding.
- Generates SEO‑ready static pages for every supported language.

All of this is powered by SiteLocaleAI’s drop‑in JavaScript library, which works with any framework (React, Vue, WordPress, Shopify, etc.) and can be self‑hosted for privacy and cost control.


Ready to go global?

Try SiteLocaleAI today and see how easy it is to add multilingual support, price localization, and SEO‑friendly pre‑rendering to any web project. Visit the quick‑start guide and start translating in minutes!