---
name: mystique-routing
description: "Mystique routing architecture: HashRouter URL mapping, manifest structure, page params, link patterns, backButtons, homePath. Derived from repo and manifest evidence."
load: on-demand
relevant-skills:
  - mystique-builder
  - mystique-validate
  - mystique-preview
  - mystique-analyze
  - mystique-diff
  - ui-test
  - ui-record
  - feature-plan
  - implementation-map
---

# Mystique Routing Architecture

Validated 2026-03-06 against repo and manifest evidence from a live Fluent implementation workspace.

## HashRouter — URL Structure

Mystique uses React HashRouter. All navigation is after `#/`:

```
https://account.env.apps.fluentcommerce.com/oms/#/orders/6692/2/ORD-001
                                            ^^^   ^^^^^^ ^^^ ^ ^^^^^^^
                                            app   page   :id :retailerId :ref
                                            path  path   URL params (positional + named)
```

**Sections have NO path.** They are sidebar nav groupings only (icon + label). They do NOT contribute a URL segment.

## Manifest-to-URL Mapping

| Manifest level | Has `path`? | URL contribution | Example |
|---|---|---|---|
| Root manifest (`fc.mystique.manifest.oms`) | Often `homePath` | Can determine default page when present | `"homePath": "orders"` |
| Fragment `routes[].type: "section"` | **No** | None — sidebar nav grouping only | `{ "type": "section", "nav": { "label": "...", "icon": "..." } }` |
| `pages[].path` (list page) | Yes | `#/<path>` | `"path": "orders"` → `#/orders` |
| `pages[].path` (detail page) | Yes | `#/<path>/:params` | `"path": "orders/:id/:retailerId/:ref"` → `#/orders/6692/2/ORD-001` |

### Path variants observed

| Pattern | Example | Notes |
|---|---|---|
| Simple list | `"path": "orders"` | Most common |
| Detail with params | `"path": "orders/:id/:retailerId/:ref"` | Named params (`:id`, `:retailerId`, `:ref`) |
| Detail with fewer params | `"path": "billing/:ref"` | Some entities use ref only |
| Detail with extra context | `"path": "returnFulfilment/:returnOrderRef/:retailerId/:ref"` | Extra parent ref |
| Leading slash | `"path": "/events"` | Seen in insights fragment — may force absolute path |

## Page Query Variables — `{{params.<name>}}`

**CRITICAL: Use `{{params.<name>}}`, NOT `{{<name>}}`.**

Page queries resolve URL parameters via the `params` prefix:

```json
{
  "data": {
    "query": "query ($id: ID!, $ref: String!, $retailerId: ID!) { orderById(id: $id) { ... } }",
    "variables": {
      "id": "{{params.id}}",
      "ref": "{{params.ref}}",
      "retailerId": "{{params.retailerId}}"
    }
  }
}
```

The param names match the `:name` segments in the page path. `{{id}}` without `params.` would look for a data field on the parent context, NOT the URL parameter.

## Link Patterns — `#/` prefix required

List-to-detail links use Handlebars templates with `#/` prefix:

```json
{
  "link": "#/orders/{{node.id}}/{{node.retailer.id}}/{{node.ref}}"
}
```

The `#/` prefix is the HashRouter entry point — without it, navigation breaks.

### Link examples from real manifests

| Context | Link pattern |
|---|---|
| Order list → detail | `"#/orders/{{node.id}}/{{node.retailer.id}}/{{node.ref}}"` |
| Customer link | `"#/customers/{{id}}/{{ref}}"` |
| Billing list → detail | `"#/billing/{{node.ref}}"` |
| Credit memo link | `"#/creditmemo/{{node.ref}}"` |

## Back Buttons (Breadcrumb Navigation)

Observed detail pages define `backButtons[]` in `props` for breadcrumb-style back navigation:

```json
{
  "props": {
    "backButtons": [
      {
        "path": "orders",
        "menuLabel": "i18n:fc.om.orders.detail.breadcrumb.backToOrders"
      },
      {
        "path": "customers/{{orderById.customer.id}}/{{orderById.customer.ref}}",
        "menuLabel": "i18n:fc.om.orders.detail.breadcrumb.viewCustomer"
      }
    ]
  }
}
```

**Key details:**
- `path` is relative (no `#/` prefix) — observed examples omit the hash prefix and rely on the framework to prepend it
- `menuLabel` uses i18n keys or Handlebars templates with data from the page query
- Multiple back buttons create a dropdown menu (e.g., "Back to Orders" + "View Customer")
- Child entity pages link back to parent: fulfilment → order, orderItem → order, creditMemo → billingAccount

### backButton field names

| Field | Purpose |
|---|---|
| `path` | Relative path (no `#/`) — framework adds hash prefix |
| `menuLabel` | Display text — i18n key or `{{i18n 'key'}} ({{data.ref}})` template |

Note: The creditmemos fragment uses `label` instead of `menuLabel` — both appear to work.

## homePath

When present, root manifest `homePath` determines the default page when navigating to the app base URL:

```json
{
  "homePath": "orders"
}
```

Observed pattern: `/oms/` can redirect to `/oms/#/orders` when `homePath` is `"orders"`. Treat exact values as app-specific.

## Cross-Fragment Navigation

Links can target pages in ANY fragment loaded by the same app. The `#/` prefix makes all links absolute within the app's route space. Example: ordermanagement fragment linking to a page defined in another fragment works as long as the target page path exists.

## Common Mistakes

| Mistake | Correct |
|---|---|
| `{{id}}` in variables | `{{params.id}}` |
| `orders/123/...` in link (no hash) | `#/orders/123/...` |
| Adding path to section | Sections have NO path — only `nav` |
| `#/ordermanagement/orders/...` | `#/orders/...` — no section segment |
| Fragment pages at root without section wrapper | Pages must be inside a `type: "section"` with `nav: { label, icon }` — otherwise sidebar menu is empty |
| `#/` in backButtons path | Just `orders` — framework adds `#/` |
