---
path: /domains/[domainId]
surface: customer
domain: shell-routing
auth: signed-in
source: apps/oshun/web/src/app/domains/[domainId]/page.tsx
status: walked
last_walked:
  '2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data
  (2xx), console/page-errors, expected content, screenshot verified; live
  screen-reader, touch, offline, and telemetry-delivery checks pending a manual
  AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md'
---

# `/domains/[domainId]` — Canonical domain experience

## Purpose

Long-form domain route. Picks per-domain SEO metadata from a static
`DOMAIN_META` table and renders the shared `DomainRouteExperience` client
composition with a sanitised single-value `searchParams` shape. Unlike
`/d/[domain]/[[...path]]` (which only redirects), this route mounts the actual
UI for the domain.

## Entry points

- Quick-actions and shell nav that prefer the canonical `/domains/<id>` form
- Domain card on `/` (DomainCardGrid → canonical route)
- Cross-domain bridge links
- Recommendation cards
- Direct URL / bookmark — yes (auth required)
- `?origin`, `?stack`, `?path`, `?ref`, `?offline`, `?reason`, `?unavailable`
  query params (all forwarded to `DomainRouteExperience`)

## Layout regions

`page.tsx` is a server component. Validates `params.domainId` against
`isWebNavigableDomainId` (calls `notFound()` if invalid). Otherwise renders
`<DomainRouteExperience domainId={domainId} searchParams={...}>` with a
single-value-flattened search-param shape (`toSingle()` collapses arrays to
their first entry).

- **`DomainRouteExperience`**: the actual domain composition. Layout regions
  live in `apps/oshun/web/src/components/DomainRouteExperience.tsx`. Walker
  should confirm region names by reading that file; from the page contract:
  - Honours `origin`, `stack`, `path`, `ref` for navigation context
  - Honours `offline`, `reason`, `unavailable` for fallback / framing states

## States

- [ ] **Unknown domainId** — fails `isWebNavigableDomainId` → `notFound()`
- [ ] **Known domain (default)** — `<DomainRouteExperience>` renders the
      domain's canonical experience
- [ ] **`?origin=home`** — domain mounted with home-origin context
- [ ] **`?stack=<name>`** — verify what `stack` controls
- [ ] **`?path=<sub>`** — domain mounts at a deep sub-path
- [ ] **`?ref=<source>`** — referrer attribution
- [ ] **`?offline=1`** — domain mounts in offline framing
- [ ] **`?reason=<code>`** — reason for unavailable / framing surface
- [ ] **`?unavailable=1`** — unavailable framing surface
- [ ] **Anonymous user** — middleware redirects to `/welcome`
- [ ] **Standalone PWA** — verify shell renders cleanly

## Interactions

Interactions live inside `DomainRouteExperience` and are domain-specific. The
page itself contributes:

- No DOM-level interactions; pure wiring of params → component.

### Per-domain SEO metadata

`generateMetadata` picks copy from `DOMAIN_META`:

- **tara**: "Tara — Meditation & Breathwork" / OG "Tara | OSHUN — Meditation &
  Mindfulness"
- **veritas**: "Veritas — Truth & Information" / OG "Veritas | OSHUN —
  Truth-Seeking & Knowledge"
- **nyx**: "Nyx — Night Sky & Astronomy" / OG "Nyx | OSHUN — Night Sky
  Exploration"
- **arete**: "Arete — Growth & Habits" / OG "Arete | OSHUN — Personal Growth &
  Excellence"
- **nisaba**: "Nisaba — Primary Texts & Scholarship" / OG "Nisaba | OSHUN —
  Texts, Commentary & Research"
- **metis**: "Metis — Learning & Tutoring" / OG "Metis | OSHUN — Learning,
  Tutoring & Mastery"

Each carries:

- `alternates.canonical: '/domains/<id>'`
- OG image: `/og/domain-<id>.png`
- Twitter `summary_large_image` card

Unknown domains return `{ title: 'Domain' }` (and `notFound()` from the page
body).

## Data & contracts

- **Reads**:
  - `params.domainId: string`
  - `searchParams: Record<string, string | string[] | undefined>`
- **Writes**: none from this page
- **Realtime**: none
- **Caching**: not explicitly cached at this level; `DomainRouteExperience`
  manages its own
- **Auth/role check**: not in `PUBLIC_PREFIXES`; signed-in only
- **Metadata**: `generateMetadata` resolves per-domain title / description / OG
  / Twitter

## Cross-references

- Sibling shell-routing helper: [`d-domain-path.md`](./d-domain-path.md)
- Canonical domain walkthroughs:
  - [`../03-tara/tara.md`](../03-tara/tara.md)
  - `../04-arete/`, `../05-veritas/`, `../06-nyx/`, `../07-nisaba/`,
    `../08-metis/`
- Component sources:
  - `apps/oshun/web/src/components/DomainRouteExperience.tsx`
  - `apps/oshun/web/src/navigation/routes.ts` (`isWebNavigableDomainId`)

## Open questions / known gaps

- [ ] Read `DomainRouteExperience.tsx` to enumerate the actual layout regions
      and per-domain branching behaviour
- [ ] Document the full set of `path`, `origin`, `stack`, `ref` values
      `DomainRouteExperience` recognises
- [ ] Confirm OG image routes (`/og/domain-<id>.png`) exist for all six domains
- [ ] Confirm whether `/domains/[domainId]` is the canonical route per domain or
      whether per-domain routes (`/tara`, `/veritas`, etc.) are preferred —
      affects coverage in `matrix/routes.csv`
- [ ] No telemetry tagged from this routing layer; verify
      `DomainRouteExperience` emits domain-entry events
