Search code examples
next.jsnext.js13react-intlapp-routerformatjs

Getting "createContext only works in Client Components" while using createIntl


I'm using NextJS 13 with the app router. In a server action I'm trying to obtain localized text. For this I've created the following function:

import { createIntl, createIntlCache, IntlShape } from "react-intl";
import { SupportedLocale } from "@/types/locale";

const cache = createIntlCache();

export const getIntlForBackend = (locale: SupportedLocale): IntlShape => {
  return createIntl(
    {
      locale,
      defaultLocale: SupportedLocale.SPANISH,
      messages: {},
    },
    cache
  );
};

My understanding is that createIntl is made for these types of scenarios (backend code in which React context is not available.

From https://formatjs.io/docs/react-intl/api): createIntl: In a non-React environment (Node, vue, angular, testing... you name it), you can directly create a intl object by calling this function with the same configuration as the IntlProvider.

Despite this I'm getting the following error:

Unhandled Runtime Error Error: createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/context-in-server-component

I've traced the calls from the start of the server action until this function is called, and I'm sure it's this that is causing it.

For example I can replace

const intl = getIntlForBackend(locale);

with

const intl = {
  formatMessage: (a: any, b: any) => "testing",
};

and no longer get the error and the code in the server action completes successfully.

Any tips on what could be happening? Ty!


Solution

  • The issue here was that you shouldn't import from react-intl but from @formatjs/intl:

    import { createIntl, createIntlCache, IntlShape } from "@formatjs/intl";