next-i18next: [8.0.0-beta.4] Error when using postProcessors

Hi, first of all, thanks for this plugin, yours and the community’s efforts ❤️

Describe the bug

I’m unable to use an i18next postprocessor - here sprintf-postProcessor-, similar to this comment, any use config parameter seems to trigger the following error when trying to start the next application (using next command):

SerializableError: Error serializing ._nextI18Next.userConfig.use[0].process returned from getStaticProps in “/”. Reason: function cannot be serialized as JSON. Please only return JSON serializable data types.

Occurs in next-i18next version

next-18next version: 8.0.0-beta.4 - c3dcef1f2c3510fa6eb2fd5c3fad42ab717964f6

Steps to reproduce

  • Checkout c3dcef1f2c3510fa6eb2fd5c3fad42ab717964f6 in this repository
  • Apply “Reproducible patch” bellow
  • Run yarn run-example
Reproducible patch from c3dcef1f2c3510fa6eb2fd5c3fad42ab717964f6
diff --git a/examples/simple/next-i18next.config.js b/examples/simple/next-i18next.config.js
new file mode 100644
index 0000000..5366457
--- /dev/null
+++ b/examples/simple/next-i18next.config.js
@@ -0,0 +1,6 @@
+const sprintf = require("i18next-sprintf-postprocessor");
+
+module.exports = {
+  postProcess: "sprintf",
+  use: [sprintf],
+};
diff --git a/examples/simple/package.json b/examples/simple/package.json
index be9e52c..83c434f 100644
--- a/examples/simple/package.json
+++ b/examples/simple/package.json
@@ -10,6 +10,7 @@
   },
   "dependencies": {
     "next": "^10.0.0",
+    "i18next-sprintf-postprocessor": "latest",
     "next-i18next": "link:../../"
   },
   "devDependencies": {

Expected behaviour

There should be no errors and I should be able to translate using any backend/plugin

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 1
  • Comments: 55 (55 by maintainers)

Most upvoted comments

Fixed via a serializeConfig option in #972.

Unfortunately, publicRuntimeConfig has performance implications and cannot be considered. Please check the docs:

A page that relies on publicRuntimeConfig must use getInitialProps to opt-out of Automatic Static Optimization. Runtime configuration won’t be available to any page (or component in a page) without getInitialProps.

Your proposed solution is:

  1. Maintain a convention of next-i18next.config.js file
  2. Continue to import next-i18next.config.js file inside serverSideTranslations to save users some trouble
  3. Require users to import their next-i18next.config.js file in _app and pass as an argument.

Correct? I think we have indeed talked in circles a little bit here, but @LeonardDrs’s point about closures and imported dependencies is pretty conclusive. I don’t think we’re going to find a way around that.

@LeonardDrs I don’t understand this:

It bothers me a bit that every pages are going to require the configuration solely for the purpose of server/build-side. The client-side page.js file will have a “useless” import of a configuration object. Unless we specify that the config import/require needs to be located in the getStaticProps/getServerSideProps functions?

I agree with you @isaachinman and I’m curious as to what will happen with Next plugins. To be honest I think the dream is that a framework API is so simple and nice that Plugins don’t need a “plugin API”. We’ve kinda seen this with Next, but I guess people are finding more and more complex use cases that it’s needed now.

Well unless somehow the module could import ../../next-i18next.config.js in appWithTranslations and serverSideTranslations, I feel like your pr https://github.com/isaachinman/next-i18next/pull/930 is the way to go.

Edit: Actually, unless I’m missing something @filipesmedeiros, your PR only require the consumer to pass the config (if any) once, in _app.tsx like so:

import type { AppProps } from "next/app";

import i18nextConfig from "next-i18next.config";
import { appWithTranslation } from "next-i18next";

const App: React.FC<AppProps> = ({ Component, pageProps }) => {
    ....
};

export default appWithTranslation(i18nextConfig)(App);

since the serverSideTranslations already requires the userConfig:

const DEFAULT_CONFIG_PATH = './next-i18next.config.js';
...
if (fs.existsSync(path.resolve(DEFAULT_CONFIG_PATH))) {
    userConfig = await import(path.resolve(DEFAULT_CONFIG_PATH));
}

so… all good?

Yeah I agree

but now I’m feeling that this could be a Next responsibility since they are the ones serializing props, but I don’t know if they would be keen on implementing it. Especialy since it may be wrong to share instances/functions this way?

I think maybe we should focus on creating a nice/easy way to make config shareable on the app side, and not on ours

Somewhat related to #930. I wonder if @filipesmedeiros has an opinion on how we might best avoid all these serialisation errors?