Aws-Amplify: manifest.json and env.json loading index.html - reactjs

The React App my am building has a manifest.json and a env.json as follows,
However, when I publish the website using AWS-Amplify to a S3 bucket, the manifest.json and env.json loads my index.html instead. Everything is working as it should in localhost but in production we are having the previous issue even though we can get other files as icons and robot.txt.
The content of our public folder is the next:
asset-manifest.json
browserconfig.xml
ec4c4f981671b5dee24ab5f541f07720.png
ef7c6637c68f269a882e73bcb57a7f6a.woff2
env.json <----- loading index.html
icons
index.html
main-5fbcf0b95e5bf6891f54.js
main-5fbcf0b95e5bf6891f54.js.LICENSE.txt
manifest.json. <----- loading index.html
robots.txt. <------ working
service-worker.js
The amplify.yml file looks as:
version: 0.1
frontend:
phases:
preBuild:
commands:
- npm install
build:
commands:
- NODE_ENV=$MY_ENV_SELECTOR node ./node_modules/webpack/bin/webpack.js --mode production --env=prod
artifacts:
baseDirectory: dist
files:
- '**/*'
cache:
paths:
- node_modules/**/*
It looks like it is serving us the index.html because it is not finding the requested files, but we do not have a clue about why this is happening.
We hope anyone can help us with this problem.

I may have found the answer, working for me.
So I am building a Single Page App (SPA) using React and React-router.
I had to put in a redirect rule to manage the way the router works. As per the amplify docs.
Source address: </^[^.]+$|\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|ttf)$)([^.]+$)/>
Target address: /index.html
Type: 200 (Rewrite)
Seems like this is also pushing the request for manifest.json to go to index.html
I solved this by adding another rule to my amplify console:
Source address: /manifest.json
Target address: /manifest.json
Type: 200 (Rewrite)
Would be interested to know if this works for anyone else.

I found the problem.
Basically Amplify has a redirect functionality that we needed to configure for serving this files.
Thanks to everyone!

Related

Deploying React app with Vite in Heroku returns 404 status code

I'm having problems trying to access my website, it returns 404 status code.
I'm using React with Vite and Heroku.
I'm using this buildpack as it says in Vite docs:
Vite Heroku Deploy Doc: https://vitejs.dev/guide/static-deploy.html#heroku
Heroku Buildpack for static file: https://github.com/heroku/heroku-buildpack-static
Website page:
Folder Structure:
Static.json file:
Package.json file:
Vite.config.ts file
if you are having deployment issues with ANY single page application, use the following buildpack and make sure you are specifying the root folder of your bundled application
https://github.com/heroku/heroku-buildpack-static
This error can occur when:
1 - You don't specify in static.json file the index route. To solve it, just add this few lines:
"routes": {
"/**": "index.html"
}
Now you are saying that all routes redirects to index.html file.
If, for some reason, you want to add more routes for different html files, just do this:
"routes": {
"/": "index.html",
"*": "404.html"
}
In above example, when request reaches "/" route, it redirects to index.html, but if request uses any different route, it redirects to 404.html file.
2 - It also can happen when you don't have heroku/nodejs buildpack installed in your Heroku app.
If you are using Vite, you have to install both heroku/nodejs and heroku/heroku-buildpack-static
To install it you can access your app in heroku website, then go to settings, finally click on add buildpack button, place this url,save it and redeploy:
https://github.com/heroku/heroku-buildpack-static

PM2 serve SPA build folder. It works but has tons of errors like "Error while serving ... ENOENT: no such file or directory..."

