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

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?

Related

Not able to view cached static files in PWA

I have a React based PWA deployed on AWS Amplify and I'm trying to cache a few PDF documents for offline use. Using USB debugging I found that the documents are effectively added to the cache. However, when I try to open a document in offline mode, I'm presented with an blank page which seems to correspond to the bare index.html of my app. My documents are located in public/documents, and service-worker.js has this added at the end:
var CACHE_NAME = "app-documents";
var urlsToCache = [
"/documents/document_1.pdf",
"/documents/document_2.pdf",
"/documents/document_3.pdf"
];
self.addEventListener("install", event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(function (cache) {
return cache.addAll(urlsToCache);
})
);
});
I'm linking from my app to the documents with a simple hyperlink:
<p>Document</p>

After deployment getting 404 error axios post

Currently, I'm trying to get axios data from node.js. and i can get the result on local url , however after i build it and deploy it, the post method get 404 error. so i tried to use get method to test it. it gets react html result .
it's totally okay when i do it on local. but only it doesn't work when i build and deployment.
I assumed it's because proxy problem so i installed http-proxy-middleware library and
I try to set up setupProxy.js on my react folder.
this is the example from
"https://create-react-app.dev/docs/proxying-api-requests-in-development/"
but it still doesn't work.
i want to know what can make this issue.
//node.js
app.get("/test", (req, res) => {
res.send({ hello: "Hello world" });
});
const __dirname = path.resolve();
app.use(express.static(path.join(__dirname, "dist")));
app.get("/*", (req, res) => {
res.sendFile(path.join(__dirname, "dist", "index.html"));
});
//react
const getTest = () => {
axios
.get(`${backend}/test`)
.then(res => {
console.log(res.data);
})
.catch(err => console.log(err));
};
The proxy configuration only applies to the webpack-dev-server you use when developing your React app...
Keep in mind that proxy only has effect in development (with npm start), and it is up to you to ensure that URLs like /api/todos point to the right thing in production.
I would suggest just using the simpler version by adding this to your package.json
"proxy": "http://localhost:5000",
You should also make sure your Express app is configured to handle API requests in both dev and production modes. To do so, I'd recommend using the same routes as used in the requests from the front-end...
app.get("/api/test", (req, res) => {
res.send({ hello: "Hello world" });
});
// or even better
app.use("/api", myApiRouter);
Now your React app can make requests to /api/test in both development and production modes
axios.get("/api/test").then(({ data }) => console.log(data));
In development mode, the proxy configuration will forward the requests to your Express app.
In production mode, your Express app will be serving the built React app via express.static() so they'll be on the same domain.

Express/React app refresh issue on Heroku

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.

Not able to connect by frontend to backend on heroku after successful deployment

I have deployed my mern stack app on heroku. The problem is i am not able to make any request to my backend .
I am connecting my frontend to my backend like this...
API=http://localhost:5000/api
import { API } from "../../backend";
import { signin } from "../../auth/helper";
export const getAllProducts = () => {
return fetch(`**${API}/allProducts**`, { method: "GET" })
.then((response) => {
return response.json();
})
.catch((err) => {
console.log(err);
});
};
I think i am caliing api on my local host thatswhy i am not getting connected to backend.
What should i do here?
If you want anything else you can tell me .
In client side (frontend) code, localhost is the end user's machine because the code runs in the browser of that machine. Therefore, when it's trying to fetch at localhost:5000/api, it's looking for a Node.js server on the end user's machine, not your actual production server on Heroku.
Instead of localhost, use the domain Heroku assigned to your app. You can find it in the Settings of your dyno and should look something like this https://yourapp.herokuapp.com/. Additionally, you can use NODE_ENV env var to set the API string so it works both on development and production:
const API = process.env.NODE_ENV === 'production' ? 'https://yourapp.herokuapp.com/api' : 'http://localhost:5000/api';

Heroku redirect Next.js React client app http to https

I have an express server deployed on Heroku: https://server.mydomain.com
and a Next.js React app also deployed on Heroku: https://app.mydomain.com
Both have their SSL certificates automatically configured by Heroku, and when I visit the https domains, they work as expected.
The problem I have is that when I visit http://app.mydomain.com, it does not redirect to https://app.mydomain.com.
All the solutions I've found online point to forcing SSL on the server:
this popular question says to check for the x-forwarded-proto value:
/* At the top, with other redirect methods before other routes */
app.get('*',function(req,res,next){
if(req.headers['x-forwarded-proto']!='https')
res.redirect('https://app.mydomain.com'+req.url)
else
next() /* Continue to other routes if we're not redirecting */
})
and others suggest using a package like express-sslify or heroku-ssl-redirect.
These solutions work fine for the server requests, but loading a React client page does not necessarily trigger app.get(). Obviously, a React client can run independently of a server.
So the question is: How does someone force https for a subdomain Next.js React client app on Heroku? Without using express server methods?
I do this in one of my production applications.
We prepare the next app object and init an express server. This is done in the server.js file. You can read more about it in the docs about a custom server.
Next.js also has an example in their github in the examples folder about a custom express server. It's here.
const express = require('express');
const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
app
.prepare()
.then(() => {
const server = express();
server.use((req, res, next) => {
const hostname = req.hostname === 'www.app.domain.com' ? 'app.domain.com' : req.hostname;
if (req.headers['x-forwarded-proto'] === 'http' || req.hostname === 'www.app.domain.com') {
res.redirect(301, `https://${hostname}${req.url}`);
return;
}
res.setHeader('strict-transport-security', 'max-age=31536000; includeSubDomains; preload');
next();
});
server.get('*', (req, res) => handle(req, res));
server.listen(
4242,
error => {
if (error) throw error;
console.error('Listening on port 4242');
}
);
})
.catch(error => {
console.error(error);
process.exit(1);
});
As for deploying to Heroku you should be able to just customize the npm start script to start nextjs like so:
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
}
Heroku also runs npm run build automatically so it should build the app for you.
Heroku does not currently "offer out of the box" functionality to force the use of https for node apps.
However, with the release of Nextjs v12 you can accomplish this without having to setup a custom server and use middleware instead.
See this answer for example code and advantages of middleware vs custom server.
I also published a npm package to handle this:
import sslRedirect from 'next-ssl-redirect-middleware';
export default sslRedirect({});

Resources