remix-i18next: remix-i18next does not provide an export named 'RemixI18Next'

Describe the bug

i dont see any errors in vscode but when starting yarn dev i get these errors:

SyntaxError: The requested module 'remix-i18next' does not provide an export named 'RemixI18Next'
/Users/revnandi/Documents/repos/epick-stack/build/index.js:141
import { RemixI18Next } from "remix-i18next";
SyntaxError: The requested module 'remix-i18next' does not provide an export named 'RemixI18Next'
    at ModuleJob._instantiate (node:internal/modules/esm/module_job:122:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:188:5)
    at async CustomizedModuleLoader.import (node:internal/modules/esm/loader:246:24)
    at <anonymous> (/Users/revnandi/Documents/repos/epick-stack/index.js:20:2)

the i18next.server.ts file:

import Backend from 'i18next-fs-backend'
import { resolve } from 'node:path'
import { RemixI18Next } from 'remix-i18next'
import i18n from './i18n.ts'; // your i18n configuration file

let i18next = new RemixI18Next({
  detection: {
    supportedLanguages: i18n.supportedLngs,
    fallbackLanguage: i18n.fallbackLng,
  },
  // This is the configuration for i18next used
  // when translating messages server-side only
  i18next: {
    ...i18n,
    backend: {
      loadPath: resolve('./public/locales/{{lng}}/{{ns}}.json'),
    },
  },
  // The i18next plugins you want RemixI18next to use for `i18n.getFixedT` inside loaders and actions.
  // E.g. The Backend plugin for loading translations from the file system
  // Tip: You could pass `resources` to the `i18next` configuration and avoid a backend here
  plugins: [Backend],
});

export default i18next;

Your Example Website or App

wip, based on https://github.com/epicweb-dev/epic-stack

Steps to Reproduce the Bug or Issue

  1. install package
  2. add configuration
  3. yarn dev

Expected behavior

There should not be any error, remix-i18next exports ‘RemixI18Next’

Screenshots or Videos

No response

Platform

OS: macOS Ventura Browser: Chrome Version: remix 1.19.1, remix-i18next: 5.3.0

Additional context

No response

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 8
  • Comments: 28 (6 by maintainers)

Commits related to this issue

Most upvoted comments

If you are using a brand new Remix (v2.X) it is now ESM by default and this library doesn’t work well with that right now.

You should add it to your serverDependenciesToBundle in your remix.config.js file:

/**
 * @type {import('@remix-run/dev').AppConfig}
 */
export default {
  cacheDirectory: "./node_modules/.cache/remix",
  ignoredRouteFiles: ["**/*"],
  //...
  serverDependenciesToBundle: [
    "remix-i18next",
    "accept-language-parser",
  ],
  serverModuleFormat: "esm",
  serverPlatform: "node",
  // ...
};

