Internationalizing a Next.js App with SiteLocaleAI (No Routing Overhaul)
Published on SiteLocaleAI Blog
Introduction
Next.js ships with a powerful built‑in i18n routing system, but it often forces you to restructure pages, duplicate routes, or run a separate build for each locale. If you want a drop‑in solution that works with any framework, respects your existing routing, and still gives you SEO‑friendly, fully translated pages, SiteLocaleAI is the answer.
In this tutorial we’ll take a standard Next.js 13 (App Router) project and:
- Install the SiteLocaleAI JavaScript library.
- Configure it to use your own LLM API key (Claude, GPT‑4o‑mini, etc.).
- Wrap your pages with a
<LocaleProvider>that automatically translates content on the client side. - Use the SiteLocaleAI CLI to pre‑render static HTML for each target language, so search engines index the translated pages.
- Add price localization with psychological rounding.
All of this happens without touching your existing next.config.js routing.
1. Install the library
# Using npm
npm install @sitelocaleai/core
# Or Yarn
yarn add @sitelocaleai/core
The package is framework‑agnostic, so it works the same in React, Vue, WordPress, Shopify, or a plain HTML site.
2. Set up environment variables
Create a .env.local file (or add to your existing env) with your LLM API key and the list of locales you want to support:
NEXT_PUBLIC_SITELOCALEAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxx
NEXT_PUBLIC_SITELOCALEAI_LOCALES=en,es,fr,de,ja
NEXT_PUBLIC_SITELOCALEAI_DEFAULT=en
Security tip: Keep the API key server‑side only. SiteLocaleAI’s client library reads the key from the environment at build time and then uses it to sign requests to your LLM endpoint.
3. Wrap your app with <LocaleProvider>
Create a new file components/LocaleProvider.tsx:
import { createContext, useContext, useEffect, useState, ReactNode } from 'react';
import { SiteLocaleAI, LocaleConfig } from '@sitelocaleai/core';
const LocaleContext = createContext<{ locale: string; setLocale: (l: string) => void }>({
locale: process.env.NEXT_PUBLIC_SITELOCALEAI_DEFAULT ?? 'en',
setLocale: () => {},
});
export const LocaleProvider = ({ children }: { children: ReactNode }) => {
const [locale, setLocale] = useState<string>(
process.env.NEXT_PUBLIC_SITELOCALEAI_DEFAULT ?? 'en'
);
// Initialize SiteLocaleAI once per locale change
useEffect(() => {
const config: LocaleConfig = {
apiKey: process.env.NEXT_PUBLIC_SITELOCALEAI_API_KEY!,
targetLocale: locale,
// Optional: custom price rounding per currency
priceRounding: {
USD: (v) => Math.round(v * 0.99), // psychological pricing
EUR: (v) => Math.round(v * 0.95),
},
};
SiteLocaleAI.init(config);
}, [locale]);
return (
<LocaleContext.Provider value={{ locale, setLocale }}>
{children}
</LocaleContext.Provider>
);
};
export const useLocale = () => useContext(LocaleContext);
Now update app/layout.tsx (or pages/_app.tsx for the Pages Router) to include the provider:
import './globals.css';
import { LocaleProvider } from '@/components/LocaleProvider';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<LocaleProvider>{children}</LocaleProvider>
</body>
</html>
);
}
4. Translate UI strings on the fly
Inside any component you can now call SiteLocaleAI.translate():
import { SiteLocaleAI } from '@sitelocaleai/core';
import { useLocale } from '@/components/LocaleProvider';
export default function Hero() {
const { locale, setLocale } = useLocale();
const [title, setTitle] = useState('Welcome to Our Store');
const [subtitle, setSubtitle] = useState('Best prices, worldwide shipping');
// Translate once when the locale changes
useEffect(() => {
async function translate() {
const tTitle = await SiteLocaleAI.translate('Welcome to Our Store');
const tSubtitle = await SiteLocaleAI.translate('Best prices, worldwide shipping');
setTitle(tTitle);
setSubtitle(tSubtitle);
}
translate();
}, [locale]);
return (
<section className="hero">
<h1>{title}</h1>
<p>{subtitle}</p>
<select
value={locale}
onChange={(e) => setLocale(e.target.value)}
aria-label="Select language"
>
{process.env.NEXT_PUBLIC_SITELOCALEAI_LOCALES?.split(',').map((l) => (
<option key={l} value={l}>
{l.toUpperCase()}
</option>
))}
</select>
</section>
);
}
The translate call is cached by SiteLocaleAI, so subsequent renders are instantaneous.
5. Localize prices automatically
If you have a price component, just pass the raw number to SiteLocaleAI.formatPrice():
import { SiteLocaleAI } from '@sitelocaleai/core';
export function Price({ amount, currency }: { amount: number; currency: string }) {
const formatted = SiteLocaleAI.formatPrice(amount, currency);
return <span>{formatted}</span>;
}
SiteLocaleAI applies the psychological rounding you configured earlier (e.g., $9.99 instead of $10.00) and adds the correct currency symbol.
6. SEO‑friendly pre‑rendering with the CLI
Search engines need static HTML to index translated pages. SiteLocaleAI ships a CLI that crawls your site, renders each locale, and writes the output to a dist/ folder.
# Install the CLI globally (optional)
npm i -g @sitelocaleai/cli
# Run the pre‑render step
npx sitelocaleai prerender \
--output ./out \
--locales en,es,fr,de,ja \
--base-url https://yourdomain.com
The CLI:
- Starts a headless Chromium instance.
- Visits each page, injects the
LocaleProviderwith the target locale, and captures the fully rendered HTML. - Saves
en/index.html,es/index.html, etc.
You can then serve the out folder with any static host (Vercel, Netlify, Cloudflare Pages). Search bots will see the translated content, boosting international SEO.
For a deeper dive, see the official docs: https://sitelocaleai.com/docs/cli-prerender
7. Optional: WordPress plugin for hybrid sites
If part of your site lives on WordPress, you don’t need Node.js. The SiteLocaleAI WordPress plugin injects the same client library via a simple shortcode. Check the integration guide at https://sitelocaleai.com/docs/wordpress.
8. Test it locally
npm run dev
# Open http://localhost:3000
# Switch language from the dropdown – you’ll see instant translation and price changes.
Run the CLI and inspect the generated HTML files to verify that the <html lang="…"> attribute matches the locale and that meta tags (og:locale, hreflang) are present.
9. Deploy
Deploy your Next.js app as usual (Vercel, Railway, Docker, etc.). Because the translation happens on the client side and the pre‑rendered HTML is served statically, you get the best of both worlds: fast page loads and crawlable content.
Conclusion
You now have a fully internationalized Next.js site that:
- Uses SiteLocaleAI’s drop‑in JS library – no routing changes.
- Provides real‑time translation and price localization with psychological rounding.
- Generates SEO‑ready static pages for every locale via the CLI.
- Works seamlessly with any framework, including WordPress.
Ready to go global? Try SiteLocaleAI today and see how effortless multilingual web experiences can be.
Happy translating!