Pre‑render Multilingual Gatsby Sites with SiteLocaleAI
International SEO is a game‑changer for static sites, but Google can only index what it can crawl. With SiteLocaleAI you can generate fully translated, pre‑rendered HTML pages at build time, letting search engines see every language version. This tutorial shows how to integrate the library into a Gatsby project, configure it with your own LLM API key, and run the CLI to produce SEO‑ready multilingual pages.
1. Prerequisites
- Node.js >= 18 and npm or yarn
- A Gatsby site (if you need a starter, run
npm init gatsby) - An LLM API key (Claude, GPT‑4o‑mini, etc.) – SiteLocaleAI is self‑hosted, so you keep the key.
- Optional: Docker for a reproducible build environment.
2. Install the SiteLocaleAI JavaScript library
# In your Gatsby project root
npm install @sitelocaleai/core
The library is framework‑agnostic, so you can import it anywhere in your React components or Gatsby Node APIs.
3. Create a translation configuration file
Add a sitelocale.config.js file at the project root. This file tells SiteLocaleAI which languages to generate, the LLM provider, and the price‑localization rules.
// sitelocale.config.js
module.exports = {
// Languages you want to support (ISO 639‑1 codes)
locales: ["en", "es", "fr", "de", "ja"],
// Default locale – used for the source content
defaultLocale: "en",
// LLM provider configuration – keep your key secret (e.g., via .env)
llm: {
provider: "openai", // or "anthropic", "gemini", etc.
model: "gpt-4o-mini",
apiKey: process.env.OPENAI_API_KEY,
},
// Psychological rounding for price localization
priceRounding: {
usd: (value) => Math.round(value / 5) * 5, // nearest $5
eur: (value) => Math.round(value / 5) * 5,
jpy: (value) => Math.round(value / 100) * 100,
},
};
Tip: Store
OPENAI_API_KEYin a.envfile and load it withdotenvingatsby-node.js.
4. Hook SiteLocaleAI into Gatsby's build pipeline
Edit gatsby-node.js to translate the library during the onCreatePage and preRenderPage phases.
// gatsby-node.js
require("dotenv").config();
const { translatePage, preRenderPage } = require("@sitelocaleai/core");
const config = require("./sitelocale.config");
exports.onCreatePage = async ({ page, actions }) => {
const { createPage, deletePage } = actions;
// Delete the original page – we’ll replace it with localized versions
deletePage(page);
// Generate a page for each locale
const localizedPages = await translatePage(page, config);
localizedPages.forEach(createPage);
};
exports.onPreRenderHTML = async ({ getHeadComponents, replaceHeadComponents }) => {
// This hook runs after HTML is generated but before it’s written to disk.
// Use SiteLocaleAI’s CLI (see next step) for bulk pre‑rendering; here we keep it simple.
const head = getHeadComponents();
// Example: inject hreflang tags for SEO
const hreflangLinks = config.locales.map((locale) => (
<link
rel="alternate"
hrefLang={locale}
href={`${process.env.SITE_URL}/${locale}${page.path}`}
/>
);
replaceHeadComponents([...head, ...hreflangLinks]);
};
The translatePage helper reads the page’s JSX, sends the text to the LLM, and returns a set of new page objects – one per locale. Prices inside the content are automatically rounded according to the priceRounding functions.
5. Pre‑render translations for SEO with the CLI
SiteLocaleAI ships a CLI that can crawl your built site, translate every HTML file, and write the localized versions to the public folder. This is what Google will index.
# Install the CLI globally (optional) or use npx
npm install -g @sitelocaleai/cli
# Run after `gatsby build`
gatsby build
# Pre‑render translations
sitelocale-cli pre-render \
--config ./sitelocale.config.js \
--output ./public \
--concurrency 4
The CLI does three things:
1. Extracts visible text from each HTML file.
2. Calls your LLM API for each target language.
3. Writes a new HTML file under public/<locale>/… preserving the original URL structure.
Because the pages are fully rendered HTML, search bots see the translated content without executing JavaScript.
6. Verify hreflang tags and sitemap
After pre‑rendering, inspect a sample page (e.g., public/es/index.html). You should see <link rel="alternate" hreflang="es" href="/es/"/> entries for every locale. Update your gatsby-plugin-sitemap configuration to include the locale prefixes.
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: "gatsby-plugin-sitemap",
options: {
query: `
{
allSitePage {
nodes {
path
}
}
}
`,
resolveSiteUrl: () => process.env.SITE_URL,
// Include locale prefixes in the sitemap
serialize: ({ site, allSitePage: { nodes } }) =>
nodes.map(node => {
const locale = node.path.split("/")[1];
const url = `${process.env.SITE_URL}/${locale}${node.path}`;
return { url, changefreq: "daily", priority: 0.7 };
}),
},
},
],
};
Submit the generated sitemap.xml to Google Search Console. Google will now crawl each language version as a separate URL, boosting your international visibility.
7. Deploy
Because the translations are static files, you can host them on any CDN or static‑site host (Netlify, Vercel, AWS S3, Cloudflare Pages). No server‑side rendering is required.
# Example: Netlify deploy
netlify deploy --dir=public --prod
8. Keep your LLM keys safe
Since SiteLocaleAI is self‑hosted, the API keys never leave your build environment. Make sure:
- .env files are excluded from version control (gitignore).
- CI pipelines use secret management (GitHub Actions secrets, GitLab CI variables, etc.).
9. Next steps
- A/B test different translation prompts to improve tone.
- Add currency conversion using the
priceRoundinghooks for each locale. - Combine with the SiteLocaleAI WordPress plugin for hybrid sites.
For deeper configuration options, see the official docs.
10. Call to action
Ready to make your Gatsby site truly global? Try SiteLocaleAI today – the drop‑in, framework‑agnostic library that gives you fast, SEO‑friendly multilingual pages without a backend. Sign up for the $5 Indie plan and start scaling your international traffic now!