# Native router example A runnable TypeScript + Rust application based on Forma’s official `native-router` starter. Home and About have distinct interactive islands. A typed persistent layout keeps its counter and input while each destination gets fresh server props. The npm and Cargo manifests and locks are the version authority for this download; use the coordinated versions they record together. ## Run locally ```sh cd admin npm ci --ignore-scripts npm run build cd .. CARGO_BUILD_JOBS=3 cargo run --locked ``` Open http://localhost:3000. `FORMA_PORT=0` selects an available loopback port; startup prints `FORMA_LISTENING` after binding. Rebuild admin and restart the server after edits. No accounts, database or external services are required. ## Try the ownership boundaries 1. Increment the layout and edit its note. 2. Open About: the layout keeps its exact nodes and state. About’s button adds two, proving its different island is active. Home’s departed island is disposed. 3. Submit a server seed. Rust validates one `count` from 0 to 9999 and sends fresh typed props. Browser clicks do not change that seed or persist data. 4. Use Back and Forward. Open `/about?count=42` directly or refresh it: HTML already contains the server value. 5. Choose Reset with a full document. The retained layout starts over. 6. Disable JavaScript. Both pages, ordinary links and GET forms still work; counter buttons require JavaScript. `admin/build.ts` compiles three independent owners and one closed, verified eager navigation group. The shell outlet sits outside the layout island. The generated bootstrap supplies registrations to `src/navigation.ts`, which uses public `createRouter` and `createNativeAdapter`. Rust binds typed handles and finalizes all modules before listening, then composes opaque owners with `NavigationBranch`. Normal requests receive a complete `PageResponse`; admitted enhanced requests receive the corresponding typed branch. No fetched executable code is replayed. ## Scope This is a public, stateless learning example. Its constant `public-v1` context is appropriate only for public content. It has GET forms and no mutation/authentication system. Add server-side authentication, authorization, Origin/CSRF checks and an opaque context generation before retaining private state or adding writes. `SealedNavigationPolicy::page_response_only` declares the complete effective response policy with an empty POST action allowlist. GET forms need no POST action declaration; this example enhances no POST endpoints. Preserve complete responses, fresh CSP nonces, no-store and the immutable group assets. If a proxy or middleware adds route-dependent policy, use document navigation until that deployment meets the profile. The first native group deliberately excludes dynamic code loading, custom elements, SVG and resource-loading markup within owners. This two-page group loads its bootstrap on both pages. For a deliberately script-free page, use the website’s Form counter or the separate minimal starter. Field Notes remains the companion example for durable validated inventory writes; this router example does not replace its persistence lesson. The source archive contains authored files and both dependency locks. It excludes installed dependencies, build output, local data, secrets and hosting instructions. Run `cargo test --locked` for the bounded request-prop checks. Browser acceptance for this application is maintained alongside the website’s downloaded-example checks; a local run does not deploy or publish anything.