Skip to main content

Static Export

vinext supports full static site generation, creating HTML files at build time that can be deployed to any static hosting provider—no server required.

Overview

Static export renders all pages to HTML at build time, producing a directory of static files:
Benefits:
  • Deploy to any static host (CDN, S3, GitHub Pages)
  • Maximum performance (no server rendering overhead)
  • Zero infrastructure requirements
  • Perfect for documentation sites, blogs, marketing pages
Limitations:
  • No server-side rendering (SSR)
  • No API routes
  • No dynamic routes without generateStaticParams() or getStaticPaths()
  • No Incremental Static Regeneration (ISR)

Enable Static Export

Add output: 'export' to your Next.js config:
Then build:
vinext generates static HTML files in the dist/ directory.

Pages Router

Static Pages

Regular pages are rendered to HTML automatically:
Generates dist/index.html.

Pages with Data (getStaticProps)

Fetch data at build time:
getStaticProps runs at build time—the API is called once, and the result is baked into the HTML.

Dynamic Routes

Dynamic routes require getStaticPaths to specify which paths to generate:
Important: fallback must be false for static export. No dynamic fallback pages are generated.

Catch-All Routes

Catch-all routes work the same way:
Generates:
  • dist/docs/getting-started.html
  • dist/docs/api/reference.html
  • dist/docs/guides/deployment/cloudflare.html

Not Supported with Static Export

getServerSideProps

Error: getServerSideProps requires a server.
Solution: Use getStaticProps instead.

API Routes

API routes are skipped with a warning:
Alternative: Use external APIs or serverless functions.

App Router

Static Pages

Server Components are rendered at build time:
Generates dist/index.html.

Pages with Data

Server Components can fetch data directly:
The fetch runs at build time, and the result is baked into the HTML.

Dynamic Routes

Dynamic routes require generateStaticParams:

Catch-All Routes

Nested Dynamic Routes

For nested dynamic segments, use top-down params passing:

Route Handlers (API Routes)

Route handlers are skipped with a warning:

Static Metadata

Metadata is included in the generated HTML:

Build Process

vinext performs the following steps during static export:
1

Route Discovery

Scans your pages/ or app/ directory to find all routes.
2

Path Expansion

For dynamic routes, calls getStaticPaths() (Pages Router) or generateStaticParams() (App Router) to expand all possible paths.
3

Rendering

Renders each route to HTML:
  • Pages Router: Calls getStaticProps, renders with React SSR
  • App Router: Starts dev server, fetches each URL, saves HTML
4

Asset Copying

Copies static assets (JS, CSS, images) from public/ and Vite build output to dist/.
5

404 Page

Renders custom 404 page if present, otherwise uses default.

Deployment

Cloudflare Pages

Deploy the dist/ directory:
Or configure automatic deployments via GitHub integration in the Cloudflare dashboard.

Vercel

Vercel auto-detects the static output and deploys it.

Netlify

Or connect your GitHub repo for automatic deployments.

GitHub Pages

Add a workflow:
Configure GitHub Pages to serve from the gh-pages branch.

AWS S3 + CloudFront

Nginx

Copy dist/ to your web server:
Configure Nginx:

Advanced Configuration

Trailing Slash

Control URL format:
With trailingSlash: true:
  • /aboutdist/about/index.html
  • Served as /about/
With trailingSlash: false (default):
  • /aboutdist/about.html
  • Served as /about

Base Path

Deploy to a subdirectory:
All routes are prefixed with /docs:
  • //docs/
  • /about/docs/about
Links and asset paths are automatically adjusted.

Image Optimization

Images are not optimized in static export. Options:
  1. Disable optimization:
  2. Use a CDN: Upload images to a CDN that handles optimization (Cloudflare Images, Imgix, Cloudinary)
  3. Optimize at build time: Use an image optimization tool before deploying

Common Patterns

Documentation Site

Blog with Pagination

Multi-Language Site

Troubleshooting

Build Error: getServerSideProps Not Supported

Error: Page uses getServerSideProps which is not supported with output: 'export' Solution: Replace getServerSideProps with getStaticProps. Server-side rendering requires a server.

Build Error: Dynamic Route Missing Paths

Error: Dynamic route requires getStaticPaths with output: 'export' Solution: Add getStaticPaths (Pages Router) or generateStaticParams (App Router):

404 on Dynamic Routes

Problem: Dynamic routes return 404 after deployment Solution: Most static hosts expect .html files. Configure your host to:
  • Append .html to paths without extensions
  • Use a rewrite rule: /blog/post-1/blog/post-1.html
Or enable trailing slashes:
This generates /blog/post-1/index.html which is served as /blog/post-1/ by default.

Large Build Time

Problem: Static export takes a long time Solution: You’re generating many pages. Options:
  • Reduce the number of pages generated
  • Use ISR instead (requires a server)
  • Deploy to Cloudflare Workers for on-demand rendering

Data Not Updating

Problem: Content changes don’t appear after deployment Solution: Static export bakes data at build time. To update:
  1. Rebuild: vinext build
  2. Redeploy the new dist/ directory
For frequently-changing data, use client-side fetching instead:

Next Steps

Deployment Guide

Deploy your static site to production

Configuration

Customize build and export settings

Cloudflare Pages

Deploy to Cloudflare Pages

Examples

Explore static export examples