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

Multiple namespaces not rendering on client. #199

Closed
karltaylor opened this issue Aug 24, 2016 · 19 comments
Closed

Multiple namespaces not rendering on client. #199

karltaylor opened this issue Aug 24, 2016 · 19 comments

Comments

@karltaylor
Copy link

karltaylor commented Aug 24, 2016

I have my common.json file being pulled into Jade template files which are working fine, but I can add another namespace and have it work correctly, it keeps getting overwritten, and the resources is not added within the window.__i18n object.

Here's my i18n-server.js

import i18n from 'i18next'
import Backend from 'i18next-node-fs-backend'
import { LanguageDetector } from 'i18next-express-middleware'

i18n
  .use(Backend)
  .use(LanguageDetector)
  .init({
    whitelist: ['en'],
    fallbackLng: 'en',

    // have a common namespace used around the full app
    ns: [
      'common',
      'homepage'
    ],
    defaultNS: 'common',

    debug: true,

    interpolation: {
      escapeValue: false // not needed for react!!
    },

    backend: {
      loadPath: 'locales/{{lng}}/{{ns}}.json',
      jsonIndent: 2
    }
  })

export default i18n

and the i18n-client.js

import i18n from 'i18next'

i18n
  .init({
    whitelist: ['en'],
    fallbackLng: 'en',

    // have a common namespace used around the full app
    ns: [
      'common',
      'homepage'
    ],
    defaultNS: 'common',

    interpolation: {
      escapeValue: false // not needed for react!!
    }
  })

export default i18n

I also have this within my client.js file

i18n.changeLanguage(window.__i18n.locale)
i18n.addResourceBundle(window.__i18n.locale, 'common', window.__i18n.resources, true)

ReactDOM.render(
  <I18nextProvider i18n={i18n}>
    <Router history={browserHistory}>
      { Routes }
    </Router>
  </I18nextProvider>,
  document.getElementById('app-container')
)

And this is my server.js file

  const locale = req.language
  const resources = i18n.getResourceBundle(locale, 'common')
  const i18nClient = {locale, resources}

  const i18nServer = i18n.cloneInstance()
  i18nServer.changeLanguage(locale)

And i18n is picking up my homepage.json file and it renders in the jade file (as =t('homepage:test.title') at first but then gets overwritten because it's not in the window.__i18n resources. What am I missing!

@jamuhl
Copy link
Member

jamuhl commented Aug 24, 2016

what is window.__i18n ?!?

and why you use the node backend on the client? change that to the xhr backend...

@karltaylor
Copy link
Author

Sorry @jamuhl I got those code blocks muddled up. I've fixed them.

window.__i18n is passed in the client, I'm taking this from the https://github.com/simpleblack/react-redux-universal-hot-example.

Apologies if this isn't the correct place!

Within the client.js the window.__i18n is passed through and then in the html.js it's loaded into the html.

@jamuhl
Copy link
Member

jamuhl commented Aug 24, 2016

const resources = i18n.getResourceBundle(locale, 'common')

is resources filled with the needed translations? might be that was assigned before backend loaded resources?

else idk...rather sure the window.__i18n.resources is empty...you will need to console.log that...

@karltaylor
Copy link
Author

karltaylor commented Aug 24, 2016

console.log(resources) logs out my common.json. Do i need to passed multiple namespaces? Sorry if i'm not making sense! Bit out of my depth!

I checked this issue and it seems to similar to what I'm experiencing!

@jamuhl
Copy link
Member

jamuhl commented Aug 24, 2016

i'm not much into this...but if your page uses the namespace homepage then you need to add that too. Or you need to add the xhr backend and let the client take care of loading the resources.

@jamuhl
Copy link
Member

jamuhl commented Sep 15, 2016

closing this as i expect it to be solved - otherwise feel free to reopen.

@jamuhl jamuhl closed this as completed Sep 15, 2016
@davidfurlong
Copy link

davidfurlong commented Feb 22, 2017

I'm finding the examples quite lacking in this regard / the universal hot render example is clearly avoiding this issue to get it to work.

i18n.addResourceBundle(window.__i18n.locale, 'AccountForm', window.__i18n.resources, true);

client & server need updated ns

import i18n from 'i18next';

i18n
  .init({
...
    ns: ['common', 'AccountForm']
  });

export default i18n;

on server need to do some sort of accumulation of resources, unfortunately clearly not integrated with react-router so any collisions across namespaces are kindof unavoidable, unless you assign based on namespaces (which would make much more sense)

const resources = Object.assign({},
    i18n.getResourceBundle(locale, 'common'),
    i18n.getResourceBundle(locale, 'AccountForm')
  );

@jamuhl
Copy link
Member

jamuhl commented Feb 22, 2017

like mentioned earlier...personally i do not have a project that uses universal rendering - as we do not profit of that (authorization, websockets, ...).

But i would love someone taking the time to make a improved example: but looking at https://github.com/ipatate/UniversalAppReact/blob/master/package.json might be good starting point?

Suggestions are welcome to improve...

@davidfurlong
Copy link

davidfurlong commented Feb 22, 2017

To be honest I looked at that project and it also doesn't solve the issue of translation splitting. I'm likely to just write my own library - as this one doesn't seem to architecturally tie a namespace to a react component (which is something I'd like, and would make integration with something like react-router much easier)

