Preview Server

Introduction

After generating your site with bun ssg, the preview server serves the static output from dist/ so you can verify everything looks correct before deploying. It handles directory-style URLs (/about/about/index.html), detects language subdirectories, and serves assets with proper MIME types.

bun preview

This serves ./dist on the port from PORT in .env (the example .env ships PORT=3000); pass --port to override it.

CLI Options

bun scripts/preview.ts [--port 3000] [--dist ./dist]
FlagAliasDefault / SourceDescription
--port <n>-pPORT (env)Port the server listens on
--dist <dir>--dir./distOutput directory to serve
--help-h-Print usage and exit

How It Works

The preview server (scripts/preview.ts) is a minimal Bun HTTP server that:

  1. Serves dist/index.html at the root (/) - the default language homepage
  2. Resolves directory paths - /about/ looks for dist/about/index.html
  3. Falls back to .html extensions - /en/about tries dist/en/about.html
  4. Serves any other file directly - CSS, JS, images, fonts with correct MIME types
  5. Returns 404 for anything that doesn't exist

Language Detection

At startup, the preview server scans the dist/ directory for subdirectories whose names match a configured language code in config/supported_languages.ts (e.g., en/, sl/, de/). Matching against the configured list - rather than any two-character directory - means content directories that happen to be two characters long (such as js/) are never mistaken for a language. It lists the detected languages in the startup log:

🖥️  Preview server ready at http://localhost:3000/
📂 Serving: ./dist
🌐 Languages: sl (default), en

The server doesn't apply language-specific logic - it simply serves files from the path the browser requests. If you navigate to /en/about/, it serves dist/en/about/index.html directly.

Production vs Development

The preview server is meant for verifying the built output - it's not a development server. The key differences:

Dev Server (bun dev)Preview Server (bun preview)
Renders templates✅ Live, on-demand❌ Static files only
Live reload✅ WebSocket
File watching✅ Auto-refresh
Requires SSG✅ Must run bun ssg first
Serves fromsrc/public/ + static/dist/
Language routing✅ Full resolution✅ File-based

MIME Types

The preview server maps file extensions to MIME types for correct Content-Type headers:

ExtensionContent-Type
.htmltext/html; charset=utf-8
.csstext/css; charset=utf-8
.jsapplication/javascript; charset=utf-8
.jsonapplication/json; charset=utf-8
.svgimage/svg+xml
.pngimage/png
.jpg, .jpegimage/jpeg
.gifimage/gif
.webpimage/webp
.icoimage/x-icon
.woff2, .woff, .ttffont/*
.txttext/plain; charset=utf-8
.xmlapplication/xml; charset=utf-8
(other)application/octet-stream