NextJS + React Router - partially SSR app - reactjs

I want to make partially SSR web application and looking for best solution for that. I need SSR for SEO and that will only serve dynamically rendered products pages - this will be handled by NextJS.
Other part of the app is only for logged users and I don't want anybody not logged to accidentally display it (but only users data have to be secure, if anyone access by a hack those restricted pages without any user data that's ok) - for that part I've already implemented React Router with proper redirections and few routes (it's using Redux too).
Whole project was made with create-react-app. Is there a way to easily combine those two functionalities? Do I have to move everything from /src to /pages? Maybe best way would be to serve them independently and just redirect to one or another using Apache configuration?

If anybody wonders about it - currently the best solution would be to use NextJS for all of it, cause Next provides a clean way to handle static pages, CSR and SSR alongside each other.
By the default all pages are static generated or pre-rendered with partial CSR, while using getServerSideProps method allows to handle SSR, without any extra configuration.

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!

Conditionally Run SSR or CSR using React

I currently have a website that uses SSR (using nextJS) to render the landing page in the root directory. However, I want the website to render my create-react-app application when the user is logged in. When the user is logged out, I want the website to show the landing page.
So my question is, is it possible to conditionally render using SSR when logged out, and use CSR when logged in? I'm just looking for general guidance on how to build the architecture that handles such event.
(The reason why I use SSR is for SEO reasons. My app doesn't need SEO so I want to use CSR instead. I also want to avoid using subdomains for now.)
It is possible with two options below:
(Recommended) Create a proxy server (just another Node server on top of your SSR and CSR servers), and implement the logic to proxy requests to either SSR or CSR in different cases. Or,
Create a custom Next server and route any logged-in requests to CSR. However, this option will sacrifice some major Next features.

Deep Linking in React without React-Native or React-Navigation

I have a request from a client to implement deep linking in our React application whereby clicking a link will take them directly into the installed app (potentially to a certain point but not sure on that yet).
To my understanding react-native and react-navigation both handle this as part of a feature set within "Linking" that they offer. However it seems excessive to import a framework just for deep linking (perhaps not though).
After googling I can only really find references to deep linking on react-native or react-navigation.
What is my best course of action?
Let's get to some basics first, then it will be clear.
In modern SPA's, say with React, it's common for the SPA to handle navigation itself. You need to use browser's history API. It's because your SPA is just a single index.html with bunch of js code, so it sort of virtual, every page is constructed by your app. In order to not reinvent a wheel, its easier to use some library for that, say react-router-dom.
But then everything works as expected, and you have deployed your app. When user wants to get some deep page, say, https://my-awesome-app.com/deep/page/1, browser will just send a request to a server, asking: "Please, server, give me a page 1.html, in folder page, in folder deep". But server doesn't have that file, because it has literally one index.html, because its a SPA application. Then we need to tell the server to re-write all deep routes to index html, here is an example for my app hosted on Netlify:
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
When user will ask for that page, server will 'redirect' that request to the index.html and my react-router-dom will figure out which 'PageComponent' to render based on that path.
So, you can implement routing in your app yourself, probably using browser's History API, but I guess it might be easier to use library. But it's your call.
On the other hand if your app is not an SPA, the story might be different, because say in NextJS routing is implemented in framework itself, and if used deep linking would require different setup depending on how app is deployed.
Deep-linking is handled largely by Apple and Google server-side
https://www.adjust.com/blog/dive-into-deeplinking/
React-native provides extended functionality for deep-linking within mobile apps but normal web-applications there is no need to implement it there. Use universal links or Google specific links as standard linking within your web app to enable deep linking

How to use create-react-app to develop multiple pages?

When creating an app with create-react-app,there is only one index.html,does that means React can only handle one SPA at a time? What if I want to develop multiple pages? Should I create another SPA with create-react-app and then put them together after building each of them?
Update:
Parceljs can do that. here is docs.
You can use Parcel instead of Webpack (which being used in create-react-app) and it provide you zero config environment to develop web apps (using react or anything else).
Having multiple pages (instead of SPA) is not what most React environments had in mind [before - see update above].
You can have different page URL's using react-router or similar client side routing solutions.
If the concern is bundle size, there are solutions using webpack or parcel to lazy load each bundle whenever they needed or cache bundle (using service workers) and so on (Tree shaking, ...). (check Code Splitting in React Docs)
Other concern I might have in my brain is SEO, in this case you may find Isomorphic app (react server side rendering) useful which initialize first view of requested URL HTML and sends it to client, then client will load react and react will take control of UI. This will help Google (or other search engines) find your URLs fast and user experience in transitions between pages will remain seamless.

server-side react-router without being isomorphic

In my web app, I don't want to use hash-based routing, I don't want to see any # appear in my URLs. I want to use RESTful URLs, e.g., http://www.example.com/blog/id.
react-router can deal with client-side routing quite well, but if a user hit enter on the browser address bar or refresh the page, the request will be sent to the web server and then the web server has to understand the URL and handle the routing.
Isomorphic is a good solution to this situation since it can render any page on both client-side and server-side. Actually there are many react starter kit projects on Github which claim to be isomorphic.
In my opinion, isomorphic looks beautiful but it's too expensive to write code: you need to make you react components render successfully both on client-side and server-side, which needs developers to make great efforts.
So here is my question, can I just make the react-router be isomorphic, not the entire code?
Yes. You can use react-router for a purely front-end (non-ismorphic) app with HTML5 history.
The routing is determined client side, so react-router will spit out the expected page.
However, whilst you don't need to write any server side code, you will need to configure the web server to point your routes to the correct place. This usually means pointing every single request - or every single valid request - to the same HTML file or entry point. Exactly how you do this depends on what you're using to serve your pages - Express, Apache etc.
I hope that makes sense.

Resources