next.jsinternationalizationi18nextnextjs14

NotFound not working on Next.js 14.x, i18NextJs


I'm working with i18NextJs in a Next.js 14 that uses the App router and next-i18n-router. My NotFound pages, both the custom and default ones, are not working as expected. I'm seeing an error about missing <html> and <body> tags in my RootLayout component, but I can’t seem to resolve it. I've tried several adjustments, but nothing seems to work.

Got this error message:
Missing required html tags The following tags are missing in the Root Layout: <html>, <body>. Read more at https://nextjs.org/docs/messages/missing-root-layout-tags

Error image:

i18NextJs NotFound not working : Missing required html tags
The following tags are missing in the Root Layout: , .
Read more at https://nextjs.org/docs/messages/missing-root-layout-tags

Server error log:

✓ Compiled /favicon.ico in 77ms
 ⚠ ./middleware.ts
Unable to parse config export in source file
The exported configuration object in a source file need to have a very specific format from which some properties can be statically parsed at compiled-time.

layout.tsx it hasn’t used 'use client'

interface RootLayoutProps {
  children: React.ReactNode;
  params: {
    locale: string;
  };
}

export default function RootLayout({
  children,
  params: { locale },
}: Readonly<RootLayoutProps>) {
  if (!i18nConfig.locales.includes(locale)) {
    notFound();
  }
  return (
    <html lang={locale} className="light scroll-smooth" dir={dir(locale)}>
      <body
        className={`${poppins.variable} font-poppins text-[15px] text-slate-900 dark:text-white dark:bg-slate-900`}
      >
        {children}
      </body>
    </html>
  );
}

Also, tried this:

export default function RootLayout({
  children,
  params: { locale },
}: Readonly<RootLayoutProps>) {

  if (!i18nConfig.locales.includes(locale)) {
    notFound();
  }

  return (
    <html lang={locale} className="light scroll-smooth" dir={dir(locale)}>
      <body
        className={`${poppins.variable} font-poppins text-[15px] text-slate-900 dark:text-white dark:bg-slate-900`}
      >
        {children}
      </body>
    </html>
  );
}

i18nConfig.ts

const i18nConfig = {
  locales: ["en", "ar"],
  defaultLocale: "en",
  prefixDefault: true,
};

export default i18nConfig;

i18n.ts

import { createInstance } from "i18next";
import { initReactI18next } from "react-i18next/initReactI18next";
import resourcesToBackend from "i18next-resources-to-backend";
import i18nConfig from "@/i18nConfig";

export default async function initTranslations(
  locale: any,
  namespaces: any,
  i18nInstance: any,
  resources: any
) {
  i18nInstance = i18nInstance || createInstance();

  i18nInstance.use(initReactI18next);

  if (!resources) {
    i18nInstance.use(
      resourcesToBackend(
        (language: any, namespace: any) =>
          import(`@/locales/${language}/${namespace}.json`)
      )
    );
  }

  await i18nInstance.init({
    lng: locale,
    resources,
    fallbackLng: i18nConfig.defaultLocale,
    supportedLngs: i18nConfig.locales,
    defaultNS: namespaces[0],
    fallbackNS: namespaces[0],
    ns: namespaces,
    preload: resources ? [] : i18nConfig.locales,
  });

  return {
    i18n: i18nInstance,
    resources: i18nInstance.services.resourceStore.data,
    t: i18nInstance.t,
  };
}

middleware.tsx

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { i18nRouter } from "next-i18n-router";
import i18nConfig from "./i18nConfig";

export function middleware(request: NextRequest) {
  const response = i18nRouter(request, i18nConfig);
  return response;
}

export const config = {
  matcher: ["/((?!api|static|.*\\..*|_next).*)", { source: "/" }],
};

Files & Folders Arch.

i18NextJs NotFound not working : Missing required html tags
The following tags are missing in the Root Layout: , .
Read more at https://nextjs.org/docs/messages/missing-root-layout-tags - App router

package.json

"dependencies": {
    "i18next": "^23.16.4",
    "i18next-resources-to-backend": "^1.2.1",
    "next-i18n-router": "^5.5.1",
    "react-i18next": "^15.1.0",
    "next": "14.2.16"
}

How can I resolve this issue?


Solution

  • To solve using Catch-all Segments. [...notFound] under the [locale] directory. it will catch any invalid routes, such as /en/some-unknown-path, and properly return a 404 / Custome NotFound Page.

    files and folders arch.

    - app
      |- [locale]
          |- [...notFound]
              |- page.tsx   // catch-all segment
          |- layout.tsx     // layout component for different locales
    - middleware.ts         // middleware for handling localization
    

    page.tsx:

     import { notFound } from "next/navigation";
    
    const CatchAll = () => {
      return notFound();
    };
    
    export default CatchAll;