next.jsinternationalizationnext-intl

How to Suppress MISSING_MESSAGE Errors in next-intl in Next.js App?


I'm developing a Next.js app using the next-intl package for locale handling, and I am loading the locale messages from an external server. Most of the messages do not exist in my local development environment, which results in numerous MISSING_MESSAGE errors cluttering the console and making it hard to debug.

I am using next-intl version 3.25.1 and the following code is from i18n/request.js

import {getRequestConfig} from 'next-intl/server';
import { routing } from './routing';

export default getRequestConfig(async ({ requestLocale }) => {
    let locale = await requestLocale;

    if (!locale || !routing.locales.includes(locale)) {
        locale = routing.defaultLocale;
    }

    websiteUrl = websiteUrl.replace(process.env.WEBSITE_CONFIG_URL);

    const websiteResponse = await fetch(websiteUrl);
    const websiteResult = await websiteResponse.json();
    const messages = websiteResult.content;
    
    return { 
        locale, 
        messages,
        onError(error) {
            return;
        },
        getMessageFallback({error, key}) {
            return key;
        }
    };
});

This code is called because my translation are loaded from the server, I can see them in the rendering. Even though I have provided the onError function to suppress errors, the MISSING_MESSAGE errors still appear in the logs. How can I effectively prevent these specific errors from appearing in my console (terminal and browser) during development?

What I've tried:

Expected Outcome: I would like a way to filter out or suppress the MISSING_MESSAGE logs while retaining the ability to debug other important messages. The onError on NextIntlClientProvider generates error Event handlers cannot be passed to Client Component props and as I am charging server messages, this code can lot be executed on client.

Any suggestions or examples on how to solve this issue would be appreciated!


Solution

  • I found a solution, Looks like I had to divide the layout in two parts, one handeled by both the server and the client app/[locale]/layout.jsx

    import Head from "next/head";
    import { getMessages, setRequestLocale } from 'next-intl/server'
    import {notFound} from 'next/navigation';
    import {routing} from '../../i18n/routing'
    import ClientLayout from "../components/clientLayout";
    
    export default async function RootLayout({ children, params }) {
    
      const { locale } = await params
      const messages = await getMessages();
    
      if (!routing.locales.includes(locale)) {
        notFound();
      }
    
      setRequestLocale(locale);
    
      return (
        <html lang={locale} >
          <Head>
            <title>Amazing title</title>
            <meta name="description" content="Description 1234" />
            <meta charSet="UTF-8" />
          </Head>
    
          <body>
            <ClientLayout locale={locale} messages={messages} >
              {children}
            </ClientLayout>
          </body>
        </html>
      );
    }
    
    export function generateStaticParams() {
      return routing.locales.map((locale) => ({locale}));
    }
    

    And then another one only for client

    'use client'
    import { NextIntlClientProvider } from "next-intl";
    import Context from "../context";
    
    export default function ClientLayout({ children, locale, messages }) {
    
        function onError(error) {
            if (error.code === 'MISSING_MESSAGE') return;
            console.error(error)
        }
    
        return (
            <Context>
                <NextIntlClientProvider
                    locale={locale}
                    messages={messages}
                    timeZone='Europe/Paris'
                    onError={onError}
                >
                    {children}
                </NextIntlClientProvider>
            </Context>
        )
    }