
Paraglide JS
Tool
Paraglide JS is the ideal i18n library for Astro's content-focused sites.
It's a compiler-based i18n library that emits tree-shakable translations, leading to up to 70% smaller i18n bundle sizes compared to runtime based libraries.
- Fully type-safe with IDE autocomplete
- SEO-friendly localized URLs with the i18n routing strategy
- Works with CSR and SSR
[!NOTE] SSG is not yet supported out of the box. You can integrate Paraglide JS yourself to achieve SSG. PR with an example is welcome.
Setup
1. If you have not initialized Paraglide JS yet, run:
npx @inlang/paraglide-js@latest init
2. Add the vite plugin to the astro.config.mjs file and set output to server:
import { defineConfig } from "astro/config";
+import { paraglideVitePlugin } from "@inlang/paraglide-js";
+import node from "@astrojs/node";
export default defineConfig({
// ... other
+ vite: {
+ plugins: [
+ paraglideVitePlugin({
+ project: "./project.inlang",
+ outdir: "./src/paraglide",
+ }),
+ ],
},
+ output: "server",
+ adapter: node({ mode: "standalone" }),
});
3. Create or add the paraglide js server middleware to the src/middleware.ts file:
import { paraglideMiddleware } from "./paraglide/server.js";
export const onRequest = defineMiddleware((context, next) => {
+ return paraglideMiddleware(context.request, ({ request }) => next(request));
});
You can read more about about Astro's middleware here.
Usage
import { m } from "./paraglide/messages.js";
import { getLocale, getTextDirection, setLocale } from "./paraglide/runtime.js";
// Use messages
m.greeting({ name: "World" }); // "Hello World!"
// Get and set locale
getLocale(); // "en"
getTextDirection(); // "ltr" | "rtl" for current locale
setLocale("de"); // switches to German
Learn more about messages, parameters, and locale management →
Disabling AsyncLocalStorage
If you're deploying Astro to Vercel Edge or to Cloudflare Workers with Node.js compatibility enabled, keep AsyncLocalStorage enabled. Those runtimes support it today, so disableAsyncLocalStorage is no longer part of the recommended setup.
disableAsyncLocalStorage remains available as a compatibility fallback for runtimes that do not provide AsyncLocalStorage or node:async_hooks but still isolate each request.
[!WARNING] Only use this fallback when your runtime guarantees per-request isolation. Using it in a multi-request server environment could leak locale state between concurrent requests.
See AsyncLocalStorage in the Middleware Guide if you need that escape hatch.