Skip to main content
A view is a version of the UI in a slot, matched to a context. The contract names those contexts and describes the data available in each one. A global side panel might show an overview on a members list, then details about one member when you open their page. The panel stays in place; its view changes.

Define the contexts

Use paths to describe a hierarchy, from general to specific:
patchsmith.ts
/ is a default context. These names don’t need to match your browser URLs. Each slot lists the contexts it supports and can have a different view for each.

Register the current context

Call useViewContext inside your Patchsmith provider. Register general contexts in layouts and specific contexts in pages:
The hook registers the context when mounted, validates its data, and updates it when values change. On unmount, it removes that registration. Register each declared ancestor too, as the layouts above do.

Select the closest matching view

Patchsmith uses the deepest mounted context. For each slot, it checks that path, then its parents, selecting the first supported view supplied by the app:
On the members list, the panel can show an overview. Opening a member registers /members/detail, so the panel switches to that member’s view. Leaving the page unregisters it and returns to the overview. The same works for a global navbar. If no matching view is available, nothing renders for that app in the slot. To write those views, see Write app UI.

SDK reference

defineContract({ views }) maps paths starting with / to object schemas. Context fields from declared ancestors combine with the selected view’s fields. Child schemas cannot repeat ancestor field names. A fallback receives its own context and its ancestors’ context, excluding fields from deeper paths. Call patchsmith.useViewContext(path, state) on the client returned by createClient:
While member data loads, register the context with loading: true:
While member data loads

Frequently asked questions

Register context from your pages and layouts. Slots and apps can each support a subset of contexts.
Call useViewContext in each relevant page or layout. Its mount and unmount lifecycle supplies the active context, so it works with different routers.
No. A slot can support a subset, and an app can provide a subset of those views. Matching falls back through parent paths. Without a match, that app’s UI is hidden.