Blog>
Snippets

Handling Redirects Based on the User's Locale

Code an example of a middleware function in Next.js 14 that performs redirects based on the user's preferred locale.
import { NextResponse } from 'next/server';

export function middleware(request) {
  // Obtain the user's locale from the request headers or default to 'en'
  const defaultLocale = 'en';
  const preferredLocale = request.headers.get('accept-language')?.split(',')[0].substring(0, 2) || defaultLocale;

  // Define redirects based on the user's locale
  const localeRedirects = {
    'en': '/en',
    'es': '/es',
    'fr': '/fr',
    // Add more locales and paths as needed
  };

  // The URL the user is trying to access
  const url = request.nextUrl.clone();

  // Redirect user if there's a path for their locale
  if (localeRedirects[preferredLocale] && !url.pathname.startsWith(`/${preferredLocale}`)) {
    url.pathname = `${localeRedirects[preferredLocale]}${url.pathname}`;
    return NextResponse.redirect(url);
  }

  // Proceed with the request if no redirection is needed
  return NextResponse.next();
}
This Next.js middleware function intercepts incoming requests and redirects users to a path based on their preferred locale, which is determined by parsing the 'accept-language' header. If a match is found in the defined locale redirects object, the user gets redirected accordingly. If the user's locale is not in the map or the user is already on the localized path, no redirect occurs.
const redirectBasedOnLocale = (locales, defaultLocale = 'en') => (req, res, next) => {
  const { 'accept-language': acceptLanguage } = req.headers;
  const userLocale = acceptLanguage ? acceptLanguage.split(',')[0].substring(0, 2) : defaultLocale;

  if (locales.includes(userLocale) && !req.originalUrl.startsWith(`/${userLocale}`)) {
    const redirectTo = `/${userLocale}${req.originalUrl}`;
    return res.redirect(redirectTo);
  }

  return next();
};

// Example usage in a Node.js/Express app
// app.use(redirectBasedOnLocale(['en', 'es', 'fr']));
This Node.js/Express middleware function checks the 'accept-language' header to determine the user's preferred locale and redirects them to a corresponding path, if available. It does not perform a redirect if the user is already on a localized path or if their preferred locale is not supported.