product icon

Paraglide JS

App

Server Side Rendering

Paraglide JS provides first-class support for server-side rendering (SSR) through its paraglideMiddleware() and async context management.

Using paraglideMiddleware()

The paraglideMiddleware() handles request-scoped locale management automatically:

import { paraglideMiddleware } from './paraglide/server.js';

// In your request handler:
const response = await paraglideMiddleware(request, async ({ request, locale }) => {
  // Your request handling logic here
  return new Response(`Current locale: ${locale}`);
});

Key features:

  • Automatically manages async local storage context
  • Handles URL localization/delocalization
  • Ensures locale state isolation between requests

Automatic re-directs

The paraglideMiddleware() automatically re-directs requests to the appropriate localized URL.

For example, assume that the cookie strategy preceeds the url strategy. If a request from a client is made where the client's locale cookie is set to de, the paraglideMiddleware() will re-direct the request from https://example.com/page to https://example.com/de/seite.

await compile({
  project: "./project.inlang",
  outdir: "./src/paraglide",
+  strategy: ['cookie', 'url'],
})

If the automatic redirects are not desired, you can increase the precedence of the url strategy:

await compile({
  project: "./project.inlang",
  outdir: "./src/paraglide",
-  strategy: ['cookie', 'url'],
+  strategy: ['url', 'cookie'],
})

Disabling Async Local Storage

You can use disableAsyncLocalStorage: true to disable the use of Node.js' AsyncLocalStorage. Paraglide JS uses Node.js' AsyncLocalStorage to maintain request context isolation. This is crucial for:

  • Preventing locale information from leaking between concurrent requests
  • Ensuring consistent URL origin resolution
  • Maintaining a clean separation of request-specific state
Disabling AsyncLocalStorage is **only safe** in these environments:
  • Cloudflare Workers
  • Vercel Edge Functions
  • AWS Lambda (single-request mode)
  • Other isolated runtime contexts
// Only disable in serverless environments
paraglideMiddleware(request, handler, { 
  disableAsyncLocalStorage: true // ⚠️ Use with caution
})

Best Practices

  1. Always enable AsyncLocalStorage for:

    • Traditional Node.js servers
    • Docker containers handling multiple requests
    • Any environment with request pooling
  2. Test isolation by making parallel requests:

// Test that locale doesn't leak between requests
await Promise.all([
  fetch('/fr/about'),
  fetch('/de/contact')
])
  1. Monitor for these warning signs:

    • Random locale switches during load testing
    • Incorrect URL origins in logs
    • Session data appearing in wrong requests

Serverless Environments

For edge functions and serverless platforms, you can use per-request overrides because each request is isolated:

// Cloudflare Worker example
export default {
  async fetch(request: Request) {
    // Determine locale from request
    const locale = getLocaleFromURL(request.url);
    
    // Override per-request
    overwriteGetLocale(() => locale);
    overwriteGetUrlOrigin(() => new URL(request.url).origin);

    return handleRequest(request);
  }
};

// Next.js Edge Middleware
import { NextResponse } from 'next/server';

export function middleware(request) {
  const locale = getLocaleFromCookie(request);
  
  overwriteGetLocale(() => locale);
  overwriteGetUrlOrigin(() => request.nextUrl.origin);

  return NextResponse.next();
}