Translating an Astro Static Site into 10 Locales with SiteLocaleAI
Published on SiteLocaleAI Blog
International SEO is no longer a luxury—it's a necessity. When you combine Astro’s fast static generation with SiteLocaleAI’s self‑hosted JavaScript library, you get a lightweight, framework‑agnostic solution that translates content, localizes prices, and serves fully rendered pages to search engines. This tutorial walks you through a production‑ready setup for 10 locales.
📦 Prerequisites
| Requirement | Why it matters |
|---|---|
| Node.js ≥ 18 | Astro 2.x runs on modern Node versions. |
| Astro project | We’ll start from a fresh astro new scaffold. |
| SiteLocaleAI API key | You’ll need a key for the LLM you prefer (Claude, GPT‑4o‑mini, etc.). |
| Git | For version control and CI/CD. |
| A domain with sub‑paths | e.g., example.com/en/, example.com/fr/ … |
1️⃣ Install the SiteLocaleAI library
SiteLocaleAI ships as a tiny NPM package that works in any front‑end framework. Open a terminal in your Astro root and run:
npm i @sitelocaleai/js
Tip: The library is framework‑agnostic, so you can later reuse the same code in React, Vue, or even a plain WordPress theme.
2️⃣ Define the locales you’ll support
Create a locales.json file at the project root. This file tells SiteLocaleAI which languages and currencies to use, and it also stores the psychological rounding rules for each market.
{
"en": { "language": "en", "currency": "USD", "round": 0.99 },
"fr": { "language": "fr", "currency": "EUR", "round": 0.95 },
"de": { "language": "de", "currency": "EUR", "round": 0.99 },
"es": { "language": "es", "currency": "EUR", "round": 0.95 },
"ja": { "language": "ja", "currency": "JPY", "round": 0 },
"zh": { "language": "zh", "currency": "CNY", "round": 0 },
"pt": { "language": "pt", "currency": "BRL", "round": 0.99 },
"ru": { "language": "ru", "currency": "RUB", "round": 0 },
"it": { "language": "it", "currency": "EUR", "round": 0.95 },
"ko": { "language": "ko", "currency": "KRW", "round": 0 }
}
The round field tells SiteLocaleAI to apply psychological pricing (e.g., $19.99 instead of $20). Adjust as needed.
3️⃣ Initialise the library in a client‑side script
Create src/lib/siteLocale.ts and expose a helper that loads the locale data and injects the translation script into the page.
import { initLocale } from '@sitelocaleai/js';
import locales from '../../locales.json';
export function setupLocale(lang: string) {
const config = locales[lang];
if (!config) {
console.warn(`Locale ${lang} not configured`);
return;
}
initLocale({
apiKey: import.meta.env.SITELOCALEAI_API_KEY,
language: config.language,
currency: config.currency,
rounding: config.round,
// Optional: limit translation to visible DOM nodes for performance
selector: '[data-i18n]'
});
}
Add the environment variable to .env (never commit it!):
SITELOCALEAI_API_KEY=sk_****************
4️⃣ Hook the locale into Astro’s routing
Astro supports dynamic routes. Create a catch‑all route src/pages/[...lang]/index.astro that renders the same page content but with the selected language.
---
import { setupLocale } from '../../lib/siteLocale';
import { useEffect } from 'react'; // Astro can use React hooks if you like
// `lang` comes from the URL, e.g. /fr/
const { lang } = Astro.params;
---
<html lang={lang}>
<head>
<title>My Astro Site – {lang.toUpperCase()}</title>
<meta name="description" content="A multilingual Astro site powered by SiteLocaleAI" />
<!-- SEO meta tags will be pre‑rendered later (see step 6) -->
</head>
<body>
<script>
// Run on the client after the DOM loads
document.addEventListener('DOMContentLoaded', () => {
import('../../lib/siteLocale').then(mod => mod.setupLocale('{lang}'));
});
</script>
<h1 data-i18n="title">Welcome to My Site</h1>
<p data-i18n="intro">
This site is translated on‑the‑fly and prices are shown in your local currency.
</p>
<p data-i18n="price">Price: $49.99</p>
</body>
</html>
The data-i18n attributes mark elements that SiteLocaleAI should translate. The same markup works for every locale.
5️⃣ Add price localisation helper (optional)
If you want prices to be rendered server‑side for SEO, create a tiny utility that formats numbers according to the locale’s currency and rounding rule.
export function formatPrice(value: number, currency: string, round: number) {
const rounded = Math.floor(value) + round;
return new Intl.NumberFormat(undefined, {
style: 'currency',
currency,
minimumFractionDigits: 0,
maximumFractionDigits: 2,
}).format(rounded);
}
Use it in your Astro component when generating static HTML:
---
import { formatPrice } from '../../lib/price';
import locales from '../../locales.json';
const { lang } = Astro.params;
const { currency, round } = locales[lang] ?? locales['en'];
const price = formatPrice(49.99, currency, round);
---
<p>Price: {price}</p>
Now search engines see the correctly formatted price during the crawl.
6️⃣ SEO pre‑rendering with SiteLocaleAI CLI
SiteLocaleAI ships a CLI that can pre‑render translated pages for crawlers. Install it globally (or as a dev dependency):
npm i -D @sitelocaleai/cli
Add a script to package.json:
{
"scripts": {
"build": "astro build",
"prerender": "sitelocaleai prerender --locales locales.json --output dist"
}
}
Run the full pipeline:
npm run build && npm run prerender
The CLI will:
1. Spin up a headless browser.
2. Visit each locale path (/en/, /fr/, …).
3. Capture the fully translated DOM.
4. Write static HTML files into dist/ so that Google, Bing, and Yandex index the exact content they serve to users.
Reference: See the official docs for advanced options – https://sitelocaleai.com/docs/seo.
7️⃣ Deploy
static output
Because Astro generates static files, you can host the dist/ folder on any CDN (Netlify, Vercel, Cloudflare Pages, etc.). The pre‑rendered locale files are already SEO‑ready, and the client‑side script will handle any dynamic content that changes after the initial load.
8️⃣ Verify the implementation
- Crawl test – Use
curl -L https://example.com/fr/and confirm the HTML contains French text and the formatted price. - Google Search Console – Submit the sitemap (
/sitemap.xml). The URLs should appear under “International Targeting”. - Lighthouse – Run an audit for each locale; you should see a 100 % score for SEO and a fast‑loading page thanks to Astro’s partial hydration.
🎉 Wrap‑up
You now have a fully international Astro site that:
- Serves 10 locales with accurate translations.
- Shows psychologically rounded prices per currency.
- Delivers pre‑rendered SEO pages to search engines.
- Remains self‑hosted and cost‑effective because you use your own LLM API keys.
All of this is possible with a few dozen lines of code and the powerful SiteLocaleAI library.
📣 Ready to go global?
Try SiteLocaleAI on your next project and see how easy it is to combine fast static sites with AI‑driven localization. Get started now and unlock the full potential of international SEO.
For deeper technical details, explore the full documentation at https://sitelocaleai.com/docs.