CLI

Three commands. That's it.

index97 dev

Start a development server with hot reload enabled.

index97 dev [pagesDir] [--port <n>]
  • Watches the pages directory for changes
  • CSS changes re-stamp without a page reload
  • All other changes morph the DOM in place
  • Defaults to the current directory and port 3000
  • Port can also be set via the PORT environment variable
index97 dev ./pages
index97 dev ./pages --port 8080

index97 start

Start a production server. No file watcher, no HMR script injected.

index97 start [pagesDir] [--port <n>]
index97 start ./pages
index97 start ./pages --port 8080

index97 serve

Serve a pre-built static directory. Use this after index97 build to preview the output or run it in production without a dynamic server.

index97 serve [dir] [--port <n>]
  • Serves files directly from the output directory
  • URL paths map to index.html files inside matching directories
  • Static assets (.css, .js, images) are served directly
  • Returns 404 for unknown paths
  • Defaults to dist/ and port 3000
index97 build ./pages && index97 serve
index97 serve ./output --port 8080

index97 build

Generate a static site. Renders all routes to HTML files and copies public/ assets.

index97 build [pagesDir] [--out <dir>]
  • Static routes (.phtml, .html, .md) are rendered automatically
  • Dynamic routes require a staticPaths() export — see below
  • Routes without staticPaths() are skipped with a warning
  • Output defaults to dist/
  • Each page is written as index.html inside a directory matching the URL path
index97 build ./pages
index97 build ./pages --out ./output

staticPaths()

Export staticPaths() from any dynamic route handler to tell the builder which URLs to generate. Return an array of param objects — one per page to render.

// blog/[slug].js
import { getAllPosts, getPost } from './_db.js'

export async function GET(req) {
  const post = getPost(req.params.slug)
  if (!post) return new Response('', { status: 404 })
  return { post }
}

export async function staticPaths() {
  return getAllPosts().map(p => ({ slug: p.slug }))
}

For routes with multiple dynamic segments, return all the params for each combination:

// users/[userId]/posts/[postId].js
export async function staticPaths() {
  return [
    { userId: '1', postId: 'a' },
    { userId: '1', postId: 'b' },
    { userId: '2', postId: 'c' },
  ]
}

Output structure

URLs map to directories with index.html files, so they work on any static host:

dist/ index.html ← / about/ index.html ← /about blog/ index.html ← /blog hello-world/ index.html ← /blog/hello-world public/ style.css logo.png
Note: staticPaths() runs at build time, so it has access to your database and any data sources available in your environment. Make sure your DB is populated before running the build.