Internalization - how to get 'lang' parameter for custom React components

Hello!

I am currently working on multi-language feature on my website. As a guideline, I followed the following tutorial / resource:

  • Creating custom React components Header and Navbar and fetch links data from Settings custom type, based on this Youtube tutorial
  • Add internalization to my NextJs project based on this blog.

Everything works well, and I was able to get my website running with a different locale (My default locale is en-us, and I'm working on a different locale zh-tw)

Now the problem is: The Navbar does not change when I change the language . The Navbar is supposed to get the content data from the Settings custom type, but seems like even when I already changed the language, the the project is still fetching the Settings from the default en-us locale instead of the zh-tw.

Note that my Navbar component is neither a Slice nor a Page type within Prismic. It's just a custom React component, as created like this Youtube tutorial

Based on the steps listed in this blog, I noticed that the page.tsx is updated to accept the lang parameter like so:

type Params = { uid: string; lang: string };
export default async function Page({ params }: { params: Params }) {
  const client = createClient();
	// ⬇️ Note this line with the `lang` parameter being passed in
  const page = await client
    .getByUID('page', params.uid, {
      lang: params.lang,
    })
    .catch(() => notFound());

  return <SliceZone slices={page.data.slices} components={components} />;
}

My understanding is that it fetches the lang parameter from the routing based on the [lang] directory. (I'm still new to this, so please correct me if I'm wrong!)

Now this is what my original code look like for the Header custom component:

import NavBar from "@/components/NavBar";
import { createClient } from "@/prismicio";

export default async function Header() {
const client = createClient();
const settings = await client.getSingle("settings");

  return (
    <header>
      <NavBar settings={settings}/>
    </header>
  )
}

And for the Navbar custom component:

"use client"

import { Content } from '@prismicio/client';
import { PrismicNextLink } from '@prismicio/next';
import Link from 'next/link';


type NavBarProps = {
  settings: Content.SettingsDocument;
} 

export default function NavBar({settings}: NavBarProps) {

  return (
    <div>
        <Link href="/">{settings.data.site_title}</Link>
          <ul>
            {settings.data.navigation.map(({ link, label }) => (
              <li key={label}>
                <PrismicNextLink field={link}> 
                  {label}
                </PrismicNextLink>
              </li>
            ))}
          </ul>
    </div>
  )
}

And I render my Header component in the app/[lang]/layout.tsx file.

import "./globals.css";
import { PrismicPreview } from "@prismicio/next";
import { repositoryName } from "@/prismicio";
import Header from "@/components/Header";

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>
        <Header />
        {children}
      </body>
      <PrismicPreview repositoryName={repositoryName} />
    </html>
  );
}

I've tried the following approaches but didn't work:

  • Moved the Header and NavBar component to app/[lang]
  • Modify the Header component so it become like so:
import NavBar from "@/components/NavBar";
import { createClient } from "@/prismicio";

type Params = { lang: string }

export default async function Header({ params }: { params: Params }) {
const client = createClient();
const settings = await client.getSingle("settings", { lang: params.lang );

  return (
    <header>
      <NavBar settings={settings}/>
    </header>
  )
}

Is there a way so that this custom Header component can somehow get the lang parameter just like it was done in page.tsx file? Or if I totally get the whole approach wrong, what's the correct approach?

Thank you!

We have a sample project that we don't officially list in the technical docs but it has the functionality that you're trying to achieve. You might find it useful: GitHub - prismicio-community/nextjs-starter-prismic-multi-language: Multi-language project with Next.js & Prismic

Hi @Pau ,

Thank you very much, I figured it out based on the sample project!

1 Like