---
path: /d/[domain]/[[...path]]
surface: customer
domain: shell-routing
auth: signed-in
source: apps/oshun/web/src/app/d/[domain]/[[...path]]/page.tsx
status: walked + e2e-covered
last_walked:
  '2026-07-01 by Codex (canonical /d redirect edge states covered in
  canonical-deep-links.spec.ts: authenticated no-path, single-segment, nested
  path, repeated query params, query path override, no visible /d terminal URL,
  PWA relaunch through a short link, anonymous welcome redirect preservation,
  and unknown-domain not-found UI), against commit HEAD'
  '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'
---

# `/d/[domain]/[[...path]]` — Canonical domain redirect

## Purpose

Server-only redirect helper. Takes a short-form `/d/<domain>/<rest>` URL and
rewrites it to the canonical web route for the domain via
`buildWebDomainRoutePath`, preserving any query string and packing the catch-all
path into a `?path=<rest>` parameter. There is no UI rendered — this is purely a
routing primitive.

## Entry points

- Cross-domain quick-links that target the short form (e.g., a recommendation
  card linking to `/d/tara/sit/123`)
- External bookmarks / emails using the short form
- Manually typed URLs (`/d/<domain>`)
- Internal shell-nav consumers that prefer the short scheme

## Layout regions

`page.tsx` returns `null` after performing one of two server actions:

- `notFound()` when `params.domain` is not a `WebNavigableDomainId` (per
  `isWebNavigableDomainId`)
- `redirect(target)` to the resolved canonical URL otherwise

There is **no UI** for this route. The visible result is either a 404 page
(handled by Next.js) or the destination view after the redirect.

## States

- [x] **Unknown domain** — `params.domain` fails `isWebNavigableDomainId` →
      `notFound()` triggers Next.js `not-found.tsx`
- [x] **Known domain, no path** — redirects to `buildWebDomainRoutePath(domain)`
      preserving query string
- [x] **Known domain, single path segment** — `params.path = ['sit']` →
      canonical path with `?path=sit`
- [x] **Known domain, nested path** — `params.path = ['sit', '123']` → canonical
      path with `?path=sit/123`
- [x] **Query params present** — incoming query values are preserved (including
      repeated params via `URLSearchParams.append`); when a catch-all route path
      exists, it becomes the authoritative `path` query value.
- [x] **Anonymous user** — middleware redirects to `/welcome` before reaching
      this route and preserves the full short-link target in `redirect=`.
- [x] **PWA cold start** — redirect resolves before hydration; user lands
      directly on the canonical route
- [x] **Reduced motion / offline / a11y** — N/A; no UI. Covered as a routing
      primitive by asserting the final URL and destination shell, not animation
      or interactive semantics.

## Interactions

No interactive elements on this route.

- [x] Verify the redirect resolves before the browser shows the URL bar with
      `/d/...` (server-side `redirect()` happens during the request, but client
      navigation may flash the short URL — confirmed by asserting the final
      Playwright URL never remains on `/d/<domain>` after navigation and PWA
      relaunch)

## Data & contracts

- **Reads**:
  - `params.domain: string`, `params.path?: string[]`
  - `searchParams: Record<string, string | string[] | undefined>`
- **Writes**: none
- **Realtime**: none
- **Caching**: not applicable; redirect is computed per request
- **Auth/role check**: signed-in. `/d/*` is not in `PUBLIC_PATHS` or
  `PUBLIC_PREFIXES`, so anonymous requests are gated by `proxy.ts` and
  redirected to `/welcome?redirect=<encoded short link>`.
- **Utilities**:
  - `isWebNavigableDomainId(domain): boolean`
  - `buildWebDomainRoutePath(domain): string`
  - Local `serializeSearchParams(...)` helper to round-trip the query string
- **Metadata**: none declared

## Cross-references

- Sibling routing helper: [`domains-domainId.md`](./domains-domainId.md)
- Canonical destinations (per domain) live under `../03-tara/`, `../04-arete/`,
  `../05-veritas/`, `../06-nyx/`, `../07-nisaba/`, `../08-metis/`
- Navigation utilities: `apps/oshun/web/src/navigation/routes.ts`
  (`buildWebDomainRoutePath`, `isWebNavigableDomainId`)
- E2E:
  [`apps/oshun/web/e2e/canonical-deep-links.spec.ts`](../../../apps/oshun/web/e2e/canonical-deep-links.spec.ts)
  covers the full authenticated domain-id matrix, no-path redirects,
  single-segment and nested catch-all paths, repeated query preservation, stale
  incoming `path` replacement, PWA relaunch through `/d/*`, anonymous welcome
  redirect preservation, and unknown-domain not-found handling.

## Open questions / known gaps

- [x] `/d/*` requires sign-in: `proxy.ts` leaves it outside the public sets, and
      `canonical-deep-links.spec.ts` verifies anonymous redirect preservation.
- [x] Canonical destinations are `/domains/tara`, `/domains/veritas`,
      `/domains/nyx`, `/domains/arete`, `/domains/nisaba`, and `/domains/metis`
      via `WEB_NAVIGABLE_DOMAIN_IDS`; all six are covered in
      `canonical-deep-links.spec.ts`.
- [x] Catch-all path is folded into `?path=<rest>` rather than a destination
      path segment; the same spec verifies single, nested, and stale incoming
      `path` replacement cases against hydrated destination shells.
- [x] Redirect telemetry: there is no app-side telemetry hook on this
      server-only route. Attribution for arrivals via `/d/*` vs canonical URLs
      would require new product instrumentation and is not part of the current
      V1 route contract.
- [ ] Browser `Referer` propagation is governed by normal
      browser/referrer-policy behavior after the App Router redirect and is not
      modified by the route; add a cross-origin referrer contract only if
      product analytics requires it.
