Loading...
Loading...
Routes live in src/routes. The folder structure is the URL structure -
there's no route table to maintain. Ossido scans the directory, generates a route
tree into .ossido/, and keeps it in sync as you add files.
src/routes conventionEach folder becomes a URL segment, and special filenames give a folder its behaviour:
The reserved names are page, layout, loading, error, not-found, and
middleware. Any other file in src/routes (a helper, a colocated component) is
ignored by the router, so you can keep related code next to a route.
A route's view is a page.tsx (or page.mdx); its optional data loader is a
page.rs alongside it:
page.tsx / page.mdx - the React component (or Markdown) rendered for the
route.page.rs - a Rust #[handler] that produces the page's data. Its return
value becomes the page component's typed props.A page without a page.rs just renders with no server data - perfect for static
content like these docs. See
Page & Layout Handlers for what goes in a
page.rs.
Wrap a segment in square brackets to capture it. A folder named [pokemon]
matches /pokemons/pikachu, /pokemons/charizard, and so on, and the value is
read from the request params in the handler:
A [...slug] segment matches the rest of the path across multiple segments -
useful for docs trees or any nested content. Inside the handler, the joined path
arrives under the param name (slug here).
For static builds, you enumerate which paths to generate with #[static_paths]
(see SSR, SSG & Streaming).
A layout.tsx wraps the pages beneath it, receiving them as children. The root
src/routes/layout.tsx renders the <html>/<body> shell (header, footer,
global styles); nested layouts wrap a subtree - this docs section uses one for its
three-column shell.
Note the split: layout.tsx is a client-rendered wrapper component, whereas
layout.rs (if present) is a data handler for the layout - only the .rs
form is a server route.
A loading.tsx is the Suspense fallback shown for its route while data resolves:
An error.tsx is a route's error boundary: it renders in place of the subtree
when a descendant route throws during render, a data resource rejects, or the
route's Rust handler fails. It receives the thrown error and a reset callback
that retries the boundary's children.
Place one at the root to catch the whole app, or in any subtree to scope recovery to that branch. See Error Handling for the props, boundary behaviour, and the server-side reporting hook.
A not-found.tsx renders the UI for unmatched routes. Place one at the root for a
site-wide 404; the root layout wires it into the route tree.
Files under src/routes/api are HTTP endpoints with no React view - a .rs file
with an #[api(METHOD)] handler. api/health_check.rs serves /api/health_check:
A middleware.rs attaches a Tower layer to its segment. At the root it applies to
every route; under api/ it applies to the API routes. It's collected via the
middleware path, not as a route.
See Page & Layout Handlers for handlers and
request handling, API Handlers for #[api], and
Middleware for #[middleware].
Next: Ossido Application · Back to Configuration