Docs
Router Plugin
RouterPlugin is an optional, framework-agnostic plugin that discovers filesystem routes and generates a virtual router module.
Configure The Router
Add RouterPlugin to the build context and import its virtual module.
router_plugin = Klenod::Build::Plugins::RouterPlugin.new(
specifier: "virtual:router",
pages_dir: "routes"
)
context = Klenod::Build::Context.new(
source_dir: "src",
plugins: [
*Klenod::Build::Context.default_plugins,
router_plugin
]
)
router = context.entry("virtual:router").exports::Default
match = router.match("/blog/hello")
In an application config, either append router_plugin to Context.default_plugins or provide a full ordered plugin list.
Supported Files And Segments
The router discovers +page.rb, +page.haml, +route.rb, +layout.rb, +layout.haml, +error.rb, +error.haml, +not-found.rb, and +not-found.haml.
Supported segment forms include:
[id]dynamic segments.[...slug]catch-all segments.[[...slug]]optional catch-all segments.(marketing)route groups.@modalparallel route slots.(.)photo,(..)profile, and(...)loginintercepted route segments.
Match Results
A route match exposes the selected modules and structural metadata:
match.page
match.handler
match.layouts
match.slots
match.params
match.route
Generated router modules use lazy_import so matching a route can load only the selected page, handler, layouts, and slots.
When no page route matches, the router returns the closest not-found module for that URL path. Frameworks can use the closest error module when rendering raises.
Framework Boundary
RouterPlugin does not decide request dispatch or rendering policy. Hybrid directories can contain both a page and +route.rb; the router exposes both and the consuming framework decides which one to use for a request.
The example configures Example::Framework::Route as the route-handler base class. It makes Response and localized_path available directly inside +route.rb files.
The example application keeps its document shell in /root.haml, separately from filesystem route layouts. RouterApp composes the matched page and layouts, discovers their route-scoped assets, and passes the ordered asset references only to the root component. The root Haml template renders html, head, body, stylesheet links, module scripts, and the composed route content.
Route content remains lazy until the document is prepared, so a provide_context boundary in the root can wrap route components. Preparation evaluates every component and lazy child once under the active request and rendering contexts. A route can render %title to replace the root templates default document title; preparation collects all title declarations before output starts, and the last declaration wins.
After preparation, HTML serialization can stream the normalized document without JavaScript, string-range replacement, or component rerendering. The final title is emitted at the root titles location, while later declarations are omitted from their original locations.