> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tagada.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Storefront templates

> The Tagada Rx template catalog: three funnel archetypes, one shared skeleton, live demos — and the matrix showing how each template maps onto the same Rx building blocks.

# Storefront templates

Tagada ships ready-made Rx storefront templates (Plugin SDK apps). They look
and sell very differently, but they are **facades over the same funnel
skeleton and the same [Rx building blocks](/developer-tools/rx/building-blocks)**:
change the facade, keep the orchestration, the tracking, and the clinical
flow.

```mermaid theme={null}
flowchart LR
    subgraph SKELETON["Shared funnel skeleton (invariant)"]
        direction LR
        S1[Landing] --> S2[Marketing quiz] --> S3[Catalog / Offer] --> S4[Checkout] --> S5[Thank-you +<br/>medical intake] --> S6[Patient portal]
    end
    T1[/"Multi-vertical<br/>(TGD Care)"/] -.facade.-> SKELETON
    T2[/"Mono-vertical, plan-first<br/>(Cobalt)"/] -.facade.-> SKELETON
    T3[/"Mono-vertical, quiz-first<br/>(Arbor)"/] -.facade.-> SKELETON
```

Templates differ **only** in the order and weight of the first three boxes
(Landing / Quiz / Catalog) and in art direction. Checkout → Thank-you/intake →
Portal are identical everywhere — that's the LegitScript-validated,
FTC-sensitive core, and it never moves.

***

## The catalog

