Pages & Layouts

Routing follows the folder tree under app/. A folder's page.jsx is its route.

TEXT
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:

JSX
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.

JSX
export default function NotFound() {
  return <h1>Page not found</h1>;
}