Tutorial

Pre‑Render Multilingual Gatsby Sites with SiteLocaleAI

Published September 27, 2026

Pre‑Render Multilingual Gatsby Sites with SiteLocaleAI

Pre‑Render Multilingual Gatsby Sites with SiteLocaleAI

Google loves fully rendered pages, and international visitors expect prices in their own currency. With SiteLocaleAI you can keep your Gatsby static site fast, self‑hosted, and SEO‑friendly—all while letting your own LLM API keys do the heavy lifting.


1. Why Pre‑Render Translations?

  • Instant indexing – Search bots see the final HTML, not a client‑side script.
  • Zero‑JS fallback – Users on slow connections or with JavaScript disabled still get the right language.
  • Performance – Gatsby already generates static assets; we just add a translation step.

SiteLocaleAI’s CLI can generate a separate HTML file for each locale, preserving your existing build pipeline.


2. Prerequisites

Requirement Version
Node.js >= 18
Gatsby CLI 5.x
SiteLocaleAI account –
LLM API key (Claude, GPT‑4o‑mini, etc.) –

Make sure you have a SiteLocaleAI account and an API key for the LLM you intend to use. You’ll need it later when configuring the CLI.


3. Install the Library

# In your Gatsby project root
npm i @sitelocaleai/js

The package is framework‑agnostic, so you can import it anywhere—React components, MDX pages, or plain HTML templates.


4. Add the Translation Wrapper

Create a small utility that loads the library and fetches translations at build time. Save it as src/utils/translate.js:

import { SiteLocaleAI } from "@sitelocaleai/js";

// Initialise with your LLM API key (kept secret via env var)
const ai = new SiteLocaleAI({
  apiKey: process.env.SITELOCALEAI_API_KEY,
  model: "gpt-4o-mini",
});

/**
 * Translate a string to the target locale.
 * The function is async because the LLM call is remote.
 */
export async function translate(text, locale) {
  const prompt = `Translate the following English text to ${locale} while preserving HTML tags and formatting.\n\n${text}`;
  const result = await ai.complete({ prompt, temperature: 0 });
  return result.text.trim();
}

Security tip – Store SITELOCALEAI_API_KEY in a .env.production file and add it to .gitignore. The key never leaves your build server.


5. Hook Into Gatsby’s Node API

Gatsby lets you create pages programmatically via gatsby-node.js. We’ll generate a page for each locale after the original page is built.

// gatsby-node.js
const path = require("path");
const { translate } = require("./src/utils/translate");

// Define the locales you want to support
const locales = [
  { code: "en", name: "English" },
  { code: "es", name: "Spanish" },
  { code: "de", name: "German" },
  { code: "fr", name: "French" },
];

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;

  // Query all pages that contain translatable content
  const result = await graphql(`
    query {
      allSitePage {
        nodes {
          path
          component
        }
      }
    }
  `);

  const pages = result.data.allSitePage.nodes;

  // Loop through each page and each locale
  for (const page of pages) {
    const originalHtml = require("fs").readFileSync(
      path.join(__dirname, "public", page.path, "index.html"),
      "utf8"
    );

    for (const locale of locales) {
      // Translate the body text only (simple regex for demo)
      const translatedBody = await translate(originalHtml, locale.code);

      const localizedPath = `/${locale.code}${page.path}`;

      createPage({
        path: localizedPath,
        component: page.component,
        context: {
          locale: locale.code,
          // Pass the translated HTML to the page component via context
          translatedHtml: translatedBody,
        },
      });
    }
  }
};

This script does three things:
1. Reads the generated HTML for each page.
2. Calls the SiteLocaleAI LLM to translate the content.
3. Creates a new page under /<locale>/… with the translated HTML baked in.

Performance note – The translation step runs at build time, not at request time, so visitors get a static file instantly.


6. Render the Translated HTML in Your Layout

Create a layout component that swaps the raw HTML with the translated version when the locale context is present.

// src/components/LocalizedLayout.jsx
import React from "react";
import { Helmet } from "react-helmet";

export default function LocalizedLayout({ children, pageContext }) {
  const { locale = "en", translatedHtml } = pageContext;

  // If we have a translation, inject it directly
  if (translatedHtml) {
    return (
      <html lang={locale}>
        <Helmet>
          <meta charSet="utf-8" />
          <title>{/* You can also translate the title via the LLM */}</title>
        </Helmet>
        <body dangerouslySetInnerHTML={{ __html: translatedHtml }} />
      </html>
    );
  }

  // Fallback to normal rendering
  return <>{children}</>;
}

Wrap your page templates with <LocalizedLayout> and Gatsby will serve the pre‑rendered translation.


7. Localize Prices with Psychological Rounding

SiteLocaleAI can also format numbers according to locale‑specific rounding rules. Add a helper:

// src/utils/price.js
export function localizePrice(amount, locale, currency) {
  // Example: round to nearest 0.99 for USD, 0.95 for EUR, etc.
  const roundingMap = {
    USD: 0.99,
    EUR: 0.95,
    GBP: 0.99,
    JPY: 1,
  };

  const factor = roundingMap[currency] || 0.99;
  const rounded = Math.floor(amount) + factor;

  return new Intl.NumberFormat(locale, {
    style: "currency",
    currency,
  }).format(rounded);
}

Use it inside your React components:

import { localizePrice } from "../utils/price";

function ProductCard({ price, currency }) {
  const { locale } = React.useContext(LocaleContext);
  const display = localizePrice(price, locale, currency);
  return <span>{display}</span>;
}

The rounding logic is fully customizable—just edit roundingMap to match your market psychology.


8. SEO Pre‑Rendering with the SiteLocaleAI CLI

SiteLocaleAI ships a CLI that can crawl your site and generate a sitemap of all locale URLs. Install it globally:

npm i -g @sitelocaleai/cli

Run the pre‑render step after gatsby build:

sitelocaleai prerender \
  --output ./public \
  --locales en,es,de,fr \
  --site-url https://yourdomain.com

The CLI:
* Fetches each localized page.
* Saves the fully rendered HTML (already done by Gatsby, but the CLI ensures correct hreflang tags).
* Updates public/sitemap.xml with every locale URL, which Google will ingest.

For more details see the official docs: https://sitelocaleai.com/docs/cli


9. Deploy

Because everything is static, you can host the public folder on any CDN—Netlify, Vercel, Cloudflare Pages, or even an S3 bucket. No Node.js runtime is required on the edge, keeping costs low.


10. Verify Google Indexing

  1. Submit the generated sitemap in Google Search Console.
  2. Use the URL Inspection tool to confirm that each locale URL returns a 200 with the translated HTML.
  3. Check the hreflang tags (the CLI adds them automatically) to ensure Google knows which language version belongs to which region.

11. Wrap‑Up & Next Steps

You now have a fully localized, SEO‑optimized Gatsby site that:
* Leverages your own LLM API keys (no third‑party data leakage).
* Serves price‑rounded, locale‑specific numbers.
* Provides static HTML for every language, guaranteeing fast load times and perfect Google indexing.

Want to explore more advanced features—dynamic locale switching, content‑type specific prompts, or integration with Shopify? The full documentation lives at https://sitelocaleai.com/docs.


Ready to boost your international traffic?

Try SiteLocaleAI for free and see how easy it is to turn any static site into a multilingual, SEO‑powerhouse.