CloudFront - serve different object based on path pattern - amazon-web-services

I'm serving a static webpage using S3/Cloudfront.
I would like to serve different html based on path pattern:
example.com/dashboard -> app.html
example.com/profile -> app.html
example.com/homepage -> homepage.html
example.com/marketing -> homepage.html
I know that you can set a 'Default Root Object' in cloudfront, but I was wondering if you would serve different object based on path patterns.

This isn't currently supported as written, but in an S3 bucket with web site hosting enabled, requesting /homepage or /homepage/ will automatically render the object at homepage/index.html if you set the Index Document for the bucket as index.html.
Lambda#Edge should be able to do this it, once that service leaves prievew mode.

Related

Configure Google Cloud Platform bucket to serve example.com/page.html when user accesses example.com/page

I'm hosting a static (NextJS) site on a GCP bucket, with my domain CNAME (let's say example.com) pointing to GCP. When Javascript is disabled, NextJS links in my generated content point to URLs like:
Page 1
but the actual file stored in the bucket is:
pages/1.html
which generates a 404 error when Javascript is disabled and <Link> doesn't capture the click.
I'm aware of the specialty page option MainPageSuffix in GCP, but I have it set as index.html and I don't think it can be set to rewrite someaddress to someaddress.html (and even if it could, it would not serve my root index.html corrctly when I point my browser to example.com)
I'm also aware of the as option in NextJS, but if I use it like:
<Link
href={`/pages/1`}
as={`/pages/1.html`}
>
it will not work when Javascript is enabled and I'm serving the site locally with npm run dev (I suppose it confuses <Link>?).
Is there any way to make this work? I'm using Next.js v13.0.7
(Alternatively, is there any other (free tier) option to host my site? I thought I could use Cloudflare Pages, but my static site has a lot of small pages - in the order of 100k - and Pages has a file limit of 20k)

AWS Redirect one domain to another except one path leading to a static website hosted on S3

I have a website with a normal url and a shorthand url, which is redirected to the normal/long url using an AWS EC2 Application load balancer, switching to http to https in the process.
Now I want one singular URL path, when added to the shorthand url, not the long url, to lead to an entirely different website.
Here an example:
short.url -> long.url (-> my website)
short.url/randompath -> long.url/randompath
short.url/specificpath -> short.url/specificpath -> entirely different website served from my s3 bucket
long.url/specificpath -> probably some 404 error
For context, Im doing this as I currently dont have full access to the website source, so I cant add the new website there directly.
Would it make sense at all to do this, is this even possible? As an alternative I'm thinking about creating a subdomain for my s3 bucket and doing a basic load balancer redirect to it, so short.url/specificpath -> sub.short.url/specificpath.
Thanks for your answers already!

How does one serve multiple static pages from a single S3 bucket?

