Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

with-react-i18next fails with react-i18next 8.0.4 (latest) #5352

Closed
Nelrohd opened this issue Oct 1, 2018 · 5 comments · Fixed by #5368
Closed

with-react-i18next fails with react-i18next 8.0.4 (latest) #5352

Nelrohd opened this issue Oct 1, 2018 · 5 comments · Fixed by #5368
Labels
good first issue Easy to fix issues, good for newcomers

Comments

@Nelrohd
Copy link

Nelrohd commented Oct 1, 2018

Examples bug report

Example name

Example name is with-react-i18next.

Describe the bug

When using react-i18next v8.0.4 in the demo, we get a 500 server error:

TypeError: Cannot set property 'wait' of undefined

Note that v8.0.4 is the latest release of react-i18next at this moment.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Clone and install the example
  2. Install react-i18next with the version 8.0.4
  3. Run the example
  4. Open your browser and see the error

Expected behavior

The page should be displayed.

Screenshots

None.

System information

  • OS: macOS High Sierra Version 10.13.6
  • Browser (if applies) Google Chrome Version 69.0.3497.100 (Official Build) (64-bit)
  • Version of Next.js: latest
{
  "name": "react-i18next-nextjs-example",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "NODE_ENV=production node server.js"
  },
  "author": "",
  "license": "MIT",
  "dependencies": {
    "express": "4.16.3",
    "i18next": "11.9.0",
    "i18next-browser-languagedetector": "2.2.3",
    "i18next-express-middleware": "1.4.0",
    "i18next-node-fs-backend": "2.1.0",
    "i18next-xhr-backend": "1.5.1",
    "next": "latest",
    "react": "^16.5.2",
    "react-dom": "^16.5.2",
    "react-i18next": "8.0.4"
  }
}

Additional context

None.

@timneutkens timneutkens added help wanted good first issue Easy to fix issues, good for newcomers labels Oct 1, 2018
@ryuken
Copy link

ryuken commented Oct 1, 2018

its broken from react-i18next version 8.0.0

@jamuhl
Copy link
Contributor

jamuhl commented Oct 3, 2018

could you please try the sample here: https://github.com/i18next/react-i18next/tree/master/example/nextjs

just updated that to v8.0.6 of react-i18next

@Nelrohd
Copy link
Author

Nelrohd commented Oct 4, 2018

It works with this new update, thank you @jamuhl

@Enalmada
Copy link
Contributor

@Nelrohd I assume this issue can be closed now? (and #5368 should be merged in to prevent others from getting same error!)

@Nelrohd
Copy link
Author

Nelrohd commented Oct 11, 2018

Yes, we can close it with the merge @Enalmada ! Thank you!

timneutkens pushed a commit that referenced this issue Oct 11, 2018
Fixes #5352 . This updates the example updating react-i18next to v8.0.6, replacing the `translate` HOC to `withNamespaces` and `I18n` to `NamespacesConsumer`.

There is one thing that I am not sure if is correct or not so I need some guidance. You gotta wrap the page with the `withI18next` HOC so it will extend the `getInitialProps` of the page with this:

```
Extended.getInitialProps = async (ctx) => {
  const composedInitialProps = ComposedComponent.getInitialProps
    ? await ComposedComponent.getInitialProps(ctx)
    : {}

  const i18nInitialProps = ctx.req
    ? i18n.getInitialProps(ctx.req, namespaces)
    : {}

  return {
    ...composedInitialProps,
    ...i18nInitialProps
  }
}
```

The problem lies in `i18n.getInitialProps` that has this code:

```
i18n.getInitialProps = (req, namespaces) => {
  if (!namespaces) namespaces = i18n.options.defaultNS
  if (typeof namespaces === 'string') namespaces = [namespaces]

  req.i18n.toJSON = () => null // do not serialize i18next instance and send to client

  const initialI18nStore = {}
  req.i18n.languages.forEach((l) => {
    initialI18nStore[l] = {}
    namespaces.forEach((ns) => {
      initialI18nStore[l][ns] = (req.i18n.services.resourceStore.data[l] || {})[ns] || {}
    })
  })

  return {
    i18n: req.i18n, // use the instance on req - fixed language on request (avoid issues in race conditions with lngs of different users)
    initialI18nStore,
    initialLanguage: req.i18n.language
  }
}
```

In my understanding, among other things, it gets the `i18n` object from the request (included by the `server.js`) and uses the data to create `initialI18nStore` and `initialLanguage`, and then return these two objects plus the `i18n` object itself. If you add the `i18n` object on the return, then there will be a crash on the client-side render of the page:

```TypeError: Cannot read property 'ready' of null```

I don't know why, but returning it breaks `NamespacesConsumer` component from `react-i18next` (the state becomes null). So I commented this line and the provider on `_app.js` is getting the `i18n` instance from the `i18n.js` file (the same as `server.js`). I don't know if this would be an issue so I would like help to debug this.
@lock lock bot locked as resolved and limited conversation to collaborators Oct 11, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
good first issue Easy to fix issues, good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants