Layouts
RedwoodSDK provides a powerful layout()
function for creating shared UI layouts across your routes. This allows you to maintain consistent page structures, implement nested layouts, and avoid code duplication.
Key Features
- Composable: Works seamlessly with existing
prefix()
,render()
, androute()
functions - Nested Support: Multiple
layout()
calls create properly nested component hierarchies - SSR/RSC Safe: Automatic client component detection prevents serialization errors
- Middleware Friendly: Preserves middleware functions in route arrays
Example with Code
-
Create a layout component:
src/app/layouts/AppLayout.tsx import type { LayoutProps } from 'rwsdk/router'export function AppLayout({ children, requestInfo }: LayoutProps) {return (<div className="app"><header><nav><a href="/">Home</a><a href="/about">About</a></nav>{requestInfo && (<span>Path: {new URL(requestInfo.request.url).pathname}</span>)}</header><main>{children}</main><footer>© {new Date().getFullYear()}</footer></div>);} -
Use the layout in your routes:
src/app/worker.tsx import { layout, route, render } from 'rwsdk/router'import { AppLayout } from './layouts/AppLayout'import HomePage from './pages/HomePage'import AboutPage from './pages/AboutPage'export default defineApp([render(Document, [layout(AppLayout, [route("/", HomePage),route("/about", AboutPage),])])]) -
Create nested layouts:
src/app/layouts/AdminLayout.tsx import type { LayoutProps } from 'rwsdk/router'export function AdminLayout({ children }: LayoutProps) {"use client" // Client component examplereturn (<div className="admin-panel"><aside>Admin Sidebar</aside><div className="admin-content">{children}</div></div>);} -
Combine layouts with other router functions:
src/app/worker.tsx export default defineApp([render(Document, [layout(AppLayout, [route("/", HomePage),prefix("/admin", [layout(AdminLayout, [route("/", AdminDashboard),route("/users", UserManagement),])])])])])
Layout Props
Layout components receive two props:
children
: The wrapped route contentrequestInfo
: Request context (only passed to server components)
There’s a specific type for the LayoutProps
prop:
import type { LayoutProps } from 'rwsdk/router'
export function AppLayout({ children, requestInfo }: LayoutProps) {...
Complex Composition
Each of these examples work:
prefix("/api", layout(ApiLayout, routes)) // ✅layout(AppLayout, prefix("/admin", routes)) // ✅render(Document, layout(AppLayout, routes)) // ✅``