Let's assume one has an Amazon S3 bucket example.com configured for static hosting. In the configuration, the console allows setting an index file and an optional error file. But I'm struggling to figure out how to add another page to the site. I thought this would be straight forward but I cannot find the answer in the official documentation or on the internet.
If I want to add one more page to the static site (e.g. example.com/page2) and there is a page2.html file already in the S3 bucket at the root, where is the correct place to make this routing configuration? Can it be done through the S3 console? Or does it need to be configured through some kind of a DNS record? As a further complication, this needs to also work with and without the www in the URL.
On the DNS side I currently have the following configuration:
CNAME | WWW | www.example.com.s3-website-east-1.amazonaws.com | TTL 30 min
URL Redirect Record | # | http://www.example.com unmasked
Are you trying to access the page at example.com/page2.html or example.com/page2
If you want to access the page at example.com/page2 then create a 'folder' called page2 off the root and in that folder put a file called index.html
If you want to use example.com/page2.html, then create a file called page2.html and put it in the 'root' of the bucket.
Simply create a file called page2.html. It will be accessible via example.com/page2.html.
No routing configuration is required.
The index file alias is only used if no page is specified (eg they go to example.com/).
As for mapping www.example.com to example.com, you would create another bucket with the name www.example.com and use "Redirect requests" to point back to example.com. (If using a CNAME works for you, that's probably easier, but test it first to see if it functions as expected. See: Mapping naked domain (www.domain.com) to static website which is saved in S3)
See: Configuring a static website using a custom domain registered with RouteĀ 53 (Follow the manual steps rather than automating via CloudFormation, so you can better understand what has been configured)

How AWS Cloudfront works for both static website and dynamic website when website is externally hosted (not hosted on AWS or S3)?

I am trying to understand how Cloudfront works. Assume static website is static.com and dynamic website is dynamic.com. static.com has thousands of html files containing img tags referencing images coming from static.com.
dynamic.com is Java based dynamically generating HTML and img tags and images comes from dynamic.com
Assume images are not manually copied to s3. No modifications are made in both sites in regards to Cloudfront other than DNS settings.
Assume Cloudfront url setup for static.com is mystaticxyzz.cloudfront.net and for dynamic.com it is mydynamicxyz.cloudfront.net
CloudFront works as a CDN sitting in front of what are called Origins.
These origins are the endpoints that CloudFront forwards traffic to, to retrieve the response and content. This could be a single server, a load balancer or any other resolvable hostname that is publicly accessible.
If you want to split between static and dynamic content you would create an origin for each type of content within the same distribution. One would be the default origin whilst the other would be matched based on a file path (/css or /images).
Each of these origins can include their own cache behaviours which enable you to define whether they should be cached and how long.
When a user accesses the CloudFront domain dependant on the path it will route to the appropriate origin or retrieve a response from the edge cache where possible.
I know this is rather late, but I am just going to add this here for those struggling to cache dynamic and static content.
Firstly, you need to understand your application your application.
Client Side Rendering
if you have a reactjs you don't need to worry too much about your caching behavior as you will be rendering , the data which will be fetched from an api client side.
none of the static files/content will be changing which are being delivered to the end user.
Since the APIs requests will be coming from a different domain , that data won't be cached by the cdn . Moreover, the data being rendered will update the html via javascript. If your javascript files are continously updating then you can use invalidations for them.
If you have content that is not stored on the origin and your CSR app is fetching the content from using a separate domain from your website domain, you will need to set up a separate cdn and point the domain name to that cdn. You wont need to make any changes to your application as the domain name stays the same for that.
However, if you static content that exists in the same origin (e.g. s3) then you would just request the content using the domain name of the cdn from which the request will come from client to cdn to origin (if not cached / expired)
lastly, assume we have separate origins like an s3 bucket for react app and s3 bucket for images . We can set up a single cdn with multiple origins . This means we can use cloudfront as an aggregator , you will then be able to cache content from different origins by using special paths.
This means , where ever you make calls to those origins previously. i.e. using the the s3 domain names, you would need to update them to that single domain name as the caching behaviors will handle the requests to the respective domains
example:
www.example.com(react-app react s3 bucket)
www.example.com/images (some s3 image bucket)
<img source={{url:"www.example.com/images/example.jpg"}} />
cloud front will make a request to that server based on that origin for the behavior configured on "/images"
Server Side Rendered
for serverside rendered apps , ideally the default cahcing behavior on the origin should allow all the different http methods , because you will have post and put http requests which you will want cloudfront to forward to the origin .
Make sure that you forward all query strings and cookies to the origin using a request policy. You can fine tune it with white listing query strings or cookies but this will make life easier. Also, the default caching behavior should use a caching policy that disables cache i.e. min,default,max ttls = 0secs . this is because the content is dynamic in nature and gets rendered on the server and not client side thus you will encounter unexpected behaviors in your application depending on how it is set up.
if you have static content on different paths like "/img", "/css" , or "/web/pages/information" cache those independently from the default behavior the respective ttls on them.
you could do some cool stuff using the cache-control header which can by pass the cache if you dont want to configure a 101 behaviors.
https://aws.amazon.com/blogs/networking-and-content-delivery/improve-your-website-performance-with-amazon-cloudfront/
Just understand your application and you will be able to leverage cdn properly
if you have a webserver that does a mixture of server side and client side rendering
just identify which paths are client-side rendered and cache those static files.
Any thing that is dynamic in nature that requires the application to make requests to the origin , make use of the caching disabled policy within a behavior.
Moreover, any of those patterns(of using a single cdn with a single/multiple origins or multiple cdns with differing origins ) mentioned earlier is applicable to serverside rendering if some content gets rendered clients side such as images

AWS S3 Redirect only works on bucket as a subdomain not bucket as a directory

Many people have received 100s of links to PoCs that are on an internal facing bucket and the links are in this structure.
https://s3.amazonaws.com/bucket_name/
I added a redirect using AWS's Static website hosting section in Properties and it ONLY redirects when the domain is formatted like this:
https://bucket_name.s3-website-us-east-1.amazonaws.com
Is this a bug with S3?
For now, how do I make it redirect using both types of links? My current workaround is to add a meta redirect tag in each html file.
The s3-website is the only endpoint that supports redirects unfortunately. Using the s3.amazonaws.com supposes that you will be using S3 as a storage layer, instead of a website. If the link is to a specific object, you can place an HTML file at that url with a JS redirect, but other than that there is really no way to achieve what you are trying to do.
In the future, i would recommend always setting up a Cloudfront distribution for those kinds of usecases, as that will allow you to change the origin later on.