Express/React app refresh issue on Heroku - reactjs

My React app with Express backend is hosted on Heroku, and all of the routing works as expected until the page refreshes. Refreshing the page either programmatically, or with the refresh button the page returns:
Failed to load resource: the server responded with a status of 404 (Not Found)
The back and forward buttons (which work before refreshing) cease to work and the only way to get the app back is to navigate to the "/". Everything works correctly then until the next refresh.
My server routes :
router.use("/api/skus", skuRoutes);
router.use("/api/categories", categoryRoutes);
// serve static files if in production
if (process.env.NODE_ENV === "production") {
router.use(express.static("client/build"));
router.get("*", (req: Request, res: Response) => {
res.sendFile(
path.resolve(__dirname, "..", "client", "build", "index.html")
);
});
}
I have read many, many other similar questions on here and many tutorials on using react router on Heroku, but I haven't found a solution that works for me.
I have already tried the solutions that use a static.json file:
{
"root": "build/",
"clean_urls": false,
"routes": {
"/**": "index.html"
}
}
, and adding the create-react-app buildpack to Heroku, but these do not work for me.
GitHub repo here.
Current deployment here.

The issue was fixed by changing my BrowserRouter to a HashRouter. Now refreshes work perfectly.

Related

Service worker caches images as html/text when deployed on Vercel

PWA Application Cache error
I'm creating a PWA Application with React. I've created a fallback page for when the application is offline. I would like to have a image showing when offline, so I cached it successfully on localhost but when deployed on Vercel, the caching isn't right.
On localhost png caches as image/png.
localhost screenshot
When deployed on Vercel, caches content is Text/Html
vercel screenshot
const staticCache = "site-static-v1";:
const assets = [
"index.html",
"offline.html",
"script/useSW.js",
"assets/Logo-offline.png",
];
self.addEventListener("install", (event) => {
event.waitUntil(
caches.open(staticCache).then((cache) => {
cache.addAll(assets);
})
);
});
Anyone knows how to solve this issue?

webpack-dev-server - Remove URI fragment from URL when live reloading

I'm dealing with an Angular 1 application that uses URI fragments for routing purposes.
For example:
http://localhost:3000/#/home
http://localhost:3000/#/menu
http://localhost:3000/#/list
Rather than:
http://localhost:3000/home
http://localhost:3000/menu
http://localhost:3000/list
When I'm using Webpack Dev Server to launch a local server with hot reloading, every time I apply some changes, Webpack reloads the URL but keeping the "/#/route" part.
Unfortunately, due to some code restrictions, I need to always reload the page from "/" because some redirections are applied internally when the app launches the first time and the app will crash if you try to start directly from any URI fragment.
I tried to use the "proxy" and "historyApiFallback" configurations in webpack.config.js like:
devServer: {
proxy: {
'/#': {
target: 'http://localhost:3000',
pathRewrite: { '^/#': '' }
}
}
And:
devServer: {
historyApiFallback: {
verbose: true,
rewrites: [{ from: /^\/#/, to: '/' }]
}
}
But so far, I didn't have any luck. The URL keeps the hash when reloading.
Any suggestions or ideas to configure Webpack Dev Server to always start from "/" and remove the hash URI?

Link tag in React is not working with devserver-proxy

I'm following this tutorial to make my React app (localhost:3000) communicate with Node server (localhost:5000) .. so instead of typing <Link to='localhost:5000/auth/google'>Login with Google</Link> I only want it to be just '/auth/google', but when I click on the button with Link tag it sends this error "No routes matched location "/auth/google"
I'm using React v17.0.2
this is what's inside my setupProxy.js file
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
["/auth/google", /api/*],
createProxyMiddleware({
target: "http://localhost:5000",
changeOrigin: true,
})
);
};
the weird thing though is that I got no error when I type the route directly in the browser (both ports work just fine) and it redirect me to the page I want (handled by Express)
If there's no solution for this problem for now, is there any other way to use a proxy in a MERN application because from what I know adding "proxy" in package.json is not working anymore

ngrok does not work with react-router when deep links are explicitly defined

Context: I'm opening up my React dev environment to external hits using a paid version of the tool ngrok -- I am running WebPack 4.0 with a devServer.
I go to my app's main page:
https://my-example-domain.ngrok.io
Loads fine.
I click one of the links on my app's main page, The router works well and I see the content for:
https://my-example-domain.ngrok.io/my-sub-page
However, if I refresh at this point, ngrok gives out a 404:
Cannot GET /my-sub-page
The reason I suspect is that in a SPA, the internal app's URLs are processed by the front end in React-Router and externally, there is no resource called /my-sub-page
Is there a way to force this to work?
The problem is that the local server doesn't know about your spa routes(react-router). To fix this, you have to create a simple server that will serve your static build and have a fallback route that will enable spa-routing.
Example in express.js:
import express from 'express';
import path from 'path';
// ... other imports
const app = express();
app.use(express.static('build'));
/*
... some route handlers
*/
// * Unknown endpoint
app.use("/*", (_req, res) => {
res.sendFile(path.join(__dirname, "../build/index.html"), (err) => {
if (err) {
res.status(500).send(err);
}
});
});
app.listen(process.env.PORT || 3000 , ()=>{
console.log('server running')
})
This resolved it -- in webpack.config.js
devServer: {
...
...
historyApiFallback: true, // <- inserting this resolved the issue.
}

Configuring a single page Create-React-App on Heroku

With Firebase Hosting, when you deploy an app you are asked whether to rewrite all urls to /index.html. This means react-router routes would be properly fired whether they are accessed directly or navigated to from the homepage.
We use Create-react-app and Create-react-app-buildpack to deploy to Heroku. How can we rewrite all the URLs to /index.html in the same manner?
Following this issue, explaining about the routes directive, I configured a static.json in the root to no avail:
{
"routes": {
"/images/*": "/images/",
"/legal/*": "/images/",
"/media/*": "/media/",
"/fav/*": "/fav/",
"/styles/*": "/styles/",
"/**": "index.html"
}
}
Create a static.json file in the project root with the following content:
{
"root": "build/",
"routes": {
"/**": "index.html"
}
}
More here.

Resources