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

Is fetching translations from API possible? #537

Closed
mercteil opened this issue Oct 25, 2019 · 9 comments
Closed

Is fetching translations from API possible? #537

mercteil opened this issue Oct 25, 2019 · 9 comments

Comments

@mercteil
Copy link

I would like to dynamically fetch my translation from a backend API prior sending the page to my client.

Unfortunately it is not clear for me where I should parse and set the translations?

I thought about writing a middleware to parse and set languages on each request to the server, but I am not sure if this would be a proper pattern to follow or should I fetch translations on the client side, which again would go against HMR.

Does anyone has experience with fetching translations on the server side prior sending the page to the client? Or am I missing it in all the docs...?

@AleVul
Copy link

AleVul commented Oct 28, 2019

I dont think currently is possible to do this, see this. Basically on the server (i.e.: when doing ssr) this library will read files from local file system.

Only way i see it is to propose a "remote" path for server side in config, maybe a flag?

@isaachinman
Copy link
Contributor

It's absolutely possible, and has been discussed numerous times in this repository.

See #336, #163, #169, etc.

@AleVul
Copy link

AleVul commented Oct 29, 2019

@isaachinman i see your point with build time suggestion in combination with web hook to rebuild the app, but there are cases where that is not viable/possible.
So my suggestion for @mercteil is to fork this repo and change backends to fetch data from remote API at runtime.

@isaachinman
Copy link
Contributor

I think that both storing localisation data on the filesystem or in memory can be appropriate, depending on your situation.

It is not, however, appropriate to make a network request for localisation data for each application request. Users will need to implement their own caching strategies.

I don't think maintaining a fork would be necessary - all that needs to be removed and/or made flexible are the filesystem lookups. Outside of that, the i18next world is already set up to consume locales over network.

@mercteil
Copy link
Author

mercteil commented Oct 31, 2019

Thank you for your replies. I took a look at the suggested (closed) issues and they mostly deal with the client API fetching (as I understood).

I was expecting to have the translations ready on my server either prior the client's request (would be the build step) or during the server rendering prior sending the translations to the client (would be some kind of a middleware or similar).

So far this would be my best fit response from @isaachinman
As a build step, writing to the filesystem, in my opinion........

The problem hereby is at every translations/texts change I would have to rebuild my front-end, which is suboptimal. That means the best solution for me would be to fetch either in an express middleware or in the App.getInitialProps.isServer step .... this also means I have to deal with concurrent write operations to the file system. Thus again the best fit is the build step ... and every change to the translations would mean an application rebuild.

PS: I currently load the translations in my redux store on every initial response during hydration on the server side and send it to the client. changeLanguage() on the other hand rehydrates the store on the client's side only.

@isaachinman
Copy link
Contributor

It's possible to do this both as a build step and as a runtime cache. Implementation is up to you!

@mercteil
Copy link
Author

mercteil commented Nov 1, 2019

I faced the issue fetching translations during the build step that I would have to rebuild my application each time my translations change (every typo change in the translations would force me to rebulid my application)

So in order to have my translations as static files locally on the server I would have to fetch the translations after the build and prior the server instance.

/server.js

/* eslint no-console: 0 */
const next = require('next');
const translationsMiddleware = require('./translationsMiddleware');
const routes = require('./routes');
const serverInstance = require('./server');

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV === 'development';
const app = next({ dev });

const routesHandler = routes.getRequestHandler(app);

app
  .prepare()
  .then(translationsMiddleware) // fetch the translations and write to FS before instantiating the server
  .then(... server instance)
  .catch(ex => {
    console.error(ex.stack);
    process.exit(1);
  });

/translationsMiddleware.js

...

const {
  config: { allLanguages = ['en'] },
} = require('../i18n');

...

module.exports = async () => {
     ...  = await getTranslationsByLang(lang);

    if (status === 200) {
      const mappedTranslations = translationsMapper(lang, content);
      fs.writeFileSync(localeFilePath(lang), JSON.stringify(mappedTranslations));
    }
  }
};

All I need to do in order to update my translations in the locales folder is to restart the server... no rebuild, no backend requests, all files locally in the locales folder

You pay with the little downtimes during restart....

@mercteil mercteil closed this as completed Nov 1, 2019
@dimisus
Copy link

dimisus commented Nov 5, 2019

The prebuild step is the only proper way to fetch translations. Fetching on server start only works if build is not needed (example in dev mode). Best way is to write a prebuild script which fetches translations prior the next build command.

@mercteil
Copy link
Author

mercteil commented Nov 5, 2019

Exactly the issue we had. Moved fetching translations to the prebuild step.

Fetching on start does not work when build is necessary.

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