Or you could convert your whole app back to CJS like @T0mThomson is proposing, but I think it is a bit extreme.

  1. In package.json set type to commonjs:

    "type": "commonjs",

  2. Edit remix.config.js and replace “export default {” with “module.exports = {”. Then add the line serverModuleFormat: "cjs".

    Example:

/** @type {import('@remix-run/dev').AppConfig} */

// Change "export default {" to "module.exports = {"
module.exports = {

 ignoredRouteFiles: ["**/.*"],
 // appDirectory: "app",
 // assetsBuildDirectory: "public/build",
 // serverBuildPath: "build/index.js",
 // publicPath: "/build/",

 // Add this line:
 serverModuleFormat: "cjs"
};

It is working on 2.0.1 with

  serverDependenciesToBundle: [
    "remix-i18next",
    "accept-language-parser",
  ],

I also add to install intl-parse-accept-language package

Hi, same here. This happend when i migrate my remix project to use v2_dev: true and set my config to use esm modules instead. I have just tried to add remix-i18next to serverDependenciesToBundle and it worked just fine!

Still have the issue with remix@2.0.0.

I already made a pull request. You need to update your server-side configuration In your entry.server.tsx replace the code with this:

import { PassThrough } from "stream";
import { createReadableStreamFromReadable, type EntryContext } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import isbot from "isbot";
import { renderToPipeableStream } from "react-dom/server";
import { createInstance } from "i18next";
import i18next from "./i18next.server";
import { I18nextProvider, initReactI18next } from "react-i18next";
import Backend from "i18next-fs-backend";
import i18n from "./i18n"; // your i18n configuration file
import { resolve } from "node:path";

const ABORT_DELAY = 5000;

export default async function handleRequest(
  request: Request,
  responseStatusCode: number,
  responseHeaders: Headers,
  remixContext: EntryContext
) {
  let callbackName = isbot(request.headers.get("user-agent"))
    ? "onAllReady"
    : "onShellReady";

  let instance = createInstance();
  let lng = await i18next.getLocale(request);
  let ns = i18next.getRouteNamespaces(remixContext);

  await instance
    .use(initReactI18next) // Tell our instance to use react-i18next
    .use(Backend) // Setup our backend
    .init({
      ...i18n, // spread the configuration
      lng, // The locale we detected above
      ns, // The namespaces the routes about to render wants to use
      backend: { loadPath: resolve("./public/locales/{{lng}}/{{ns}}.json") },
    });

  return new Promise((resolve, reject) => {
    let didError = false;

    let { pipe, abort } = renderToPipeableStream(
      <I18nextProvider i18n={instance}>
        <RemixServer context={remixContext} url={request.url} />
      </I18nextProvider>,
      {
        [callbackName]: () => {
          const body = new PassThrough();
          const stream = createReadableStreamFromReadable(body);

          responseHeaders.set("Content-Type", "text/html");

          resolve(
            new Response(stream, {
              headers: responseHeaders,
              status: didError ? 500 : responseStatusCode,
            })
          );

          pipe(body);
        },
        onShellError(error: unknown) {
          reject(error);
        },
        onError(error: unknown) {
          didError = true;

          console.error(error);
        },
      }
    );

    setTimeout(abort, ABORT_DELAY);
  });
}

Also in package.json set type to commonjs:

 > `"type": "commonjs",`

And lastly edit remix.config.js and replace “export default {” with “module.exports = {”. Then add the line serverModuleFormat: "cjs".

Example:

/** @type {import('@remix-run/dev').AppConfig} */

// Change "export default {" to "module.exports = {"
module.exports = {

 ignoredRouteFiles: ["**/.*"],
 // appDirectory: "app",
 // assetsBuildDirectory: "public/build",
 // serverBuildPath: "build/index.js",
 // publicPath: "/build/",

 // Add this line:
 serverModuleFormat: "cjs"
};

This will only work in remix 2.0.0

I’ve figured it out on my own the same way @sergiodxa did, it works.

For those looking for an instant solution:

// import { getInitialNamespaces } from "remix-i18next"; 
// import { useChangeLanguage } from "remix-i18next";
// import { RemixI18Next } from "remix-i18next";

// Instead use with the exact corresponding package export

import { getInitialNamespaces } from "remix-i18next/client";
import { useChangeLanguage } from "remix-i18next/react";
import { RemixI18Next } from "remix-i18next/server";

@eliawk the moduleResolution is only required since v6 because it’s using package.json exports key to define each path (remix-i18next/server, remix-i18next/react and remix-i18next/client), and TS can’t find them correctly without that setting.

@eliawk check if you have moduleResolution set to Bundler, that’s required to TS to find the /react module

In my case, the issue: Cannot find module 'remix-i18next/server' or its corresponding type declarations.ts(2307) is gone if I set "moduleResolution": "Bundler" in tsconfig.json file. Or if you use i18next.server.ts you should rename it to i18next.server.js.

Ok I just tried a newly created Remix + Vite application and setup remix-i18next without any issue, here’s the archived repo with the app code https://github.com/sergiodxa/remix-vite-i18next for anyone interested.

If your app doesn’t work compare with this app.

Still have the issue with remix@2.0.0.

It’s still broken according to https://publint.dev/remix-i18next@5.4.0.

Hi, same here. This happend when i migrate my remix project to use v2_dev: true and set my config to use esm modules instead. I have just tried to add remix-i18next to serverDependenciesToBundle and it worked just fine!

adding to serverDependenciesToBundle worked, thanks

hi, @revnandi similar issue happened to me just 10mins ago. I use pnpm and the following is the output after the fresh install

file://{filetoPath}/build/index.js:22
import { RemixI18Next } from "remix-i18next";
         ^^^^^^^^^^^^
SyntaxError: Named export 'RemixI18Next' not found. The requested module 'remix-i18next' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'remix-i18next';
const { RemixI18Next } = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:124:21)
    at ModuleJob.run (node:internal/modules/esm/module_job:190:5)

I reinstalled remix-i18next with the version “^5.0.0”. It is working now without an issue.