@jamuhl
Copy link
Member

jamuhl commented Feb 22, 2017

Cool...would be great to see you're version - you plan to write a wrapper around i18next - or icu format? Send me a link to your repo as soon as possible...thank you.

@davidfurlong
Copy link

davidfurlong commented Feb 22, 2017 via email

@jamuhl
Copy link
Member

jamuhl commented Feb 22, 2017

looking forward to it...

@tricoder42
Copy link

@davidfurlong I'm dealing with the same problem if I understood you correctly. I've just written down my ideas in js-lingui repo (link above). I would appreciate your comments or suggestions.

@davidfurlong
Copy link

davidfurlong commented Feb 22, 2017

@tricoder42 Yes, so I wrote a little (very naive) way of doing that isn't good enough (https://github.com/davidfurlong/react-local-translations) - as I was trying to avoid having to add more API surface area on my react code. But I am totally on board with what you are saying.

If local CSS is a good idea, then surely so is local translation files. Ofcourse having a build process to unify them would be useful for handing to translators (this is a pain with local translations), but it also means that you can add / remove components really quickly and not worry about global namespace. It also solves the issue of having huge translation files being loaded into your bundle. I tried using this repo and (without benchmarking) I could see a noticeable performance hit, so I'm trying to keep what I build minimal (for the vast majority of translations, things like pluralization or other helper utilities aren't needed).

I'm about to start writing a basic version of this, and I think it'll be pretty quick. But I'm still uncertain of what i18n library to use

@davidfurlong
Copy link

davidfurlong commented Feb 22, 2017

@tricoder42 Why did you decide to use react components to wrap translations rather than using either a key or functions? - I think passing the choice of how to structure the either string or react component should be passed along into the individual translations

Also heads up example-usecase link on the readme is broken link https://github.com/lingui/js-lingui/blob/master/packages/example-usecase/src/Usecase.js

@davidfurlong
Copy link

Also thanks for writing js-lingui it looks much more minimal and along the lines of what I was looking for

@jamuhl
Copy link
Member

jamuhl commented Feb 22, 2017

What we basically do in our projects (and those are huge user applications managing access control) is we pass down a t function to components consumed from our shared libraries - as we manage namespace files using locize.com service - we do not have to create them multiple time...but this might be luxury.

@jamuhl
Copy link
Member

jamuhl commented Feb 22, 2017

and agree i18next might be a little bigger in size - as it's more than a translation function (backend, cache, lng-detection, flexibility) all comes with a price - but the benefit is - i18next will be usable when nobody will use react anymore - as the next better framework arised ;)

and don't get me wrong...i like what @tricoder42 did with js-lingui. Use whatever suits your need best.

@tricoder42
Copy link

@davidfurlong Don't want to hijack this thread, so I answered your question here: lingui/js-lingui#15

Also, thanks for the report. Readme is fixed now 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants