Serve Stati's clean URLs from nginx

/about is about.html. The try_files line, the trailing slash redirect and the 404 page.

SNP 066 #742 Filed stati nginx

nginx
server {
  listen 80;
  server_name example.com;
  root /var/www/example.com/dist;

  # /blog/ and /about/ redirect to /blog and /about, the URLs Stati writes
  rewrite ^/(.+)/$ /$1 permanent;

  location / {
    # /about is about.html, / is index.html
    try_files $uri $uri.html $uri/ =404;
  }

  # Stati writes site/404.md as 404.html
  error_page 404 /404.html;
}

Stati writes every page as an .html file named after its URL: /about is dist/about.html, /blog is dist/blog.html next to the dist/blog/ folder of its posts, and only the home page is an index.html. stati preview and Netlify serve that as it is. Plain nginx needs the $uri.html in try_files.

The rewrite matters too. Without it, /blog/ hits the blog/ folder, which has no index.html of its own, and nginx answers with a 403. A permalink that ends in / is the one way to get a folder with an index.html in it, and $uri/ covers those.

While you're at it, keep the 404 page out of the sitemap and the search index:

typescript
sitemap: { enabled: true, excludePatterns: ['/404'] },
search: { enabled: true, exclude: ['/404'] },

For HTTPS on top, see redirect www and http to https in nginx.

In the Stati docs: Clean URLs and Front matter URL override.