Routing
Routing is path based and inspired by Next.js.
Hereβs the basic structure of a potential blog application:
app/root.cssroot.hamlcomponents/Layout/Footer.hamlHeader.hamlLayout.hamlPage.haml
UI/Button.hamlHeading.hamlHr.hamlLink.haml
pages/about/+page.haml
posts/[id]/+page.haml
+page.haml+layout.haml
+page.haml+layout.haml
app/root.haml contains the <html> tag, and all pages are wrapped in
the layouts of their parent directories.
This tree would generate the following routes:
/posts/:id/posts/about/
Not found
A +not-found.haml file is rendered when no page matches a path. The
closest one wins: app/pages/posts/+not-found.haml handles /posts/nope,
and app/pages/+not-found.haml handles everything else.
A page that matches but has nothing to show can raise NotFound while it
renders. The closest +not-found.haml for the current path takes over,
and the first request responds with status 404:
:ruby
Post = import("/models/Post")
- post = Post.find($params[:id])
- raise NotFound unless post
%h1= post.title
NotFound is navigation rather than an error, so error boundaries do not
see it and nothing is logged. A +error.haml file handles other exceptions.
Route handlers
A +route.rb file handles HTTP requests for its directory. Public methods
are named after HTTP verbs and return [status, headers, body]:
# app/pages/api/health/+route.rb
def GET(_request)
[200, {"content-type" => "application/json"}, '{"status":"ok"}']
end
A route can have both +page.haml and +route.rb. Browser HTML requests
render the page; non-HTML requests are handled by the route handler.