01
Keep routes thin
A route composes content, validated data, metadata, and small interaction boundaries. Keep data access in server-only layers and pass validated results into renderable components.
02
Static by default
A component with no events, Signals, or browser APIs remains an ordinary server-rendered component. Use semantic elements and real anchors for navigation.
03
Interaction stays local
Do not make an entire layout interactive because one button needs state. Extract the small control and mark only the handler with the $ suffix.
- Use readonly props for data that a component does not mutate.
- Never pass secrets or unvalidated API values into JSX.
- Use labels, buttons for actions, links for navigation, and aria-live for async status.
PRACTICAL LABS
Run this capability.
Each example states the observable output, the boundary that remains your responsibility, and the check that proves the result.
01
Keep a component static
TSXexport function ResourceCard({ title, href }: { readonly title: string; readonly href: string }) {
return <article><h2><a href={href}>{title}</a></h2></article>
}- OUTPUT
- The card contributes ordinary server-rendered HTML with no event boundary.
- BOUNDARY
- Use a link for navigation and a button only for an action.
- PROVE IT
- Build the route and confirm no route-specific interaction chunk is required.
VERIFICATION
Prove the contract.
Keyboard-test controls and inspect static page output to ensure essential text, links, and labels exist before scripts load.