React App - Include /health - Health Endpoint for Load Balancer - reactjs

I have a React Application and I wish to deploy this behind a load balancer, where the load balancer periodically pings the app to see whether it's healthy. My requirement is to provide a /health endpoint, that can be used for health checking.
What would be the ideal way to implement a health endpoint?
This is something that is required for anyone planning to deploy a React App in a auto-healing fashion
The main page of this App is /dashboard, which is a heavy page. Hence, it cannot be used as a health endpoint.
i.e: I have seen react apps which have /hello kind of endpoints which return a simple message like I am healthy.

I will be answering my own question. After some considerable amount of research and asking around from experienced React developers, the following is the used approach for Including a health endpoint in React Applications.
This requirement came up when containerising the React App to be used in a Kubernetes Environment.
Do NOT ever try to use an existing page as your health check endpoint. Because, your regular pages are heavy and healthcheck endpoints need to be simple.
Hence, create a new route with /health (or a preferable path) and return a simple HTML element. given below is a Simple Route component.
<Route path="/health">
<h3>Hey There!!! The App is Healthy</h3>
</Route>
This being used in a Routes.js file, is given below.
import React from 'react';
import { Switch, Redirect, Route } from 'react-router-dom';
const Routes = () => {
return (
<Switch>
{/* This endpoint will just return you to a dummy HTML with a simple heading tag */}
<Route path="/health">
<h3>Hey There!!! The App is Healthy</h3>
</Route>
{/* All other routes will be defined here */}
{/* Finally you will be redirected to a not found page */}
<Redirect to="/not-found" />
</Switch>
);
};
export default Routes;

The answer above will work but the health endpoint will contain all of the index.html content which is technically unnecessary for the health endpoint.
A much better approach is just adding a file called health in the public folder. Then, when /health is called, the service will return the content of the file, which is faster and much smaller.

Related

How to route NextJS page to SPA (Single Page Application)

I am building a SaaS application using Next JS. I am wishing to take advantage of SSG for SEO on landing pages, pricing etc. However for the actual application I am wishing to use a SPA since its highly interactive and do not wish to use SSR (at least initially) since I have more past experience with SPA (and don't want the server costs to begin).
My desire is to have https://example.com/ (in pages folder) render the SPA (route to SPA/index.tsx which is the default create react app entry point) if the user is logged in.
essentially:
pages/index.tsx
imports...
export default function Home() {
if (isLoggedIn) {
route to SPA
}
return <LandingPage>
}
Example file structure
Pages
index.tsx
_app.tsx
_document.tsx
dashboard
SPA
index.tsx
App.tsx
Any advice or help on how to do this would be great.
Thank you :)
Solution I ended up using was to use a subdomain.
E.g. host the next app with landing pages etc on example.com and then host the react app on app.example.com. Once a user signs in redirect them to app.example.com which still has access to the auth session.

Best way to render dynamic sitemap - react

I am a beginner in react and I have made a portfolio website using react frontend.
I wanted to add a dynamic sitemap to the application and almost tried every possible way given on youtube, stackoverflow and google. But, I couldn't do what I wanted like if I add a new portfolio, it will not be there in the sitemap.
Things I already tried:-
At first, I added a sitemap.xml file in the public folder with all static contents but there was the same problem, I had to build whole application everytime I add a portfolio and also I will have to manually change the sitemap.
I also tried react-snap and react-snap-sitemap together which mostly worked but then, for some pages, I don't know why but the css stopped working. Mostly it happened with the pages which I didn't want in the sitemap or I didn't want them to be crawled.
Then, I also tried a way where there was a sitemap-generator.js which we would have to run to create a sitemap.xml file in the build folder, but then, we would have to build it again and again, and a bigger issue was that it used babel scripts which was giving errors.
Then I finally found out react-dynamic-sitemap which works almost perfectly but the issue is that it is rendering the component Sitemap and not a file sitemap.xml.
So, the xml content is displayed as text.
I also found out ways to display it as xml content but I was unable to do so.
I assume that this sitemap could not be submitted to google and also, this is not working as purely dynamic.
Because, for the portfolio details pages, I have to pass slugs in the slugs parameter like this: [{id: "foo"}, {id: "bar"}]. I tried to bring these from the database but even if I use .then() and then load the Routes after the portfolios data is fetched from the server, it gives error as it has to be loaded in other Sitemap component till then.
Code for react-dynamic-sitemap:-
Sitemap.js
import React from "react";
import Routes from "./Routes";
import DynamicSitemap from "react-dynamic-sitemap";
export default function Sitemap(props) {
return (
<DynamicSitemap routes={Routes} prettify={true} {...props}/>
);
}
Routes.js
import React, { useContext, useEffect, useState } from 'react';
import { Route, Routes } from 'react-router-dom';
import { Portfolio } from './PortfolioComponent/Portfolio';
import { PortfolioDetail } from './PortfolioDetailComponent/PortfolioDetail';
import Sitemap from './Sitemap';
const MyRoutes = () => {
return (
<Routes>
...Other Static Routes...
<Route
path="/portfolio"
element={<Portfolio />}
sitemapIndex='true'
changefreq='weekly'
priority='1'
/>
<Route
path="/portfolio/:slug"
element={<PortfolioDetail />}
sitemapIndex='true'
changefreq='weekly'
priority='1'
slugs={[Objects of the slugs of different portfolios have to written staticly]}
/>
<Route path="/sitemap" element={<Sitemap />}></Route>
</Routes>
)
}
export default MyRoutes;
Can someone please answer these points, and end the issue for all React developers:-
What is the best way to generate sitemaps staticly in react, as many solutions say to use nextjs or to use online sitemaps generator
If no other way possible, how can we render react-dynamic-sitemap content as xml
If I'm not mistaken, you are using Create React App (CRA), right?
I have to be honest, CRA is easy to get started, but as you scale up and require more advanced features (e.g. image optimization, sitemap generation, SEO, etc), as you may have already noticed, you will start finding it problematic.
Since you want to have a sitemap, indicating your site is starting to grow into a decent size, instead of digging the rabbit hole, I would suggest you move to a more scalable framework, which Next.js is one of the most popular ones.
That being said, be warned that even Next.js doesn't have native support to sitemap. Most people just rely on next-sitemap, but it is proven to be a robust solution

