The scenario

Consider a software product with a public website, documentation, and a small engineering blog. It needs fast public pages but no account-specific rendering. A static Next.js export could keep the delivery path small while allowing normal React development and independently deployable content releases.

Design for static routes explicitly

Next.js would generate the pages at build time with output set to export. Dynamic article routes would have a known set of slugs. Contact could remain a mailto link; any later server-only feature would need a separate service or a different hosting decision.

With trailing-slash routes, a request for /privacy/ needs to resolve to /privacy/index.html at the origin. A CloudFront viewer-request function could make that rewrite. Unknown paths should receive a real 404 response, rather than returning the home page with a successful status.

Use a private storage origin

S3 would keep public access blocked. CloudFront Origin Access Control would sign origin requests, with the bucket policy scoped to the intended distribution. This uses the S3 bucket origin rather than the S3 website endpoint.

A custom-domain certificate for CloudFront would be issued in us-east-1. The distribution would redirect HTTP to HTTPS, and a deliberate www policy would choose one canonical hostname. CDK would describe these resources with stable identifiers so that a routine content edit does not replace storage.

Publish assets before documents

A release job would upload the complete export to an immutable release prefix before changing live files. Hashed JavaScript and CSS would be copied first, followed by HTML and route payloads. Older hashed assets would remain available for browsers that still hold an earlier document.

Cache rules would distinguish fingerprinted assets from HTML and stable image URLs. After publication, checks would request every sitemap route, verify canonical URLs, and exercise deep links and 404s. Rollback would restore a previous complete release through the same process, without needing to change DNS.

What to validate

  • The direct S3 object URL is denied.
  • A nested route works when opened directly.
  • Unknown paths return 404 and www preserves the intended path.
  • A previous content release can be restored and checked.

The tradeoff

Static export fits public content, but not every Next.js feature. Authenticated rendering, server actions, and request-dependent pages would require an architecture change. Reassess the hosting model when the product actually needs them.

Technical references

Official documentation supporting the tools and mechanisms discussed above. The proposed architecture is illustrative.