Persistent site storage
Keep data across requests with ctx.read and ctx.write, instead of global variables.
On this page
A complete persistent counter
GET reads the counter without changing it. POST /increment saves the next value, then redirects to / so the browser displays the updated page. Try it in preview and again after reopening the site. Local preview uses the local site’s real data, so preview form submissions can change that data.
return function(ctx)
local P = ctx.page
local count = ctx.read("counter", 0)
if ctx.method == "POST" and ctx.path == "/increment" then
ctx.write("counter", count + 1)
return {kind="redirect", path="/"}
end
if ctx.method ~= "GET" or ctx.path ~= "/" then
return {kind="error", status=404, message="Page not found"}
end
return {kind="page", page=P.document("Community counter", {
P.heading{text="Count: " .. tostring(count)},
P.form{action="/increment", children={P.submit{text="Add one"}}}
})}
endKeys and values
For portability, use storage keys of 2–40 lowercase letters, digits or hyphens, beginning with a letter or digit. The cloud accepts a somewhat broader key set; local hosts use the stricter site-name rule.
Store strings, booleans, numbers and JSON-compatible tables. Do not store functions, cyclic structures or host objects. ctx.read(key, default) returns default when the key is absent. ctx.write is allowed only on POST requests. There is no dedicated delete-key API.
Where the data lives
Publishing code does not migrate your local data. Test with disposable data and plan any real migration separately. Keep local backups of your site folder and protect private identity state separately.
| Local host | Lantern Hub |
|---|---|
| /lantern-data/sites/<name>/data/<key>.json | Site-scoped cloud database storage |
| Stored on the Minecraft computer | Survives fresh execution VMs |
| Excluded from Upload Hub draft | Not copied from local preview storage |
Concurrency and limits
The current cloud site storage limit is 128 KiB. Conflicting concurrent writes are rejected rather than silently overwriting one another. The counter is a teaching example, not a transactional high-traffic counter service. Reload and inspect state before resubmitting a conflicting action.
Keep guestbooks and lists bounded. The guestbook template retains a limited number of entries. Data is scoped to a site, but any visitor can invoke routes you expose; your handler is responsible for what those routes allow.
Found a mismatch? Include the exact error, runtime version and a small example with secrets removed.