pesde bizwiz3 / nova

Routing Guide

Nova uses a filesystem-based router. This means the structure of your app directory directly defines the URL structure of your API or website.

Directory Structure Rules

Nova recursively scans the app folder for route.luau files. Each file represents a set of HTTP handlers for that specific path.

URL PathFilesystem Location
/app/route.luau
/auth/loginapp/auth/login/route.luau
/posts/:idapp/posts/[id]/route.luau

Defining Handlers

Inside a route.luau file, you export a table where keys correspond to HTTP methods (e.g., get or Get).

local Nova = require("@path/to/nova")

local Route = {}

function Route.Get(req)
    return Nova.response({ body = "Hello GET" })
end

function Route.Post(req)
    return Nova.response({ body = "Hello POST" })
end

return Route

Dynamic Routing

To create a dynamic route, wrap a folder name in square brackets [ ]. This tells Nova that the segment is a variable that should be captured.

Example: User Profiles

If you create app/users/[id]/route.luau, it will match URLs like /users/123 or /users/john

You can access these variables via the req.params table:

-- app/users/[id]/route.luau
local Nova = require("@path/to/nova")
local User = {}

function User.Get(req: Nova.RequestWith<{ id: string }>)
    local userId = req.params.id

    return Nova.response({
        body = {
            message = "Fetching data for user: " .. userId
        }
    })
end

return User

Nested Parameters

Nova supports multiple dynamic segments in a single path.

  • Path: app/orgs/[orgId]/members/[memberId]/route.luau

  • URL: /orgs/nova-team/members/admin

  • Access: req.params.orgId and req.params.memberId

Trailing Slashes

Nova automatically normalizes incoming URLs. A request to /users/ is treated exactly the same as a request to /users, preventing duplicate route errors.

Next Steps

After defining your routes, learn how to protect them or add pre-processing logic in the Middleware guide.