Search code examples
reactjstypescriptnext.jsnext.js14next-intl

How to navigate when using `Next-intl` and `next/link`


I implemented a next-intl for multi-language support. So my paths look like www.next.com/de or www.next.com/en

I'm using NextJS 14.

<NextLink href="/support-us">{t("About us")}</NextLink>

And when I want to navigate to for example /support-us it must navigate me to /en/support-us instead I get to /support-us so it throws an error.

NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.

Here is my code. middleware.ts

import createMiddleware from "next-intl/middleware";
import { locales } from "./i18n";

export default createMiddleware({
  // A list of all locales that are supported
  locales,

  // Used when no locale matches
  defaultLocale: "en",
});

export const config = {
  // Match only internationalized pathnames
  matcher: ["/", "/(en|it|de|nl|fr|sv|es|nb|pt|pl)/:path*"],
};

i18next

import { notFound } from "next/navigation";
import { getRequestConfig } from "next-intl/server";

interface Language {
  symbol: string;
  name: string;
}

export const supportedLanguages: Language[] = [
  { symbol: "EN", name: "English" },
  { symbol: "DE", name: "Deutsch" },

];

const languageSymbolsLowercase: string[] = supportedLanguages.map((lang) =>
  lang.symbol.toLowerCase()
);

const initialLocales: string[] = [];

const combinedLocales: string[] = [
  ...initialLocales,
  ...languageSymbolsLowercase,
];

export const locales: string[] = combinedLocales;

export default getRequestConfig(async ({ locale }) => {
  if (!locales.includes(locale)) notFound();

  return {
    messages: (await import(`../messages/${locale}.json`)).default,
  };
});

Solution

  • At the end I had to add a navigation file as mentioned in the next-intl documentation in there it exports a Link component which solves the problem and navigates to /[locale]/support-us
    for example /en/support-us here is my navigation file

    import {
      createLocalizedPathnamesNavigation,
      Pathnames,
    } from "next-intl/navigation";
    import { locales } from "./i18n";
    
    export const localePrefix = "always"; // Default
    
    export const pathnames = {
      "/support-us": "/support-us",
    } satisfies Pathnames<typeof locales>;
    
    export const { Link, redirect, usePathname, useRouter, getPathname } =
      createLocalizedPathnamesNavigation({ locales, localePrefix, pathnames });
    

    And use the Link exported in the navigation file

    import { Link as NavLink } from "@navigation"
    <NavLink href="/support-us">{t("support us")}</NavLink>