1

as the title refers, is there a way to pass locale to tRPC context (other than passing it as an input from useRouter hook)?

Couldn't find any information related to i18n in the docs.

Thanks.

// src/server/router/context.ts
import * as trpc from "@trpc/server";
import * as trpcNext from "@trpc/server/adapters/next";
import { Session } from "next-auth";
import { getServerAuthSession } from "../common/get-server-auth-session";
import { prisma } from "../db/client";

type CreateContextOptions = {
  session: Session | null;
  locale: "en" | "tr";
};

export const createContextInner = async (opts: CreateContextOptions) => {
  return {
    session: opts.session,
    prisma,
    locale: opts.locale,
  };
};

export const createContext = async (
  opts: trpcNext.CreateNextContextOptions,
) => {
  const { req, res } = opts;

  // Get the session from the server using the unstable_getServerSession wrapper function
  const session = await getServerAuthSession({ req, res });
  const locale = "en" // TODO: get locale from router

  return await createContextInner({
    session,
    locale
  });
};

export type Context = trpc.inferAsyncReturnType<typeof createContext>;
Kene
  • 85
  • 1
  • 3
  • 7

1 Answers1

1

I managed to set the locale to the tRPC context by extracting it from the referer header.

// Get the referer header (example of value - http://localhost:3000/ro/settings).
export const createContext = async (opts: CreateNextContextOptions) => {
  const { req, res } = opts;

  const locale = getLocaleFromURL(req.headers.referer);

  // ...

  return await createContextInner({
    ...,
    locale,
  });
};

export const LOCALES = ["en", "ro"];
export const DEFAULT_LOCALE = "en";

export const getServerSideHostname = (url: string) => new URL(url).hostname;

// In my case, the locale can either be as a slug, or a TLD.
// If neither contain a locale, return the default locale.
export function getLocaleFromURL(url: string | undefined) {
  if (!url) return DEFAULT_LOCALE;

  const slugLocale = url.split("/")[3];
  const usingSlugLocale = LOCALES.includes(slugLocale || "");
  const topLevelDomainLocale = getServerSideHostname(url).split(".").pop();
  const usingTopLevelDomainLocale = LOCALES.includes(
    topLevelDomainLocale || ""
  );

  if (usingSlugLocale) return slugLocale!;
  if (usingTopLevelDomainLocale) return topLevelDomainLocale!;

  return DEFAULT_LOCALE;
}