Internationalization

Introduction

The customer web app has a preconfigured internationalization to support multiple languages that you need in your app. The template uses the next-intl library https://next-intl-docs.vercel.app/ . Right now the template only the highlights the usage of this library on the landing page. The only relevant files and folders for internationalization purposes are

  • apps/web-app/src/config.ts

  • apps/web-app/src/middleware.ts

  • apps/web-app/src/navigation.ts

  • apps/web-app/messages

  • apps/web-app/src/components/locale-switcher.tsx

How it works in a nutshell

NextJS will pull all language translations inside the messages folder as a server side component and then store all of those language translations in a global context

apps/web-app/src/app/[locale]/layout.tsx
export default async function LocaleLayout({
  children,
  params: { locale },
}: {
  children: React.ReactNode;
  params: { locale: string };
}) {
  const messages = await getMessages();

  return (
    <html
      suppressHydrationWarning={true}
      className="!scroll-smooth bg-dark"
      lang={locale}
    >
      <head />
      <body>
        <NextIntlClientProvider messages={messages}>
          <Providers>
            {children}
            <ScrollTop />
          </Providers>
        </NextIntlClientProvider>
      </body>
    </html>
  );
}

So that once you need that language translation, you can easily use it using this way

apps/web-app/messages/en.json
{
  "Index": {},
  "Hero": {
    "description": "<strong>TheNextStartup</strong> is an open-source template designed with scalability in mind, providing a swift pathway to launch your startup. It ensures high engineering quality while being cost-effective, making it an ideal choice for aspiring entrepreneurs.",
    "starOnGithub": "<star>Star it on</star><github>Github</github>",
    "getStarted": "Get Started"
  },
  "BuiltWith": {
    "supercharge": "Supercharge Your Business With Batteries"
  },
  "LocaleSwitcher": {
    "label": "Change language",
    "locale": "{locale, select, jp {πŸ‡―πŸ‡΅ Japanese} en {πŸ‡ΊπŸ‡Έ English} other {Unknown}}"
  }
}
apps/web-app/src/components/hero.tsx
  const t = useTranslations('Hero');

  return (
    <section
      id="hero"
      className={`flex flex-col bg-gradient-to-b from-yellow-800 dark:via-neutral-900 via-neutral-300 dark:to-black to-white sm:py-16 py-6`}
    >
      <div
        className={`flex-1 flex items-center flex-col xl:px-0 sm:px-16 pt-12 m-10 xl:m-10 justify-center text-center`}
      >
        <h1 className="p-10 bg-gradient-to-r dark:from-white from-black dark:to-zinc-400 to-neutral-700 bg-clip-text text-transparent flex-1 font-lexend font-semibold ss:text-[72px] text-[50px] lg:text-[72px] ss:leading-[100.8px] lg:leading-[90px]">
          The <label className="font-pacifico">Next</label> Startup
        </h1>
        <p className="font-notoSans mt-4 lg:text-base text-sm dark:text-white text-black line-clamp-3 lg:px-48">
          {t.rich('description', {
            strong: (chunks) => <strong>{chunks}</strong>,
          })}
        </p>
      </div>
      

Last updated