Beta documentation. This is an early preview — content is still in active development. Feedback helps shape the final release. Share your thoughts or join the discussion.

Static Files (ZIP)

Upload a ZIP bundle of HTML, CSS, JS, and images — serve it as if it were real files on your domain. No per-file upload. No folder structure to manage.

On this page

Serve a ZIP as static files

Upload a ZIP bundle of HTML, CSS, JS, and images — serve it as if it were real files on your domain. No per-file upload. No folder structure to manage.

app:mount("/")

That's it. If your ZIP contains index.html and style.css:

  • / → serves index.html
  • /style.css → serves style.css

Files that don't exist in the ZIP fall through to your routes.

Mount at a sub-path

app:mount("/assets/")

-- /assets/logo.png → serves logo.png from ZIP
-- /api/users       → handled by your routes

Custom handler for cache control

Set cache headers for specific file types:

app:mount("/assets/", function(ctx, items, path)
    if path:match("%.css$") or path:match("%.js$") then
        ctx:set_header("Cache-Control", "public, max-age=604800")  -- 7 days
    end
    if path:match("%.png$") or path:match("%.jpg$") then
        ctx:set_header("Cache-Control", "public, max-age=2592000") -- 30 days
    end
    return path
end)

Mount a specific ZIP by hash

app:mount("/theme/", nil, "abc123def456789...")

This lets you version your assets — upload a new ZIP, change the hash, instant rollback.

Combining with routes

Serve a React/Vue frontend from ZIP, and an API from Lua:

local app = framework()

-- Frontend (from ZIP)
app:mount("/")

-- API (from Lua)
app:group("/api/v1", function()
    app:get("/users", listUsers)
    app:post("/users", createUser)
end)

-- SPA fallback: any unmatched URL serves index.html
app:get("*", function(ctx)
    return ctx:render("index", {})
end)

Mount multiple ZIPs

app:mount("/")             -- main site from one ZIP
app:mount("/blog/", nil, "hash_for_blog_theme")
app:mount("/docs/", nil, "hash_for_docs_theme")

Each prefix gets its own ZIP. Requests fall through in registration order.

Note: Static files from ZIP are served from memory — no disk I/O. Fast and efficient.

Next: Configuration — debug mode, logging, env vars.

Previous Input Validation Next Configuration