I developed a reactJS project (front-end) on AWS which has it RESTFUL API coming from heroku. They are completly separated i.e the frontend and backend.
I have successfully uploaded my files to S3, and have activated my CloudFront Distributions, but I can't really figure out what is wrong because I can't see my react app when I hit the URL generated from the Domain name.
I have checked this SO answer, but it doesn't help.
Please any help will be greatly appreciated.
Firstly, it is perfectly fine to deploy them on different servers/cloud. Can you give the URL ? I feel it is not issue of different clouds but configuration issue. Can you first put a simple html file on same S3 bucket and see if you can access that via your domain name.
Suppose you have your react app example.com hosted in bucket named ant. So, go ahead and put additional test.html in bucket ant. Then try example.com/test.html .. This will make sure your domain setting etc. are proper
I have experienced similar issues trying to run a react.js app through cloudront, here are a few things you should check:
Make sure that your s3 hosting bucket has public read access, or that you have set up your cloudfront origin access policy with the s3 bucket by first creating an origin access identity in cloudfront, then associating the identity with your s3 bucket through the access policy:
{
"Version": "2012-10-17",
"Id": "MyPolicy",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity YOUR_CLOUDFRONT_ORIGIN_ACCESS_ID"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::YOUR_S3_BUCKET/*"
}
]
}
Make sure your s3 bucket has a cors policy allowing requests from any domain similar to:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
<AllowedHeader>Content-Length</AllowedHeader>
</CORSRule>
</CORSConfiguration>
If your package.json file in the react.js app has a homepage, you should remove it as this the application expects to be hosted from that url and not the cloudfront domain. Example package.json with homepage:
{
"name": "your-package-name",
"version": "1.0.0",
"description": "",
"author": "",
"homepage": "https://somepage.com/home",
"repository": {},
"dependencies": {}
}
Make sure that your root object in the cloudfront distribution is index.html
Make sure that after you run "npm run build" in the react app, you are only syncing your build folder with the s3 bucket.
Make sure that if you use the aws cli to move your build files to the s3 bucket, you use the command "aws s3 sync build/ s3://YOUR_DEPLOY_BUCKET/ --acl public-read --delete", this ensures that only the most recent build files are uploaded to s3, and that any old files are deleted.
After pushing files to s3, it is a good idea to run a cloudfront invalidation to ensure that your old files are removed from the cache and any new requests serve up the new files. you can run "aws cloudfront create-invalidation --distribution-id YOUR_CF_DISTRIBUTION_ID --paths '/*'" to accomplish this.
Because react.js uses the virtual dom, and the only html document actually served is the index.html document, you need to add custom error responses to your cloudfront distribution as cloudfront will expect to serve up web pages like about.html or contact.html depending on the route in your react app. I recommend adding custom error responses for http codes 400-404 and mapping the response to status code 200 with a redirect to the "/" route. This ensures that if cloudfront cant find a file such as about.html, it will stay on the index.html file (where your react app is) and react router will virtually route to your /about route. see below for example configuration:
have you tried making setting S3 bucket to “public”?
you can either set a policy for the entire bucket or to to make certain objects available publicly.
here’s an AWS manual
chances are, your react app needs something like that
Related
I'm investigating a way of deploying an Angular or React web application on Google Cloud using GCS, Load Balancer, and CDN.
I've set up the LB and the GCS using the urlRewrite, but since the LB does not allow full URL rewrite only pathPrefixRewrite, I cannot redirect all the requests to /index.html
I want to achieve the same functionality as firebase hosting where you can specify the rewrite rules
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
Another option will be to set the 404 page as index.html, but that will result in a 404 status code return by the server, which I don't like.
Is this possible with Load Balancer, because they are not supporting a full rewrite?
Google added rewrite engine in 2020 (see https://serverfault.com/questions/927143/how-to-manage-url-rewrites-with-a-gcp-load-balancer/1045214) and it is only capable pathPrefixRewrite (stripping fixed prefix).
For SPA you need variable suffix rewrite to index.html so you use Nginx or Firebase.
Or mentioned error handler in bucket's HTTP server (with a downside of HTTP code 404 for your virtual URLs):
gsutil web set -m index.html -e index.html gs://web-stage/
Full instructions to set SPA app is here: Google cloud load balancer create backend service for Firebase Hosting to serve microservices & frontend SPA from the same domain via load balancer?
Discussion of LB rewrite engine limitations:
How can I implement a .htaccess configuration in Firebase Hosting?
Google Cloud Load balancer URL Rewrite not working
https://www.reddit.com/r/googlecloud/comments/8zgg20/static_website_url_rewrite/
A complete newbie to AWS but I have a client project I am trying to host on Elastic Beanstalk (Angular App)
Currently, I have a spring boot app that I managed to deploy successfully to AWS EB yesterday which serves the front end the data it needs based on API Calls. I am now trying to upload the front end side of the project into its own S3 Bucket and host it as a static website. As far as I am aware, I have made all access to the bucket public, but still get the 403 Forbidden - Access Denied.
This is what I get in the browser after following the link generated by AWS which apparently serves my static site:
The steps I have taken are as follows:
I have created a new Bucket called three-counties-medical and added the project folder containing the built files from ng build --prod. These get uploaded successfully.
The bucket contents are as follows:
Once the bucket was created correctly with all of files added successfully, I then went to the Bucket Properties, scrolled down to the very bottom to Static Website Hosting and clicked Edit. I then enabled static website hosting and configured my index.html as the index page of the static website. The config looks as follows for the Static Website Hosting:
However, when I click the link created by S3, I get the 403 forbidden displayed in the browser.
In the Permissions Tab, I have turned Block all public access to OFF:
Something else I have noticed is that the Bucket Policy is completely blank with no Json.
Whether this is correct I am unsure, but from reading various sources online, it became apparent that the site needs to be public so it can be seen from anyone (Im guessing?)
I have also tried to make every file accessible/public by clicking on the file going to the Actions dropdown and selecting - Make Public. However, the error still remains.
I have tried looking at this post also:
Similar Error
If anyone has any answers please let me know. There is obviously some problem with the deployment of the app or some sort of config.
Cheers!
*** Edit ***
I have now added the following Bucket Policy from this answer Answer
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::three-counties-medical/*"
}
]
}
But now I get a 404 - KeyNotFound index.html:
But index.html definitely exists in the bucket!!
Ok so it turns out the issue was that I didnt have a Bucket Policy created. I then solved the 404 by deleting the contents of the bucket and then re-uploading the files in to the bucket rather than a folder containing the files. Guess this is why it could not find the index.html file!!
If anyone has any issues like this then please ensure you have a Bucket Policy. You can use the one in this answer!
For business reasons, I have to host my React app on one domain and serve the images/fonts from another domain (ie. S3). Not sure how I can configure the app to do this?
An example, I want to host my React app at:
http://kamilski.com/#/
And then serve my static assets (images and fonts) from:
http://camel.assets.s3.com/***
I don't know how to configure my create-react-app or Webpack to do this. I know that PUBLIC_URL is available but that still forces me to run the React app and assets on the same server.
This isn't too bad - I do a similar thing with a couple of my apps.
First, get the assets you want onto S3 using an S3 bucket.
There's a good youtube video for that here (this is about uploading from your react app, but the AWS setup is similar in some ways): https://www.youtube.com/watch?v=cDj4LPTLR3o
So once you have your aws bucket setup, you'll probably have one called "site_images" for example. At that point you can source those images from S3 like you would any other image:
https://camel.assets.s3.amazonaws.com/images/SOME-IMAGE-ON-AWS
You'd load fonts in a similar way via your css file(s) most likely with something like:
#fontface {
font-family: 'My Awesome Font';
src: url('https://camel.assets.s3.amazonaws.com/fonts/SOME-FONT-ON-AWS')
}
How you do this specifically will depend on your configuration. You'll need to adjust our aws bucket for CORS which can be a bit of a snag. These links should should help you in the right direction though!
https://coderwall.com/p/ub8zug/serving-web-fonts-via-aws-s3-and-cloudfront
Amazon S3 CORS (Cross-Origin Resource Sharing) and Firefox cross-domain font loading
Did you try to use plugins like webpack-s3-plugin
You can define rules for all assets you need.
And of cause you'll have to eject CRA or use something kind of react-app-rewired or rescripts.
I'm working on a React app hosted on Firebase, and a Wordpress blog hosted on Godaddy.
Is it possible to have the Wordpress blog rendering under /blog ?
I tried something like this in firebase.json (handeling multiple targets):
"hosting": [
{
"target": "site1",
"public": "site1/public",
"rewrites": [
{
"source": "/blog/**",
"destination": "myblog.example.com"
}
]
},
...
]
But I'm getting the 404 page from the React app.
I know I can rewrite to a Cloud Function, but how to "proxy" to the external blog, preventing the app to "catch" the request ?
You can't rewrite to arbitrary URLs -- to accomplish this you'd need to deploy a Cloud Function that proxied to the Wordpress blog using e.g. node-http-proxy. You could also use Cloud Run to host the Wordpress blog directly and rewrite to the Cloud Run service.
How do I redirect all requests to my static AWS S3 website to index.html so I can use AngularJS' HTML5 Mode?
I recently learned (to my unending delight) that it is possible to use AngularJS without the # in the URL by using HTML5 Mode. However, I know from this answer that this requires some setup on the server, since all requests have to be redirected to the right html file (in this case, index.html) for this to work.
I use AWS S3's static website hosting for my site. I tried adding this to my redirection rules:
<RoutingRules>
<RoutingRule>
<Redirect>
<ReplaceKeyWith>/</ReplaceKeyWith>
</Redirect>
</RoutingRule>
</RoutingRules>
and
<RoutingRules>
<RoutingRule>
<Redirect>
<ReplaceKeyWith>index.html</ReplaceKeyWith>
</Redirect>
</RoutingRule>
</RoutingRules>
but I get issues with too many redirects.
Is there a way to do the kind of redirection necessary in AWS S3 with the static website hosting?
You can use AWS CloudFront for your use case. Setup the S3 bucket behind CloudFront and add index.html as the default route.
Still if the page is refreshed in a angular route (e.g /home), AWS CloudFront will search for a /home.html file in S3 and return 404: Not Found Response. However there is a workaround for this, where you can setup an custom error response for 404: Not Found HTTP error code to points towards the /index.html response page path.
For more details refer the blog post Using AWS CloudFront to serve an SPA hosted on S3.