Auth0 React JS Token EndPoint Gets Called On Every Route Change and Page Reload

Every time I try and use Auth0 SDK in a new react js project, it gives me this issue. In the past, I usually circumvent this problem by using their ready to use react js sample. This time I cannot use that sample, so trying to get some help.
After successful login, on every route change, there is a network call to the token endpoint, and a new token is generated and received by the app. Every time. The app does not prompt a log in. It already knows that the user is logged in. It simply goes ahead and asks for new token.
Here is a photo of how it looks. All this activity in less then a minute.
I have raised a issue on the SDK Github Repo here - https://github.com/auth0/auth0-react/issues/181
Further, I have configured the SDK, as per the steps, available here. https://github.com/auth0/auth0-react#getting-started
As per the getting started, all I need to do is wrap my App inside their component. This is my index file, with the wrapping.
ReactDOM.render(
<Auth0Provider
domain={config.domain}
clientId={config.clientId}
audience={config.audience}
redirectUri={window.location.origin}
onRedirectCallback={onRedirectCallback}
scope={config.scope}
>
<React.StrictMode>
<App />
</React.StrictMode>,
</Auth0Provider>,
document.getElementById('root')
);
The bizarre part is the React sample runs just fine, and I have compared every possible setting of that sample with my project, but nothing stands out. the react sample is configured to use the exact same server, and running on the same computer and browser.
The pull request I raised, one of the auth0 developers provided me the solution.
quoting the Auth0 developer from the pull request,
"The issue is that you're bypassing react-router and loading a new page when you click <Button href="/about". "
So, that was the problem. I had accidentally (being new to react js) written code that was invoking the token call.
solution, also quoting the Auth0 developer,
import { Link } from 'react-router-dom';
const Home = () => {
//...
<Button tag={Link} to="/about" color="primary" size="sm">about</Button>
// ...
}
more details here - https://github.com/auth0/auth0-react/issues/181

React router dom hijacking my image/pdf/api links

I have a react app, it uses react router dom. I built it and moved it to, say,
http://domain.tld/ the site works fine. I have two problems :
if I visit the app and then click on a pdf linked (which is just a real file on my server) react-router-dom somehow hijacks it, and shows me the 404 page I set up in react router
same goes if I try to access, for example, http://domain.tld/api/whatevs, it doesn't work either
in both case if I empty the cache, I can see my pdf, or the json result of my api then a js is injected, and a refresh gives me my 404 page.
How can I prevent react router to hijack everything ? I already have a mandatory apache rewrite to redirect in case files dont exist.
EDIT: as requested in a comment, here is how my routes are defined :
<BrowserRouter>
<div>
<Menu />
<Route path="/" exact component={Home}/>
<Route path="/pages/:page_name" component={Page}/>
<Footer />
</div>
</BrowserRouter>
I removed some routes, but the structure is intact.
EDIT2:
from what I gathered, in fact, the service worker 'hijacks' all my static server route, and that's suppose to be normal, so I'll just unregister it, but if I'm correct I can't do that unless I want my app to reload on each link, I'm still looking for a way to tell it : "pretty please, dont touch /api/, /assets/ etc"
EDIT3:
and this might just be what I need :
Setting service worker to exclude certain urls only
I'll try when I'm at work tomorrow

Structuring a modular enterprise application with React?

A lot of us will be familiar with the enterprise web applications that are the be all and end all of the business data. They are usually a collection of various modules behind a login authentication and role based authorization. Instead of the user login in to various smaller application they login once and have a dashboard/menu of what they have access to.
The user login
Their roles are retrieved and stored in session
Application load with a large menu populated according to their roles (CRM, CMS, no admin panel, etc.)
We have been thinking of how we could leverage some of the newer frameworks out there (Angular, React, Vue) or if we should at all for these kind of applications.
I am a struggling when it come to state management. I understand the idea of managing the state using something like Redux with React for smaller components but if various part of a larger application are completely unrelated to each other I am left wondering how complex and how large this state might get to be?
Using React as an example my root component after login might be (I am not sure as I am not extremely familiar with React yet).
const Root = () => {
return (
<div className="container">
<Router history={browserHistory}>
<Route path="/" component={dashboard}/>
<Route path="/crm" component={crm}/>
<Route path="/cms" component={cms}/>
<Route path="/module1" component={module1}/>
...
<Route path="/moduleN" component={moduleN}/>
</Router>
</div>
)
}
ReactDOM.render(<Root />, document.getElementById('root'));
Is this the better approach even if the multiple routes have nothing in common (the cms doesn't care about the crm) that they should all share the state or would actually reloading the page and going to different smaller more focused single page applications be preferred?
For example, using traditional server side logic to present the menu going to different html file for each modules.
What you are referring to is called lazy loading, that will break down your routes in different JS files and only load them on requests. You can refer to this link on how to use lazy loading in vue.js
https://router.vuejs.org/en/advanced/lazy-loading.html
Here is a way in React (does not seem to be native, correct me if I am wrong)
Dynamic loading of react components

Resources