
Paraglide JS
ToolparaglideMiddleware()
paraglideMiddleware<
T>(request,resolve,callbacks?):Promise<Response>
Defined in: server/middleware.js:102
Server middleware that handles locale-based routing and request processing.
This middleware performs several key functions:
- Determines the locale for the incoming request using configured strategies
- Handles URL localization and redirects (only for document requests)
- Maintains locale state using AsyncLocalStorage to prevent request interference
When URL strategy is used:
- The locale is extracted from the URL for all request types
- If URL doesn't match the determined locale, redirects to localized URL (only for document requests)
- De-localizes URLs before passing to server (e.g.,
/fr/about→/about)
Type Parameters
T
T
The return type of the resolve function
Parameters
request
Request
The incoming request object
resolve
(args) => T | Promise<T>
Function to handle the request. The callback receives:
request: A modified request with a delocalized URL when the URL strategy is used (e.g.,/fr/about→/about). If your framework handles URL localization itself (e.g., TanStack Router'srewriteoption), use the original request instead to avoid redirect loops.locale: The determined locale for this request.
callbacks?
Callbacks to handle events from middleware
onRedirect
(response) => void
Returns
Promise<Response>
See
https://inlang.com/m/gerre34r/library-inlang-paraglideJs/middleware
Examples
// Basic usage in metaframeworks like NextJS, SvelteKit, Astro, Nuxt, etc.
export const handle = async ({ event, resolve }) => {
return paraglideMiddleware(event.request, ({ request, locale }) => {
// let the framework further resolve the request
return resolve(request);
});
};
// Usage in a framework like Express JS or Hono
app.use(async (req, res, next) => {
const result = await paraglideMiddleware(req, ({ request, locale }) => {
// If a redirect happens this won't be called
return next(request);
});
});
// Usage in serverless environments like Cloudflare Workers
// ⚠️ WARNING: This should ONLY be used in serverless environments like Cloudflare Workers.
// Disabling AsyncLocalStorage in traditional server environments risks cross-request pollution where state from
// one request could leak into another concurrent request.
export default {
fetch: async (request) => {
return paraglideMiddleware(
request,
({ request, locale }) => handleRequest(request, locale),
{ disableAsyncLocalStorage: true }
);
}
};
// Usage with frameworks that handle URL localization/delocalization themselves
//
// Some frameworks like TanStack Router handle URL localization and delocalization
// themselves via their own rewrite APIs (e.g., `rewrite.input`/`rewrite.output`).
//
// When the framework handles this, the middleware's URL delocalization is not needed.
// Using the modified `request` from the callback would cause a redirect loop because
// both the middleware and the framework would attempt to delocalize the URL.
//
// Solution: Pass the original request to the handler instead of the modified one.
// The middleware still handles locale detection, cookies, and AsyncLocalStorage context.
//
// ❌ WRONG - causes redirect loop when framework handles URL rewriting:
// paraglideMiddleware(req, ({ request }) => handler.fetch(request))
//
// ✅ CORRECT - use original request when framework handles URL localization:
// paraglideMiddleware(req, () => handler.fetch(req))
import { paraglideMiddleware } from './paraglide/server.js'
import handler from '@tanstack/react-start/server-entry'
export default {
fetch(req: Request): Promise<Response> {
// TanStack Router handles URL rewriting via deLocalizeUrl/localizeUrl
// so we pass the original `req` instead of the modified `request`
return paraglideMiddleware(req, () => handler.fetch(req))
},
}