The problem is that the logs are flooded, but it works fine.
The build folder contains the build from React using CRA (Create React App).
So from the PM2 Docs I have this:
ecosystem.config.js
module.exports = {
name: "projectName",
script: "serve",
watch: true,
env: {
NODE_ENV: "production",
PM2_SERVE_PATH: './build',
PM2_SERVE_PORT: 5001,
PM2_SERVE_SPA: 'true',
PM2_SERVE_HOMEPAGE: './index.html'
},
}
I'm using PM2 serve command.
Command to start PM2 process:
pm2 start
Errors
Only happens when I enter for the first time or when I reload.
Error while serving /.../projectName/build/routeX with content-type text/plain : ENOENT: no such file or directory, open '/.../projectName/build/routeX'
I think you have to find the nature of those requests leading to an error. If they are originated from your app, then you have either to put away what causes that request or let something to be in that place inside of your build folder (depends on request's reason). If they are originated not from your app, then you should figure out where they come from. "Network" Tab of DevTools should help you in both cases
This issue is fixed in pm2 v5.2.0
https://github.com/Unitech/pm2/pull/5272

Service worker not found (404) on deployment: React-Django-Heroku

I'm trying to get my first service worker registered on a Heroku app. Front end has been built using create-react-app, backend uses Django on the same server. I've made a basic "hello world" service worker which works in development, but gives a 404 error in production. I think I might be misunderstanding the basic file system that I'm using in production.
My file system on my local directory essentially looks like this:
root
- public
- index.html
- sw.js
static
- manifest.json
- src
- app.js
- serviceWorker.js
...
serviceWorker.js checks the browser and then attempts to register the service worker:
...
navigator.serviceWorker
.register(`${process.env.PUBLIC_URL}/sw.js`)
.then(registration => {
...
//process.env.PUBLIC_URL returns http://localhost:3000/ in development, and https://www.mydomain.app/ in production
sw.js just contains dummy code:
self.addEventListener('install', function(event) {
console.log("Hello World")
})
When this is deployed to Heroku, yarn build packages everything into a build directory, which looks like:
build
- index.html
- sw.js
- service-worker.js // added automatically by web-pack
- asset-manifest.json // added automatically by web-pack
- precache-manifest.xyz.js // added automatically by web-pack
- static
- css
- js
- manifest.json
In production, this fails to find the file sw.js during the register() function. The same error is happening with the auto-generated service-worker.js, where it works in development but not in production (404):
"TypeError: Failed to register a ServiceWorker for scope ('https://www.mydomain.app/') with script ('https://www.mydomain.app/sw.js'): A bad HTTP response code (404) was received when fetching the script."
I think my use of PUBLIC_URL is correct, as it works in development and production to find manifest.json at<link rel="manifest" href="%PUBLIC_URL%/static/manifest.json" />. I've checked the file system by using heroku run bash and everything seems to be in the right place, what am I missing?
Found the answer here, maybe this will help someone else.
I needed to serve the sw.js file as a view with django urls:
from django.views.generic.base import TemplateView
urlpatterns = [
...
path('sw.js', TemplateView.as_view(template_name="sw.js",
content_type='application/javascript'), name='sw.js'),
...
]

Gatsby running as a local file (index.html) without a server

Using the starter gatsby site, when I build it and load /public/index.html in chrome without running gatsby serve - none of the route links work. They point to the root of my drive - so <Link>'s look like this file://c:/page-2
I tried setting the pathPrefix in gatsby-config.js and ran a gatsby build --prefix-paths - but I can't get the route <Link>'s to be relative.
module.exports = {
pathPrefix: `/`,
....
Any ideas? I know this is possible with create-react-app without a server - as long as you set "homepage": "./" in package.json and use HashRouter - but not sure how to achieve the same in Gatsby.

Deploy a React app to a subdirectory using HashRouter and Traefik

I have a problem that is: I can't serve a react app in a sub-directory using HashRouter. I already tried the solutions proposed in this and this questions but it doesn't work as expected.
I have the following architecture:
Traefik as reverse-proxy
foo-service:
image: foo
labels:
- "traefik.enable=true"
- "traefik.http.routers.foo.rule=Host(`foo.localhost`) && PathPrefix(`/bar`)"
# The line below is done in order to nginx to serve the files on the root
- "traefik.http.middlewares.pathStrip.stripprefix.prefixes=/bar"
- "traefik.http.routers.foo.middlewares=pathStrip#docker"
nginx serving a React App (that uses HashRouter)
The problem here is that on package.json when I use "homepage": "." and I enter foo.localhost/bar I get a lot of 404 errors because the links to resources such as js/css are located on ./static/css/...css instead of bar/static/css/...css.
When I put "homepage": "/bar" the resources are loaded correctly but the URL becomes foo.localhost/bar#/login which seems wrong.
And finally when I set both "homepage": "/bar" and <HashRouter basename={'/bar'}> the resources are also loaded correctly but then the URL becomes foo.localhost/bar#/bar/login which is a disaster.
I know that my second solution is "apparently" the closest one to the right solution but I honestly dislike it because setting the path on package.json seems bad to me. I would like to only change the reverse-proxy configuration instead and let the app be "agnostic".
Thanks in advance.

Resources