Using a 'web server aware' Node library, with JavaScriptServices / NodeServices (React SPA) #515

Closed
opened 2025-08-09 17:16:35 +00:00 by fergalmoran · 0 comments
Owner

Originally created by @mcquiggd on 8/11/2017

(Although this topic specifically mentions i18next, this could equally apply to other node packages that typically expect to have access to a Node web server such as Express, and some guidance would be most helpful.)

Scenario:

I wish to integrate the Node internationalization library i18next to provide language detection (initially browser accept-language headers in the request, or url segment such as /en-GB/), client side language selection (drop down), client side persistence of selected language (cookie / local storage / Redux), caching of translation data (local storage / Redux), translation of text client side and most importantly in the pre-rendered server side environment.

Usual approach:

The normal way to do this with a fully isomorphic JavaScript app would be to use a plugin package (in this case i18next-express-middleware), that has access to the server-side request and response, to perform language detection by accessing the request context - example server.js here.

JavaScriptServices / NodeServices approach:

The actual loading of locales, and translation of text within my React components, can be achieved as normal once the i18next instance is initialised (tested this by specifying a default language).

The owner of the i18next project described the process of language detection and instance initialization as follows:

Regarding language detection (or recover via cookie, session, what ever) this has to happen inside the request code => as a sample express middleware does this on every request using the middleware: https://github.com/i18next/i18next-express-middleware/blob/master/src/index.js#L23

From there you:
a) create a fixedT function to use inside request: https://www.i18next.com/api.html#getfixedt
b) create a new clone of main instance and change language on that: https://www.i18next.com/api.html#cloneinstance --> https://github.com/i18next/i18next-express-middleware/blob/master/src/index.js#L13 (on line 30 is the changeLanguage call)

However, it seems to me that NodeServices execution context has no knowledge of the web environment itself, other than the data that is passed to it via the asp-prerender-data tag helper.

So, it also seems to me that any examination of the web request has to be performed in the .Net Core pipeline, with relevant parameters determined.

This would then be passed from the controller (e.g. Home/Index) to the corresponding view that contains asp-prerender-module tag and use asp-prerender-data to pass along these parameters, which can then be accessed in the server-boot.ts module. Here, I would use them to initialise the i18next instance, and allow its provider to supply locales to my components as normal, as they are rendered by NodeServices / WebPack.

Then, I should pass data - the language detected via ASP.Net Core, the locale json data loaded from the server filesystem - back to the client via the globals return 'type', as is currently done with initial state for Redux. This would then be attached the data to the window object on the client side, and could be persisted into local storage to allow i18next to take over and work as normal from then on.

Questions:

  1. Is my understanding of the Kestrel > AspNet Core > NodeServices flow, and that NodeServices is essentially a non-web aware Node context, correct?

  2. The advice from the owner of i18next to 'clone the main instance of i18next, and change the language on that', is to ensure each request receives its own instance, with its own language detection result. I am presuming that this is only required due to Node / Express, and that in the JavaScriptServices / NodeServices framework, each request would have its own isolated Node context?

  3. It's not clear to me exactly how NodeServices interacts with WebPack to return transpiled output to the browser, or how that pipeline is arranged. Is there an in-depth explanation somewhere of the full interaction of each component in a typical lifecycle?

  4. Does the team have any guidance in terms of internationalization, in the current JavaScriptServices / NodeServices framework?

Many thanks for any feedback...

*Originally created by @mcquiggd on 8/11/2017* (Although this topic specifically mentions i18next, this could equally apply to other node packages that typically expect to have access to a Node web server such as Express, and some guidance would be most helpful.) **Scenario:** I wish to integrate the Node internationalization library `i18next` to provide language detection (initially browser accept-language headers in the request, or url segment such as /en-GB/), client side language selection (drop down), client side persistence of selected language (cookie / local storage / Redux), caching of translation data (local storage / Redux), translation of text client side and most importantly in the pre-rendered server side environment. **Usual approach:** The normal way to do this with a fully isomorphic JavaScript app would be to use a plugin package (in this case `i18next-express-middleware`), that has access to the server-side request and response, to perform language detection by accessing the request context - [example server.js here](https://github.com/i18next/react-i18next/blob/master/example/nextjs/server.js). **JavaScriptServices / NodeServices approach:** The actual loading of locales, and translation of text within my React components, can be achieved as normal once the i18next instance is initialised (tested this by specifying a default language). The owner of the i18next project described the process of language detection and instance initialization as follows: > Regarding language detection (or recover via cookie, session, what ever) this has to happen inside the request code => as a sample express middleware does this on every request using the middleware: https://github.com/i18next/i18next-express-middleware/blob/master/src/index.js#L23 > > From there you: > a) create a fixedT function to use inside request: https://www.i18next.com/api.html#getfixedt > b) create a new clone of main instance and change language on that: https://www.i18next.com/api.html#cloneinstance --> https://github.com/i18next/i18next-express-middleware/blob/master/src/index.js#L13 (on line 30 is the changeLanguage call) However, it seems to me that NodeServices execution context has no knowledge of the web environment itself, other than the data that is passed to it via the `asp-prerender-data` tag helper. So, it also seems to me that any examination of the web request has to be performed in the .Net Core pipeline, with relevant parameters determined. This would then be passed from the controller (e.g. Home/Index) to the corresponding view that contains `asp-prerender-module` tag and use `asp-prerender-data` to pass along these parameters, which can then be accessed in the `server-boot.ts` module. Here, I would use them to initialise the i18next instance, and allow its provider to supply locales to my components as normal, as they are rendered by NodeServices / WebPack. Then, I should pass data - the language detected via ASP.Net Core, the locale json data loaded from the server filesystem - back to the client via the globals return 'type', as is currently done with initial state for Redux. This would then be attached the data to the window object on the client side, and could be persisted into local storage to allow i18next to take over and work as normal from then on. **Questions**: 1. Is my understanding of the Kestrel > AspNet Core > NodeServices flow, and that NodeServices is essentially a non-web aware Node context, correct? 2. The advice from the owner of i18next to 'clone the main instance of i18next, and change the language on that', is to ensure each request receives its own instance, with its own language detection result. I am presuming that this is only required due to Node / Express, and that in the JavaScriptServices / NodeServices framework, each request would have its own isolated Node context? 3. It's not clear to me exactly how NodeServices interacts with WebPack to return transpiled output to the browser, or how that pipeline is arranged. Is there an in-depth explanation somewhere of the full interaction of each component in a typical lifecycle? 4. Does the team have any guidance in terms of internationalization, in the current JavaScriptServices / NodeServices framework? Many thanks for any feedback...
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/JavaScriptServices#515
No description provided.