Guide / 05

File-Based Routing

The structure of the pages/ directory fully defines the application's routing. No routing configuration is necessary.

File Conventions

pages/
β”œβ”€β”€ @layout.stew           β†’ Root layout (wraps all pages)
β”œβ”€β”€ @page.stew             β†’ GET /
β”œβ”€β”€ about/
β”‚   └── @page.stew         β†’ GET /about
β”œβ”€β”€ blog/
β”‚   β”œβ”€β”€ @layout.stew       β†’ Nested layout for /blog/*
β”‚   β”œβ”€β”€ @page.stew         β†’ GET /blog
β”‚   └── __slug__/
β”‚       └── @page.stew     β†’ GET /blog/{slug}
└── api/
    └── users/
        └── server.go      β†’ Custom Go handlers (POST, DELETE, etc.)

URL Parameters

A folder named __param__ creates a dynamic parameter in the URL. Accessible via data.Params["param"]:

<!-- pages/users/__id__/@page.stew -->
<p>User Profile: {{ data.Params["id"] }}</p>

Generates the route: GET /users/{id}

Query Parameters

Query parameters are accessible via data.Query (of type url.Values):

<goscript>
    import "strconv"

    page := 1
    if p := data.Query.Get("page"); p != "" {
        page, _ = strconv.Atoi(p)
    }
</goscript>

<p>Page {{ page }}</p>

Router Generation

The stew generate command scans pages/ and generates stew_router_gen.go:

// Code generated by Stew. DO NOT EDIT.
func RegisterStewRoutes(mux *http.ServeMux) {
    // Static assets
    mux.Handle("GET /static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))

    // Route /
    mux.Handle("GET /", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        data := stew.PageData{URL: r.URL.Path, Query: r.URL.Query(), ...}
        pages.Layout(w, data, func() {
            pages.Page(w, data)
        })
    }))

    // Parameterized route
    mux.Handle("GET /users/{id}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        data.Params["id"] = r.PathValue("id")
        stew_pages_users_id.Page(w, data)
    }))
}
⚠️ Do not modify stew_router_gen.go β€” This file is completely regenerated with each stew generate.

Static Assets

All files placed in static/ are automatically served under the /static/ prefix. The static/wasm/ folder contains generated Wasm binaries.

<link rel="stylesheet" href="/static/style.css">
<img src="/static/images/logo.png">