Server-side Lua
Handle a request, build a page, and return a response. Start with a complete working file.
On this page
The handler contract
The file must return a function. Lantern calls that function with ctx for each request. The function returns page data, a redirect, an error, or nil for static fallback.
local P = ctx.page is simply a convenient abbreviation. P.document adds the document version and title; P.paragraph, P.heading and other builders add the component type. They do not print or draw directly.
return function(ctx)
local P = ctx.page
return {kind="page", page=P.document("My first site", {
P.heading{text="Hello, other worlds!"},
P.paragraph{text="testing"},
P.link{text="Explore the Hub", href="hub://directory/"}
})}
endRequest context
| Member | Meaning |
|---|---|
| ctx.method | GET for navigation; POST for forms |
| ctx.path | Rooted site path, such as / or /greet |
| ctx.fields | Submitted string or boolean field values |
| ctx.requestId | Request identifier, not a secret or user identity |
| ctx.page.document(title, children) | Build a version-1 page |
| ctx.page.<component>{...} | Build any documented component |
| ctx.read(key, default) | Read persistent site data |
| ctx.write(key, value) | Write JSON-compatible site data on POST |
Response types
-- Render a document
return {kind="page", page=P.document("Title", {P.paragraph{text="Hello"}})}
-- Navigate within this site
return {kind="redirect", path="/"}
-- Report an input or route error
return {kind="error", status=400, message="Please enter a name"}
-- Fall back to a static JSON file on GET
return nilRoute before doing work
Test both ctx.method and ctx.path before handling a form. Return nil for static GET fallback, or an explicit 404 error for unknown routes. Do not change data merely because someone opens a page.
Available cloud Lua functions
The environment exposes assert, error, ipairs, pairs, next, pcall, select, tonumber, tostring and type, plus math, string, table and utf8. It does not expose print, os, io, shell, fs, http, peripheral, require, package, load or debug. There is no arbitrary network access.
Every cloud request starts fresh. Variables and globals from an earlier request are gone. Local hosts use the installed computer’s Lua environment and privileges, so local success does not prove cloud compatibility. Use only the shared ctx API for portable handlers.
Found a mismatch? Include the exact error, runtime version and a small example with secrets removed.