12

Summary

I'm trying to setup Next.js with static website hosting on S3 and CloudFront. For the most part it works but I'm having trouble with dynamic routes.

My directory structure looks like this.

pages/
  index.js
  about.js
  [id].js

Currently my Next.js config is set to trailingSlash: true so when I run next build && next export my exported static files look like this.

out/
  index.html
  about/
    index.html
  [id]/
    index.html

This means that when I visit "123456.cloudfront.net" or "123456.cloudfront.net/about/" the correct index.html is displayed. However when I visit "123456.cloudfront.net/1/", I obviously get an error message instead of out/[id]/index.html.

Caveats

The id pages are added, removed and updated regularly, so I don't want to generate them at build time using getStaticProps and getStaticPaths.

Solutions I've considered

  • I tried routing the S3 error document to out/index.html in the hopes that it would load the home page, run the JavaScript, recognise the path and end up showing the correct [id] page but it just stays on the home page.
  • I've considered trying a solution with Lambda@Edge to load the correct page but anytime I add or change paths in my application, I would probably need to update the lambda which seems messy.

Am I missing something?

alexedwardjones
  • 561
  • 1
  • 5
  • 18
  • "I don't want to generate them at build time using getStaticProps and getStaticPaths" - If you're exporting your Next.js app as static files, how else would those pages be available then? That defeats the purpose of using SSG in the first place. Maybe you should consider using SSR instead for the dynamic path? – juliomalves Mar 15 '21 at 17:15
  • 1
    Those pages would be "available" because I export the single [id]/index.html page and that fetches the data for each [id] on the client. – alexedwardjones Mar 15 '21 at 19:18
  • 1
    Ah, got it. You fetch the data on the client. – juliomalves Mar 15 '21 at 20:31
  • 1
    You need URL rewriting. The right solution is indeed having any kind of technical solution that can rewrite "out/3" to the actual file "out/[id]/index.html". It could be an NGINX server, an API gateway etc. I haven't set it up yet in my apps so I don't have a precise/scalable solution though. The problem is indeed how to update automatically, you need a way to parse your pages. But I am pretty sure you can script that somehow if it doesn't exist yet. – Eric Burel Mar 16 '21 at 16:08
  • Thanks, I was hoping to be able to do some cloudfront/S3 magic but looks like I have to go in a different direction. – alexedwardjones Mar 16 '21 at 22:20
  • One should also consider looking at Amplify. It sets up a lot of these configs for Next SSR out of the box. – Chris Hayes Jul 10 '22 at 06:07

2 Answers2

8

After doing some more reading into this, I realised that serverless next.js is basically aimed at solving this same problem. It hosts your Next.js app in an s3 bucket and then uses a combination of CloudFront behaviours and Lambda@Edge to route your requests to the correct place.

It also includes support for a lot of other Next.js features, so it looks like that's the way to go for now.

alexedwardjones
  • 561
  • 1
  • 5
  • 18
5

After more than a year of keeping with my ego to host it purely with S3 and cloudfront, I have moved to Vercel. If your site has a large number of pages say a product listing, then for SEO and performance you have to have ISG (Incremental Static Generation) and you can not do that with pure S3 and Cloudfront combination. We fought hard and it seemed like our engineering was going to build a product like vercel rather than own product development. So finally pulled the plug and moved.

NOTE: I do not work for vercel, and this is just a revelation after 1.5 years of S3 + Cloudfront + LambdaEdge based struggling, and live was easy after that.

Sourav Sarkar
  • 406
  • 1
  • 5
  • 14
  • Yeah, it doesn't make sense to end up rebuilding Vercel. – alexedwardjones Sep 11 '21 at 21:00
  • FWIW I have had reasonably good success with Amplify's support for NextJS. As long as you're not doing anything fancy with query strings (e.g. like a simple blog, small marketing site, etc.) or have similar requirements typical of a business app where you'd need to customize the Edge Lambda behaviours + other AWS services it worked well. There are plenty of examples out there to get NextJS + Amplify rolling with aws-cdk. – firxworx Oct 27 '22 at 16:50