Pages & Layouts
Routing follows the folder tree under app/. A folder's page.jsx is its route.
app/ ├─ page.jsx # / ├─ about/page.jsx # /about └─ blog/page.jsx # /blog
Layouts
A layout.jsx wraps every route at or below its folder. Render the active route with props.children:
export default function Layout(props) { return ( <div class="shell"> <Nav /> <main>{props.children}</main> </div> ); }
Layouts nest: app/layout.jsx wraps app/blog/layout.jsx wraps app/blog/page.jsx.
Metadata
Export metadata or generateMetadata from a page or layout to control <title>, descriptions, Open Graph tags, and canonical URLs. Layout defaults merge down the tree; pages override what they need. On SSG and SSR each route gets a full resolved <head>; on a plain CSR build only the root layout's site-wide fields (favicon, description, Open Graph site defaults) are injected into the shared index.html shell — per-page title and canonical require --ssg or otfw serve. See Metadata & SEO.
Not found
app/404.jsx renders when no route matches.
export default function NotFound() { return <h1>Page not found</h1>; }