TanStackT
TanStack13mo ago
1 reply
good-rose

i18n

What's the best way to implement a redirect rule in a subsection of the website /$lang/... whereby I get the language from logged in user / cookies / request and redirect to that the /$lang/... equivalent route if it's different from the parameter?

Example


User navigates directly to /fr/a/b/c but user is logged in and their language is en. The code should redirect to /en/a/b/c.

Use case


Language is inferred from: 1) logged in user, 2) language cookie, 3) accept-language header in this order. I need this rule for when a link is shared from other websites which may be localized differently and I want it to automatically localize it for the given user.

What have I tried?


I tried to have this layout route:

import { getViewerQuery } from "~/client/queries/use-viewer";
import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";

export const Route = createFileRoute("/$lang")({
  component: Layout,
  loader: async ({ context, params, location }) => {
    const [viewer] = await Promise.all([
      context.queryClient.ensureQueryData(getViewerQuery),
    ]);

    if (viewer.language !== params.lang) {
      const langRegex = new RegExp(`^/(${params.lang})(\/|$)`);
      const pathnameWithoutLang = location.pathname.replace(
        langRegex,
        `/${viewer.language}/`
      );
      const newUrl = `${pathnameWithoutLang}${location.searchStr}`;
      throw redirect({ to: newUrl, resetScroll: false });
    }
  },
});

function Layout() {
  return <Outlet />;
}


but I've just realised this only runs once when loading the layout but then every route change within /$lang/... (e.g. from /en/a to /en/b) will not trigger the loader.

This currently doesn't work if I trigger a client navigation. It does work if the page is reloaded though.
Was this page helpful?