Skip to article
HANDBOOK / CREATE A WEBSITE

Files, paths and templates

Understand what goes in a site, how pages are resolved, and what is uploaded.

FORMAT 1Updated September 19, 2026
On this page

A small site directory

The root is /lantern-data/sites/<name>. Page JSON filenames keep their .json extension in links. Only / maps automatically to /index.json. A Lua handler can implement routes such as /greet without a file extension.

Site directory
my-first-site/
  index.json       # Home page
  about.json       # /about.json
  guides/
    start.json     # /guides/start.json
  app.lua          # Optional server handler
  data/            # Local ctx.write storage; never upload

How a request is resolved

  1. If app.lua exists, load it and call the returned function with ctx.
  2. If the handler returns a response, use it.
  3. If it returns nil, try the static JSON file for a GET request.
  4. If no matching page exists, return a not-found error. Static files do not handle POST.

Pick the right starting point

TemplateUse it for
personalStatic homepage with pixel art and columns
documentationA linked handbook with a getting-started page
directoryA collection of links
fieldnotesA two-page build journal
guestbookPersistent notes submitted through a Lua form
showcasePixel art, forms, choices and masked demo input

Hub package format

A package is a JSON object with format: 1 and a files map. Map keys are relative paths; values are file contents as strings. The downloadable templates are ready-made packages. The computer’s Upload Hub draft action builds this package for you.

Upload package
{
  "format": 1,
  "files": {
    "index.json": "{\"version\":1,\"title\":\"Hello\",\"children\":[{\"type\":\"paragraph\",\"text\":\"Hello!\"}]}"
  }
}

Keep paths inside the site

Use paths such as /about.json or /guides/start.json. Traversal segments (.. and .), percent escapes, backslashes, query strings, fragments and colon-bearing paths are rejected. Form actions and redirects stay within the current site.

Found a mismatch? Include the exact error, runtime version and a small example with secrets removed.