Build pages with the Elm Architecture
Each page is a self-contained module with its own model, update, and view functions. Simple, predictable, and easy to reason about.
src/Pages/Page.fs
type Model = { Count: int }
type Msg =
| Increment
| Decrement
let init () =
{ Count = 0 }, Command.none
let update msg model =
match msg with
| Increment -> { model with Count = model.Count + 1 }, Command.none
| Decrement -> { model with Count = model.Count - 1 }, Command.none
let view model dispatch =
Html.div [
Html.button [ prop.onClick (fun _ -> dispatch Decrement); prop.text "-" ]
Html.span [ prop.text (string model.Count) ]
Html.button [ prop.onClick (fun _ -> dispatch Increment); prop.text "+" ]
]
localhost:5173
0
Route pages with the file system
Just create files in the Pages directory and Elmish Land automatically generates routes. No manual route configuration needed.
Project Structure
📂src/Pages/
📄Page.fs
→/
📂About/
📄Page.fs
→/about
📂Blog/
📂Post/_Slug/
📄Page.fs
→/blog/:slug
Type-safe from URL to page
Define your route parameters in a simple JSON file and get fully typed, parsed route objects in your page functions. No string parsing, no runtime errors.
src/Pages/Blog/route.json
{
"queryParameters": [
{
"type": "int",
"name": "page"
}
]
}
src/Pages/Blog/Page.fs
// Route parameters are parsed and typed automatically
let page (shared: SharedModel) (route: BlogRoute) =
// route.Page : int option (query parameter)
Page.from init update view () LayoutMsg
Type-Safe Routes
🔒myapp.com/blog?page=2
Parsed Route
page : int option = Some 2