SSR and localization - reactjs

I ran into a problem that I have never faced before developing a PWA with translations.
I state that I have always and only developed multilingual applications in Vue, React, Angular, and at the moment I am using Svelte.
I have always used simple practices, translation with a json dictionary and sending the Lang variable to the server for data acquisition in the requested language (set in the Headers).
All of this was fine until I encountered the need to receive the translated meta tags for the requested content immediately, during SSR, upon landing on the page. But as you know, at this stage there is no access to localStorage or similar, which is why it is impossible for me to acquire the meta tags in the requested language, since I do not have access to the variable set in the browser. How do you act in this case? I'm not interested in finding a specific solution for a certain framework, but a possible technique.
For Svelte I found this half solution, which allows me to obtain the slug / lang / from the address and use it in the server during the rendering phase, in order to obtain the data already translated on the server side.
Can I consider this a good solution?

I don't know what are you returning from the API, but if you have localized user defined content on backend, then this solution is good. If you are translating the app itself, you maybe you can give Tolgee a try, which supports SSR. https://tolgee.io/integrations/svelte

Related

How to set dynamic metatags in ReactJS to get nice share links?

The app
The application was made using ReactJS, React Router Dom, Styled Components and Redux ducks.
The backend we consume is also made by us using Amazon Amplify and GraphQL.
The goal
We need to define the meta tags of one of the application pages so that it is possible to share personalized links to users
in social networks using OpenGraphic meta tags and the like.
The problem
The project was made in ReactJS and ReactJS has only one HTML page as root (/public/index.html), in this way, everything is generated with Javascript in a root tag, and when it arrives in the browser it is transpiled, as we already know. The problem is that the crawlers responsible for understanding the meta tags are not able to understand Javascript and end up not finding the dynamic data that I am defining on the page that I need to share the link on. They understand that there is one html file and only.
Attempts to resolve the issue
1) Define the meta tags in the /public/index.html file itself
This solution doesn't work because the data we are using is dynamic and the index.html file is a static file
2) Using react-helmet
The solution allows meta tags to be defined, but as already mentioned, crawlers don't understand JS. So, despite being on the page, the meta tags do not appear when sharing the link.
3) Using some SSR technology
This is a possible solution, but we were unable to integrate any SSR Framework into React. And it is not feasible to change the base technology of the project. We can't just switch from React to Next, for example, as the project is already complete.
4) Using a small server made with express.js along with the React application to replace the meta tags in index.html with string.replace() simulating something like an SSR
This solution works, but it causes two requests to be made every time the page is accessed, once by express.js and once on the front-end side by React. Due to the number of requests increasing, this solution was discarded. But if necessary, you can do it. In this case it is also necessary to check if Amplify can keep the application and the small server running in the same project.
5) Using react-snap with react-helmet
React-snap allows you to create html snapshots of the pages of a React project based on their routes and links, this added to react-helmet generates a perfect solution for links to be treated well by web crawlers when they are shared. But the solution doesn't work with dynamic routes. For example, /your-route/:id is a dynamic route that expects an id to be fully defined. React-snap gets lost when trying to create a snapshot of a route that only exists when the id is set. Unfortunately, this solution doesn't work.
These were the solutions we used to try to solve the problem, but it was not possible yet. Probably attempt 4 would be the most ideal to solve the problem. But we are looking for the best way that will not generate reworks and future problems. If someone knows a better way to do that, would help us a lot!

Headless SPA Server Side approach with Content Management Sysstem

I am evaluating how is it possible to implement Server Side Rendering in SPA app with React and CMS as backend.
This is the approach I see Next.js suggest to have per-rendered and all most all CMS system suggests:
User request a page from react app running on Node server
Node server requests JSON data from CMS through fetch call
Then React App reads this JSON and transform HTML into String like renderToString() and sends the response back to the user.
The disadvantage of this approach is that if JSON data from CMS is huge then first request takes long time.
What alternate solution do you suggest?
Heyooo, Contentful DevRel here. 👋🏻
your concerns are absolutely valid.
And that's why Next.js just recently added advanced static pre-generation using getStaticProps. The goal is to tackle the long dynamic response times by pre-generating as much as possible. This way the user has a fast initial content paint, but can still enjoy all the dynamic benefits that come with a React application (Next.js usually follows an isomorphic JavaScript architecture)
The processing time you describe then is moved from dynamic request/response time into build-processes.
In general, when you're not dealing with millions of pages, I recommend giving static HTML a try. It makes applications often faster, safer, and more secure. For more complext and larger sites, Vercel is also experimenting with hybrid solutions that offer ways to only pre-generate certain pages. That's all very new though. :)

Multilanguage with ReactJS

I want to integrate i18n within a ReactJS application that renders on client-side only.
I can handle the internationalization itself with one of the several i18n libraries available, however I was wondering which would be the best way/available options to store whatever language the user has chosen cross-request (like refreshing the page).
Is this something I can handle on the client-side only or do I have to do it server-side and then pass it to the client?
Thank you very much in advance.
You have limited options with storing a users preference using client side technology. Essentially, you are limited to storing these preferences in a cookie.
Any other sort of persisted data should be handled by the server and most likely saved to a database somewhere.

Sharing constants between Django and angular

I'm working with a SPA web app with Django backend and Angular frontend. Sharing constants like enums (eg. Django model field choices, error codes/messages) has always been a struggle. Is there an easy way to handle them?
I was thinking about generating a JSON that contains every constant in the project, which is created on the backend (maybe during collectstatic), what can be loaded in a <script>tag during page load as a JSONP object. The JSON resource name could look like const.XXXX.json where XXXX is the md5 sum of the file itself, so it can be cached and updated easily. The problem is that this would mean a lot of code change in Django.
Or maybe creating a repo which contains the shared constants, and bump it in both in the backend and frontend. But This would also mean a complete rewire. Maybe with this approach, I could make use of the IDE highlight both server and client side.
But both approaches take a relatively lot of effort and code change, so I thought I'll ask before jumping into it.
I've seen examples in php, Java, etc. But not for Django (and Angular).

Trying to understand how an isomorphic react app is supposed to do client-side routing

Pardon my English, it is a second language. The whole point of an isomorphic app, as opposed to a regular client-side SPA is so the client doesn't have to download the whole JS file initially which results in really slow initial load time.
I've been trying to teach myself server-side rendered React, and after watching countless videos around the concept and following countless tutorials on the actual implementation, I still can't get my head around this (at least this is how I understand it):
Despite the server conditionally rendering pages and sending props to the client on url change, the client side still uses a router that includes all the entry points for the app (by requiring all of them, and then loading the file based on the url location). Doesn't that means all the files are included in the main client JS file anyways since it's already been required by the client-side router? Doesn't that defeat the whole purpose of server-rendered React? Or am I thinking about this the wrong way?
In short, how does an isomorphic React app really works with a client-side router that includes (by requiring them) all of the app's entry points?
I'm not sure that "The whole point of an isomorphic app [...] is so the client doesn't have to download the whole JS file initially which results in really slow initial load time" is necessarily true. I think the primary reason people do this is for SEO reasons and to improve perceived load time. You still get the benefit of showing the users the page before they have to load all the JavaScript (e.g. yes, they have to load all the JS, but it's OK because they already have most/all of the content). The app upgrades to an SPA transparently, providing a seamless experience for the user.
That said, you can implement a system where you don't have to load all the JS at once with something like webpack's code splitting. There's even a simple React Router example that does this.

Resources