src/routes/ becomes a URL. Protected, org-scoped pages live under src/routes/_app/organizations/$slug/ and automatically inherit session verification and organization context from their parent layouts — so you focus on your page logic, not auth boilerplate.
Route naming conventions
The directory prefix determines who can access a route and what layout wraps it:
The
$slug segment is a dynamic parameter — TanStack Router fills it with the URL segment and makes it available via Route.useParams().
Add a new org-scoped page
The following three steps create a fully functional, SSR-ready page scoped to an organization. The pattern mirrors every existing page in the boilerplate.1
Create the route file
Create The parent route file (
src/routes/_app/organizations/$slug/my-page.tsx. The filename becomes the URL path segment — this page will be reachable at /organizations/:slug/my-page.route.tsx) already validates that the user is a member of the organization. If getOrgBySlug returns null, it redirects to /organizations before your loader runs.2
Create the server function
Create
src/server/my-fns.ts. Server functions run exclusively on the Nitro server — they never ship to the client bundle.3
Register the query option
Add a
queryOptions factory to src/server/query-keys.ts. Defining the cache key here means the SSR loader and the client component share exactly the same key — TanStack Query will not re-fetch data that was already seeded on the server.Access loader data from parent routes
The$slug/route.tsx loader fetches the organization and exposes it to all child routes. Import the parent route and call useLoaderData():