|               | Multi-vertical                                               | Cobalt                                           | Arbor                                               |
| ------------- | ------------------------------------------------------------ | ------------------------------------------------ | --------------------------------------------------- |
| Template      | `telehealth-tgdcare` (+ reskins `oakwell`, `kura`, `sanara`) | `telehealth-cobalt`                              | `telehealth-arbor`                                  |
| Live demo     | [tgdcare.com](https://tgdcare.com) (catalog-first)           | [cobalt.tgdcare.com](https://cobalt.tgdcare.com) | [arbor.tgdcare.com](https://arbor.tgdcare.com)      |
| Archetype     | Catalog-first "clinic storefront"                            | Plan-first "impulse"                             | Quiz-first "specialist"                             |
| Verticals     | hair · weight · skin · sexual                                | sexual (ED) only                                 | hair only                                           |
| Landing sells | The clinic (choose your treatment area)                      | The product (plan picker above the fold)         | The diagnosis ("Start my assessment")               |
| Quiz role     | Qualify within the chosen vertical                           | Preselect a plan (5–7 preference questions)      | Diagnose and recommend (8–12 visual screens)        |
| Catalog       | Central: verticals, then products                            | Reduced to an inline plan picker                 | Invisible: single-product recommendation page       |
| Best for      | Umbrella brands, several verticals                           | Single vertical with simple SKUs                 | High-personalization verticals (hair, skin, weight) |
| Status        | **LegitScript-validated — structure frozen**                 | Demo live                                        | Demo live                                           |

<Note>
  `oakwell`, `kura`, and `sanara` are anonymized reskins of the multi-vertical
  template — same structure, different branding — used for demos and as forks
  for new affiliate brands. `oakwell.tgdcare.com` is parked ("Coming soon")
  until remounted; use [tgdcare.com](https://tgdcare.com) as the live catalog
  demo. Cobalt and Arbor were built from a competitive audit of the DTC
  telehealth market (structures and vocabulary, never brands or assets).
</Note>

***

## Three orchestration patterns, same boxes

```mermaid theme={null}
flowchart TB
    subgraph A["Quiz-first (Arbor)"]
        direction LR
        A1[Quiz] --> A2["Recommendation<br/>(1 product)"] --> A3[Checkout]
    end
    subgraph B["Catalog-first (TGD Care)"]
        direction LR
        B1[Vertical<br/>catalog] --> B2[Vertical<br/>quiz] --> B3[Vertical<br/>products] --> B4[Checkout]
    end
    subgraph C["Plan-first (Cobalt)"]
        direction LR
        C1["Plan picker<br/>on the landing"] --> C2["Preference<br/>mini-quiz"] --> C3["Checkout<br/>(checkoutOffers)"]
    end
```

|               | Quiz-first                                                   | Catalog-first                        | Plan-first                                    |
| ------------- | ------------------------------------------------------------ | ------------------------------------ | --------------------------------------------- |
| The quiz      | writes the recommendation (product/variant) into the session | qualifies inside the chosen vertical | tags preferences, preselects an offer         |
| The catalog   | invisible — single recommendation                            | central — verticals then products    | an inline plan picker                         |
| Funnel config | quiz output feeds `resources.product`                        | one step group per vertical          | `checkoutOffers` (custom) + `defaultOfferId`  |
| Entry variant | ads can land directly on quiz question 1 (`entryStepId`)     | landing is the entry                 | ads can deep-link a plan straight to checkout |

***

## How a template maps onto the bricks

This is the load-bearing table: **each funnel step of every template calls
the same brick the same way.** A headless rebuild of any template is exactly
these calls, self-orchestrated.

| Funnel step (box)                             | What the template does                                                                                                                                                  | Brick / SDK call                                                                                                  |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| **Landing** (`/`)                             | Sell the promise; fire PageView pixels; start the funnel session                                                                                                        | Funnel engine (`RuntimeStepConfig.pixels`)                                                                        |
| **Marketing quiz** (`/quiz/:id`)              | Config-driven quiz (`config.quizzes`), zero medical questions; answers map to products via `config.productMappings` (defaults + conditions), kept locally with the cart | Template quiz engine → cart. Answers forwarded later as `intakeAnswers`                                           |
| **Catalog / Offer**                           | Plan picker (Cobalt), recommendation page (Arbor), or vertical catalog (TGD Care)                                                                                       | `checkoutOffers` / `resources.product` on the step config                                                         |
| **Checkout** (`/checkout`)                    | Create session from cart, take payment, order bumps                                                                                                                     | Plugin SDK `useCheckout` + `usePayment`; `useFunnel().next` to advance                                            |
| **Thank-you + medical intake** (`/thank-you`) | Fetch the network-authored questionnaire, collect patient + answers, submit the case, poll status                                                                       | `rx.getQuestionsForProduct` → `rx.submitCase` → `rx.getCasesForOrder` (poll with backoff until a terminal status) |
| **Post-purchase offer** (`/offer`)            | Optional upsell between payment and thank-you                                                                                                                           | Funnel `upsellOffers`; `useFunnel()` transition                                                                   |
| **Patient portal** (`/portal`)                | OTP login, case timeline, secure messaging, photo-ID upload                                                                                                             | Portal client over `/api/v1/rx/portal/*` (CMS session)                                                            |

Publishing a template installs this **same Funnel v2** on the merchant
instance. Every telehealth template (catalog + reskins) must serve these
paths — that is the compatibility contract with `ensureRxStorefrontFunnel`:

| Funnel box                 | Path         | Remappable                              |
| -------------------------- | ------------ | --------------------------------------- |
| Landing                    | `/`          | yes                                     |
| Marketing quiz             | `/quiz`      | no (template-internal, `matchSubPaths`) |
| Checkout                   | `/checkout`  | yes                                     |
| Offer                      | `/offer`     | yes                                     |
| Thank-you + medical intake | `/thank-you` | yes                                     |
| Patient portal             | `/portal`    | no (template-internal, `matchSubPaths`) |

The plugin matcher is `.*` (catch-all), so the six boxes are the same site,
not six mounts. The remappable pages carry feature contracts (checkout
session from `checkoutToken`, order from context) so the funnel engine can
rewire them per variant without touching template code.

<Info>
  **Decoupling in practice:** the medical intake never moves. Whatever the
  sales path — quiz-first, catalog-first, plan-first, or a headless funnel on
  your own infrastructure — the `product → medical questionnaire` pair is
  resolved *after payment* on the thank-you step. That's why the top of the
  funnel is completely free to vary.
</Info>

***

## Compliance rules baked into every template

1. **The marketing quiz contains no medical questions** — no PHI before
   the card hold. The medical intake is network-authored and post-hold.
2. **Prescription disclaimer wherever money changes hands**: authorizing
   or subscribing does not guarantee a prescription; the hold is voided
   if the clinician doesn't prescribe.
3. **Honest pricing**: displayed monthly price = billed price; billing
   cadence explicit at checkout.
4. **Safety information** reachable from every product surface.
5. **Self-service cancellation** in the patient portal.
6. **No platform branding patient-side** — the affiliate brand (or the
   marketplace brand) is the only name a patient ever sees.

***

## Launching from the CRM

Merchants don't deploy templates by hand: the CRM storefront wizard
(**Tagada Rx → Storefront**) lists this catalog. The merchant picks a
template, uploads a logo, sets brand name/colors and a subdomain, and
publishing **auto-deploys the chosen template and installs a Funnel v2**
on `brand.tgdcare.com` — catalog remap, payment flow, domain mount, and
the six-step canvas (landing → marketing quiz → checkout → offer →
thank-you → portal) so each page is visible in the CRM funnel builder.
Republishing with a different template swaps the facade in place: same
subdomain, same funnel, same cases. The plugin stays mounted as a
catch-all; the Funnel v2 graph is the operator view, not a second site.

The wizard also offers a **build-your-own path** for merchants who prefer
the [Headless SDK](/developer-tools/rx/headless-sdk) — with the constraint
that the build is still hosted on the Tagada subdomain (LegitScript).

***

## Forking a template

Templates live in the monorepo under `templates/v2/telehealth-*`. To create
a new brand: fork the closest archetype, patch `config/default.config.json`
(branding, verticals, products, `paymentFlowId`), adjust the theme CSS
variables, and deploy with the standard plugin pipeline (deploy →
instantiate → mount on the brand's domain). In affiliate mode, each brand is
one plugin instance on its own subdomain — same code, different config.

See [With the Plugin SDK](/developer-tools/rx/plugin-sdk) for the
integration contract inside a template.
