# Portals

Dynamic data, [user auth](/docs/user-auth), and gated pages combine to create full application experiences — without writing JavaScript. This page walks through complete, copy-pasteable portal examples. Each one includes the data source config, the listing page, and the detail page.

For the core syntax reference, see [Dynamic Data](/docs/dynamic-data). For auth setup, see [User Auth & Gating](/docs/user-auth).

{#how-portals-work}
## How portals work

Every portal on this page is built from the same three layers:

1. **A listing page** shows a collection of records — as cards, a table, or a list. This is the user's dashboard: their orders, projects, listings, whatever the portal is for.
2. **A detail view** shows one record in full. It can be a **standalone page** with its own URL (`/orders/detail?id=4821`) or a **modal** that opens inline without navigating away.
3. **Auth gating** scopes everything to the logged-in user. A `{{currentUser.id}}` filter on the data source ensures each person sees only their own records. Putting pages in `gated-pages/` enforces login.

### Detail pages vs detail modals

The detail layer is where portals become useful. Without it, you just have a list. With it, users can drill into any record and see the full picture.

**Standalone detail pages** get their own URL. Use them when the detail needs to be bookmarkable, shareable, or linkable from an email. An order receipt, a property listing, a member profile — anything a user might want to come back to directly.

```
data: my-orders
data-display: detail
data-param: id
data-key: id
data-auth: required
data-field: Order Number: order_number
data-field: Status: status
data-field: Total: ${{total}}
data-field: Shipping: {{street}}, {{city}}, {{state}} {{zip}}
```

The `data-param` reads a URL query parameter (`?id=4821`), `data-key` matches it against a field in the data source, and the page renders that single record.

**Detail modals** open inline on the same page. Use them for quick-peek details where navigating away would break the flow — scanning a table of support tickets, previewing a product from a grid, checking an order without leaving the dashboard.

```
data: support-tickets
data-display: table
data-detail: modal
data-field: Subject: subject
data-field: Status: status
data-link: View: #
data-detail-field: Subject: subject
data-detail-field: Priority: priority
data-detail-field: Assigned To: assigned_to
```

Add `data-detail: modal` and `data-detail-field:` lines to any cards, list, or table block. Clicking the link opens the modal with the full record — no separate page needed.

### Combining both on one page

A single page can have multiple data blocks. A project detail page can show the project record as a detail view at the top and its invoices as a table with modal details below it. Every example on this page demonstrates this kind of composition.

---

{#freelancer-client-portal}
## Freelancer client portal

A freelancer shares project status, invoices, and files with each client. Every client logs in and sees only their own projects. Each project links to a detail page with deliverables, timeline, and an invoice download.

### Data sources

```yaml
# settings/data.md
sources:
  - name: client-projects
    table: projects
    select: id, name, status, start_date, due_date, budget, thumbnail_url, slug
    filter: client_id = {{currentUser.id}}
    sort: due_date desc

  - name: project-invoices
    table: invoices
    select: id, invoice_number, amount, status, issued_date, pdf_url, project_id
    filter: client_id = {{currentUser.id}}
    sort: issued_date desc
```

### Projects list

The client's dashboard — shows all their active and completed projects as cards.

**File:** `gated-pages/projects.md`

```yaml
---
title: My Projects
slug: /account/projects
---
```

```
data: client-projects
data-display: cards
data-auth: required
data-title: name
data-text: {{status}} · Due {{due_date}}
data-image: thumbnail_url
data-link: View Project: /account/projects/detail?slug={{slug}}
```

<div class="sitemd-data" style="margin:var(--space-lg) 0">
<div class="sitemd-data-content">
<div class="card-grid">
<div class="card">
<img src="https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=600&h=400&fit=crop" alt="Brand Refresh" loading="lazy" class="card-image">
<div class="card-body">
<h3 class="card-title">Brand Refresh 2026</h3>
<p class="card-text">In Progress · Due 2026-04-15</p>
<span class="card-link"><a href="#" class="data-detail-trigger" data-demo-modal="demo-project-1">View Project &#8594;</a></span>
</div>
</div>
<div class="card">
<img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=600&h=400&fit=crop" alt="Product Launch Site" loading="lazy" class="card-image">
<div class="card-body">
<h3 class="card-title">Product Launch Site</h3>
<p class="card-text">Review · Due 2026-04-01</p>
<span class="card-link"><a href="#" class="data-detail-trigger" data-demo-modal="demo-project-2">View Project &#8594;</a></span>
</div>
</div>
<div class="card">
<img src="https://images.unsplash.com/photo-1542744094-24638eff58bb?w=600&h=400&fit=crop" alt="Q1 Campaign" loading="lazy" class="card-image">
<div class="card-body">
<h3 class="card-title">Q1 Campaign Assets</h3>
<p class="card-text">Delivered · Due 2026-02-28</p>
<span class="card-link"><a href="#" class="data-detail-trigger" data-demo-modal="demo-project-3">View Project &#8594;</a></span>
</div>
</div>
</div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-project-1" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Project</dt><dd class="data-detail-value">Brand Refresh 2026</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">In Progress</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Started</dt><dd class="data-detail-value">2026-01-15</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Due</dt><dd class="data-detail-value">2026-04-15</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Budget</dt><dd class="data-detail-value">$12,000</dd></div>
</dl>
<h4 style="margin-top:var(--space-md)">Invoices</h4>
<div class="sitemd-data-table-wrap">
<table class="sitemd-data-table">
<thead><tr><th>Invoice</th><th>Amount</th><th>Status</th><th>Issued</th></tr></thead>
<tbody>
<tr><td>INV-0042</td><td>$4,000</td><td>Paid</td><td>2026-02-01</td></tr>
<tr><td>INV-0051</td><td>$4,000</td><td>Paid</td><td>2026-03-01</td></tr>
<tr><td>INV-0063</td><td>$4,000</td><td>Pending</td><td>2026-04-01</td></tr>
</tbody>
</table>
</div>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-project-2" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Project</dt><dd class="data-detail-value">Product Launch Site</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Review</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Started</dt><dd class="data-detail-value">2026-02-01</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Due</dt><dd class="data-detail-value">2026-04-01</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Budget</dt><dd class="data-detail-value">$8,500</dd></div>
</dl>
<h4 style="margin-top:var(--space-md)">Invoices</h4>
<div class="sitemd-data-table-wrap">
<table class="sitemd-data-table">
<thead><tr><th>Invoice</th><th>Amount</th><th>Status</th><th>Issued</th></tr></thead>
<tbody>
<tr><td>INV-0044</td><td>$4,250</td><td>Paid</td><td>2026-02-15</td></tr>
<tr><td>INV-0058</td><td>$4,250</td><td>Pending</td><td>2026-03-15</td></tr>
</tbody>
</table>
</div>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-project-3" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Project</dt><dd class="data-detail-value">Q1 Campaign Assets</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Delivered</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Started</dt><dd class="data-detail-value">2025-12-10</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Due</dt><dd class="data-detail-value">2026-02-28</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Budget</dt><dd class="data-detail-value">$5,200</dd></div>
</dl>
<h4 style="margin-top:var(--space-md)">Invoices</h4>
<div class="sitemd-data-table-wrap">
<table class="sitemd-data-table">
<thead><tr><th>Invoice</th><th>Amount</th><th>Status</th><th>Issued</th></tr></thead>
<tbody>
<tr><td>INV-0031</td><td>$2,600</td><td>Paid</td><td>2026-01-10</td></tr>
<tr><td>INV-0039</td><td>$2,600</td><td>Paid</td><td>2026-02-10</td></tr>
</tbody>
</table>
</div>
</div></div>
</div>
</div>

### Project detail

Each project gets its own page with full specs, timeline, and a list of invoices.

**File:** `gated-pages/projects/detail.md`

```
data: client-projects
data-display: detail
data-param: slug
data-key: slug
data-auth: required
data-field: Project: name
data-field: Status: status
data-field: Started: start_date
data-field: Due: due_date
data-field: Budget: {{budget}}
```

Below the project detail, show invoices for that project:

```
data: project-invoices
data-display: table
data-auth: required
data-filter: project_id = {{param.id}}
data-field: Invoice: invoice_number
data-field: Amount: {{amount}}
data-field: Status: status
data-field: Issued: issued_date
data-link: Download PDF: {{pdf_url}}
```

---

{#saas-admin-panel}
## SaaS admin panel

An admin dashboard for a SaaS product. Team members manage users, view subscription metrics, and handle support tickets. Different user types see different views.

### Data sources

```yaml
# settings/data.md
sources:
  - name: team-users
    table: users
    select: id, email, name, avatar_url, plan, status, created_at, last_login
    sort: created_at desc

  - name: support-tickets
    table: tickets
    select: id, subject, requester_email, status, priority, created_at, assigned_to
    sort: created_at desc

  - name: subscriptions
    table: subscriptions
    select: id, user_email, plan, amount, interval, status, next_billing, started_at
    sort: next_billing asc
```

### User management

**File:** `gated-pages/admin/users.md`

```yaml
---
title: Users
slug: /admin/users
gated: admin
---
```

```
data: team-users
data-display: table
data-auth: required
data-field: Name: name
data-field: Email: email
data-field: Plan: plan
data-field: Status: status
data-field: Joined: created_at
data-link: View: /admin/users/detail?id={{id}}
data-paginate: true
data-limit: 25
```

<div class="sitemd-data" style="margin:var(--space-lg) 0">
<div class="sitemd-data-content">
<div class="sitemd-data-table-wrap">
<table class="sitemd-data-table">
<thead><tr><th>Name</th><th>Email</th><th>Plan</th><th>Status</th><th>Joined</th><th></th></tr></thead>
<tbody>
<tr><td>Alice Park</td><td>alice@example.com</td><td>Pro</td><td>Active</td><td>2025-11-03</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-user-1">View</a></td></tr>
<tr><td>Ben Torres</td><td>ben@example.com</td><td>Starter</td><td>Active</td><td>2025-12-18</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-user-2">View</a></td></tr>
<tr><td>Carla Nguyen</td><td>carla@example.com</td><td>Pro</td><td>Churned</td><td>2025-09-22</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-user-3">View</a></td></tr>
<tr><td>David Kim</td><td>david@example.com</td><td>Enterprise</td><td>Active</td><td>2026-01-07</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-user-4">View</a></td></tr>
<tr><td>Eva Johansson</td><td>eva@example.com</td><td>Starter</td><td>Trial</td><td>2026-03-19</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-user-5">View</a></td></tr>
</tbody>
</table>
</div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-user-1" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Name</dt><dd class="data-detail-value">Alice Park</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Email</dt><dd class="data-detail-value">alice@example.com</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Plan</dt><dd class="data-detail-value">Pro</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Active</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Joined</dt><dd class="data-detail-value">2025-11-03</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Last Login</dt><dd class="data-detail-value">2026-03-23</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-user-2" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Name</dt><dd class="data-detail-value">Ben Torres</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Email</dt><dd class="data-detail-value">ben@example.com</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Plan</dt><dd class="data-detail-value">Starter</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Active</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Joined</dt><dd class="data-detail-value">2025-12-18</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Last Login</dt><dd class="data-detail-value">2026-03-22</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-user-3" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Name</dt><dd class="data-detail-value">Carla Nguyen</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Email</dt><dd class="data-detail-value">carla@example.com</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Plan</dt><dd class="data-detail-value">Pro</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Churned</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Joined</dt><dd class="data-detail-value">2025-09-22</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Last Login</dt><dd class="data-detail-value">2026-01-15</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-user-4" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Name</dt><dd class="data-detail-value">David Kim</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Email</dt><dd class="data-detail-value">david@example.com</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Plan</dt><dd class="data-detail-value">Enterprise</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Active</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Joined</dt><dd class="data-detail-value">2026-01-07</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Last Login</dt><dd class="data-detail-value">2026-03-24</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-user-5" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Name</dt><dd class="data-detail-value">Eva Johansson</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Email</dt><dd class="data-detail-value">eva@example.com</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Plan</dt><dd class="data-detail-value">Starter</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Trial</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Joined</dt><dd class="data-detail-value">2026-03-19</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Last Login</dt><dd class="data-detail-value">2026-03-24</dd></div>
</dl>
</div></div>
</div>
</div>

### User detail

**File:** `gated-pages/admin/users/detail.md`

```
data: team-users
data-display: detail
data-param: id
data-key: id
data-auth: required
data-field: Name: name
data-field: Email: email
data-field: Plan: plan
data-field: Status: status
data-field: Joined: created_at
data-field: Last Login: last_login
```

### Support tickets

**File:** `gated-pages/admin/tickets.md`

```
data: support-tickets
data-display: table
data-auth: required
data-detail: modal
data-field: Subject: subject
data-field: From: requester_email
data-field: Priority: priority
data-field: Status: status
data-field: Created: created_at
data-link: View: #
data-detail-field: Subject: subject
data-detail-field: From: requester_email
data-detail-field: Priority: priority
data-detail-field: Status: status
data-detail-field: Assigned To: assigned_to
data-detail-field: Created: created_at
data-filter: status != closed
data-sort: priority desc
```

<div class="sitemd-data" style="margin:var(--space-lg) 0">
<div class="sitemd-data-content">
<div class="sitemd-data-table-wrap">
<table class="sitemd-data-table">
<thead><tr><th>Subject</th><th>From</th><th>Priority</th><th>Status</th><th>Created</th><th></th></tr></thead>
<tbody>
<tr><td>Can't export CSV from dashboard</td><td>alice@example.com</td><td>High</td><td>Open</td><td>2026-03-23</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-ticket-1">View</a></td></tr>
<tr><td>Billing page shows wrong amount</td><td>ben@example.com</td><td>High</td><td>In Progress</td><td>2026-03-22</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-ticket-2">View</a></td></tr>
<tr><td>Feature request: dark mode</td><td>david@example.com</td><td>Low</td><td>Open</td><td>2026-03-20</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-ticket-3">View</a></td></tr>
<tr><td>SSO setup not working</td><td>eva@example.com</td><td>Medium</td><td>Open</td><td>2026-03-19</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-ticket-4">View</a></td></tr>
</tbody>
</table>
</div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-ticket-1" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Subject</dt><dd class="data-detail-value">Can't export CSV from dashboard</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">From</dt><dd class="data-detail-value">alice@example.com</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Priority</dt><dd class="data-detail-value">High</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Open</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Assigned To</dt><dd class="data-detail-value">Jamie (Support Lead)</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Created</dt><dd class="data-detail-value">2026-03-23</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-ticket-2" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Subject</dt><dd class="data-detail-value">Billing page shows wrong amount</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">From</dt><dd class="data-detail-value">ben@example.com</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Priority</dt><dd class="data-detail-value">High</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">In Progress</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Assigned To</dt><dd class="data-detail-value">Sam (Billing Team)</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Created</dt><dd class="data-detail-value">2026-03-22</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-ticket-3" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Subject</dt><dd class="data-detail-value">Feature request: dark mode</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">From</dt><dd class="data-detail-value">david@example.com</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Priority</dt><dd class="data-detail-value">Low</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Open</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Assigned To</dt><dd class="data-detail-value">Unassigned</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Created</dt><dd class="data-detail-value">2026-03-20</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-ticket-4" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Subject</dt><dd class="data-detail-value">SSO setup not working</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">From</dt><dd class="data-detail-value">eva@example.com</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Priority</dt><dd class="data-detail-value">Medium</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Open</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Assigned To</dt><dd class="data-detail-value">Jamie (Support Lead)</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Created</dt><dd class="data-detail-value">2026-03-19</dd></div>
</dl>
</div></div>
</div>
</div>

### Role-based access

Gate different admin sections by user type in your page frontmatter:

```yaml
# Full admin access
gated: admin

# Support team only
gated: admin, support

# View-only for managers
gated: admin, manager
```

See [User Types](/docs/user-auth#user-types) for how to define and assign user types.

---

{#real-estate-listings}
## Real estate listings portal

A property listing site where agents publish listings and buyers browse. Public listing cards, detailed property pages, and a gated agent dashboard for managing listings.

### Data sources

```yaml
# settings/data.md
sources:
  - name: listings
    table: properties
    select: id, address, city, state, price, beds, baths, sqft, photo_url, slug, status, listed_date
    filter: status = active
    sort: listed_date desc

  - name: my-listings
    table: properties
    select: id, address, city, price, status, views, inquiries, listed_date, slug
    filter: agent_id = {{currentUser.id}}
    sort: listed_date desc
```

### Public property browse

This page is public — no login required. Visitors browse active listings as cards.

**File:** `pages/properties.md`

```yaml
---
title: Properties for Sale
slug: /properties
---
```

```
data: listings
data-display: cards
data-title: address
data-text: {{city}}, {{state}} · {{beds}} bd / {{baths}} ba · {{sqft}} sqft
data-image: photo_url
data-link: ${{price}}: /properties/detail?slug={{slug}}
data-limit: 12
data-paginate: true
```

<div class="sitemd-data" style="margin:var(--space-lg) 0">
<div class="sitemd-data-content">
<div class="card-grid">
<div class="card">
<img src="https://images.unsplash.com/photo-1564013799919-ab600027ffc6?w=600&h=400&fit=crop" alt="Property 1" loading="lazy" class="card-image">
<div class="card-body">
<h3 class="card-title">742 Evergreen Terrace</h3>
<p class="card-text">Springfield, IL · 4 bd / 2 ba · 2,400 sqft</p>
<span class="card-link"><a href="#" class="data-detail-trigger" data-demo-modal="demo-property-1">$425,000 &#8594;</a></span>
</div>
</div>
<div class="card">
<img src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?w=600&h=400&fit=crop" alt="Property 2" loading="lazy" class="card-image">
<div class="card-body">
<h3 class="card-title">221B Baker Street</h3>
<p class="card-text">London, UK · 3 bd / 2 ba · 1,800 sqft</p>
<span class="card-link"><a href="#" class="data-detail-trigger" data-demo-modal="demo-property-2">$1,250,000 &#8594;</a></span>
</div>
</div>
<div class="card">
<img src="https://images.unsplash.com/photo-1600596542815-ffad4c1539a9?w=600&h=400&fit=crop" alt="Property 3" loading="lazy" class="card-image">
<div class="card-body">
<h3 class="card-title">1640 Riverside Drive</h3>
<p class="card-text">Hill Valley, CA · 5 bd / 3 ba · 3,200 sqft</p>
<span class="card-link"><a href="#" class="data-detail-trigger" data-demo-modal="demo-property-3">$875,000 &#8594;</a></span>
</div>
</div>
</div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-property-1" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Address</dt><dd class="data-detail-value">742 Evergreen Terrace</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Location</dt><dd class="data-detail-value">Springfield, IL</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Price</dt><dd class="data-detail-value">$425,000</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Bedrooms</dt><dd class="data-detail-value">4</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Bathrooms</dt><dd class="data-detail-value">2</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Square Feet</dt><dd class="data-detail-value">2,400</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Active</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Listed</dt><dd class="data-detail-value">2026-03-10</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-property-2" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Address</dt><dd class="data-detail-value">221B Baker Street</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Location</dt><dd class="data-detail-value">London, UK</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Price</dt><dd class="data-detail-value">$1,250,000</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Bedrooms</dt><dd class="data-detail-value">3</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Bathrooms</dt><dd class="data-detail-value">2</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Square Feet</dt><dd class="data-detail-value">1,800</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Active</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Listed</dt><dd class="data-detail-value">2026-03-05</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-property-3" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Address</dt><dd class="data-detail-value">1640 Riverside Drive</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Location</dt><dd class="data-detail-value">Hill Valley, CA</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Price</dt><dd class="data-detail-value">$875,000</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Bedrooms</dt><dd class="data-detail-value">5</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Bathrooms</dt><dd class="data-detail-value">3</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Square Feet</dt><dd class="data-detail-value">3,200</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Active</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Listed</dt><dd class="data-detail-value">2026-02-20</dd></div>
</dl>
</div></div>
</div>
</div>

### Property detail

**File:** `pages/properties/detail.md`

```
data: listings
data-display: detail
data-param: slug
data-key: slug
data-field: Address: address
data-field: Location: {{city}}, {{state}}
data-field: Price: ${{price}}
data-field: Bedrooms: beds
data-field: Bathrooms: baths
data-field: Square Feet: sqft
data-field: Status: status
data-field: Listed: listed_date
```

### Agent dashboard

Logged-in agents see their own listings with performance metrics.

**File:** `gated-pages/agent/listings.md`

```
data: my-listings
data-display: table
data-auth: required
data-field: Address: address
data-field: City: city
data-field: Price: ${{price}}
data-field: Status: status
data-field: Views: views
data-field: Inquiries: inquiries
data-link: Details: #
data-detail: modal
data-detail-field: Address: address
data-detail-field: City: city
data-detail-field: Price: ${{price}}
data-detail-field: Status: status
data-detail-field: Views: views
data-detail-field: Inquiries: inquiries
data-detail-field: Listed: listed_date
```

<div class="sitemd-data" style="margin:var(--space-lg) 0">
<div class="sitemd-data-content">
<div class="sitemd-data-table-wrap">
<table class="sitemd-data-table">
<thead><tr><th>Address</th><th>City</th><th>Price</th><th>Status</th><th>Views</th><th>Inquiries</th><th></th></tr></thead>
<tbody>
<tr><td>742 Evergreen Terrace</td><td>Springfield</td><td>$425,000</td><td>Active</td><td>342</td><td>12</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-listing-1">Details</a></td></tr>
<tr><td>1640 Riverside Drive</td><td>Hill Valley</td><td>$875,000</td><td>Active</td><td>189</td><td>5</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-listing-2">Details</a></td></tr>
<tr><td>31 Spooner Street</td><td>Quahog</td><td>$310,000</td><td>Pending</td><td>567</td><td>23</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-listing-3">Details</a></td></tr>
</tbody>
</table>
</div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-listing-1" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Address</dt><dd class="data-detail-value">742 Evergreen Terrace</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">City</dt><dd class="data-detail-value">Springfield</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Price</dt><dd class="data-detail-value">$425,000</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Active</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Views</dt><dd class="data-detail-value">342</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Inquiries</dt><dd class="data-detail-value">12</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Listed</dt><dd class="data-detail-value">2026-03-10</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-listing-2" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Address</dt><dd class="data-detail-value">1640 Riverside Drive</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">City</dt><dd class="data-detail-value">Hill Valley</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Price</dt><dd class="data-detail-value">$875,000</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Active</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Views</dt><dd class="data-detail-value">189</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Inquiries</dt><dd class="data-detail-value">5</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Listed</dt><dd class="data-detail-value">2026-02-20</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-listing-3" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Address</dt><dd class="data-detail-value">31 Spooner Street</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">City</dt><dd class="data-detail-value">Quahog</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Price</dt><dd class="data-detail-value">$310,000</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Pending</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Views</dt><dd class="data-detail-value">567</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Inquiries</dt><dd class="data-detail-value">23</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Listed</dt><dd class="data-detail-value">2026-01-15</dd></div>
</dl>
</div></div>
</div>
</div>

---

{#membership-directory}
## Membership directory

A professional community with public member profiles and private member-only features. Members browse the directory, view profiles, and access gated resources.

### Data sources

```yaml
# settings/data.md
sources:
  - name: members
    table: members
    select: id, name, title, company, avatar_url, bio, location, website, slug
    filter: visibility = public
    sort: name asc

  - name: member-resources
    table: resources
    select: id, title, description, category, file_url, created_at
    sort: created_at desc
```

### Member directory

Public directory showing all visible members.

**File:** `pages/members.md`

```
data: members
data-display: cards
data-title: name
data-text: {{title}} at {{company}}
data-image: avatar_url
data-link: View Profile: /members/profile?slug={{slug}}
data-paginate: true
data-limit: 24
```

<div class="sitemd-data" style="margin:var(--space-lg) 0">
<div class="sitemd-data-content">
<div class="card-grid">
<div class="card">
<img src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=600&h=600&fit=crop" alt="Sarah Chen" loading="lazy" class="card-image">
<div class="card-body">
<h3 class="card-title">Sarah Chen</h3>
<p class="card-text">Principal Engineer at Vercel</p>
<span class="card-link"><a href="#" class="data-detail-trigger" data-demo-modal="demo-member-1">View Profile &#8594;</a></span>
</div>
</div>
<div class="card">
<img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=600&h=600&fit=crop" alt="Marcus Rivera" loading="lazy" class="card-image">
<div class="card-body">
<h3 class="card-title">Marcus Rivera</h3>
<p class="card-text">Design Lead at Figma</p>
<span class="card-link"><a href="#" class="data-detail-trigger" data-demo-modal="demo-member-2">View Profile &#8594;</a></span>
</div>
</div>
<div class="card">
<img src="https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=600&h=600&fit=crop" alt="Priya Patel" loading="lazy" class="card-image">
<div class="card-body">
<h3 class="card-title">Priya Patel</h3>
<p class="card-text">CTO at Stripe</p>
<span class="card-link"><a href="#" class="data-detail-trigger" data-demo-modal="demo-member-3">View Profile &#8594;</a></span>
</div>
</div>
</div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-member-1" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Name</dt><dd class="data-detail-value">Sarah Chen</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Title</dt><dd class="data-detail-value">Principal Engineer</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Company</dt><dd class="data-detail-value">Vercel</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Location</dt><dd class="data-detail-value">San Francisco, CA</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Bio</dt><dd class="data-detail-value">Building the frontend cloud. Previously at Google and Meta. Open source contributor to Next.js and Turborepo.</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Website</dt><dd class="data-detail-value">sarahchen.dev</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-member-2" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Name</dt><dd class="data-detail-value">Marcus Rivera</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Title</dt><dd class="data-detail-value">Design Lead</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Company</dt><dd class="data-detail-value">Figma</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Location</dt><dd class="data-detail-value">New York, NY</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Bio</dt><dd class="data-detail-value">Design systems and component architecture. Author of "Scaling Design" and frequent conference speaker on design tokens.</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Website</dt><dd class="data-detail-value">marcusrivera.design</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-member-3" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Name</dt><dd class="data-detail-value">Priya Patel</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Title</dt><dd class="data-detail-value">CTO</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Company</dt><dd class="data-detail-value">Stripe</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Location</dt><dd class="data-detail-value">London, UK</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Bio</dt><dd class="data-detail-value">Leading payments infrastructure. Background in distributed systems at AWS. Passionate about developer experience and API design.</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Website</dt><dd class="data-detail-value">priyapatel.io</dd></div>
</dl>
</div></div>
</div>
</div>

### Member profile

**File:** `pages/members/profile.md`

```
data: members
data-display: detail
data-param: slug
data-key: slug
data-field: Name: name
data-field: Title: title
data-field: Company: company
data-field: Location: location
data-field: Bio: bio
data-field: Website: website
```

### Gated resources

Members-only resource library, visible after login.

**File:** `gated-pages/resources.md`

```
data: member-resources
data-display: list
data-auth: required
data-title: title
data-text: {{category}} · {{description}}
data-link: Download: {{file_url}}
```

<div class="sitemd-data" style="margin:var(--space-lg) 0">
<div class="sitemd-data-content">
<ul class="sitemd-data-list">
<li class="data-list-item">
<div class="data-list-body">
<span class="data-list-title">2026 Industry Salary Report</span>
<p class="data-list-text">Research · Comprehensive salary data across 12 engineering roles and 40 metro areas</p>
</div>
</li>
<li class="data-list-item">
<div class="data-list-body">
<span class="data-list-title">Startup Fundraising Playbook</span>
<p class="data-list-text">Guide · Seed to Series B — term sheets, pitch decks, and investor outreach templates</p>
</div>
</li>
<li class="data-list-item">
<div class="data-list-body">
<span class="data-list-title">Remote Team Toolkit</span>
<p class="data-list-text">Template · Async standup templates, decision logs, and meeting-free week schedules</p>
</div>
</li>
</ul>
</div>
</div>

---

{#ecommerce-customer-account}
## E-commerce customer account

A customer account area for an online store. Order history, saved addresses, and wishlist — all filtered to the logged-in user.

### Data sources

```yaml
# settings/data.md
sources:
  - name: my-orders
    table: orders
    select: id, order_number, status, total, item_count, created_at, tracking_url
    filter: customer_id = {{currentUser.id}}
    sort: created_at desc

  - name: my-addresses
    table: addresses
    select: id, label, street, city, state, zip, is_default
    filter: customer_id = {{currentUser.id}}
    sort: is_default desc

  - name: my-wishlist
    table: wishlist_items
    select: id, product_name, product_image, product_price, product_slug, added_at
    filter: customer_id = {{currentUser.id}}
    sort: added_at desc
```

### Order history

**File:** `gated-pages/account/orders.md`

```
data: my-orders
data-display: table
data-auth: required
data-detail: modal
data-field: Order: order_number
data-field: Items: item_count
data-field: Total: ${{total}}
data-field: Status: status
data-field: Date: created_at
data-link: Details: #
data-detail-field: Order Number: order_number
data-detail-field: Status: status
data-detail-field: Total: ${{total}}
data-detail-field: Items: item_count
data-detail-field: Tracking: tracking_url
data-paginate: true
```

<div class="sitemd-data" style="margin:var(--space-lg) 0">
<div class="sitemd-data-content">
<div class="sitemd-data-table-wrap">
<table class="sitemd-data-table">
<thead><tr><th>Order</th><th>Items</th><th>Total</th><th>Status</th><th>Date</th><th></th></tr></thead>
<tbody>
<tr><td>ORD-9182</td><td>3</td><td>$247.00</td><td>Delivered</td><td>2026-03-18</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-order-1">Details</a></td></tr>
<tr><td>ORD-9145</td><td>1</td><td>$89.00</td><td>Shipped</td><td>2026-03-12</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-order-2">Details</a></td></tr>
<tr><td>ORD-9023</td><td>5</td><td>$412.50</td><td>Delivered</td><td>2026-02-28</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-order-3">Details</a></td></tr>
<tr><td>ORD-8891</td><td>2</td><td>$156.00</td><td>Delivered</td><td>2026-02-14</td><td><a href="#" class="data-detail-trigger" data-demo-modal="demo-order-4">Details</a></td></tr>
</tbody>
</table>
</div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-order-1" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Order Number</dt><dd class="data-detail-value">ORD-9182</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Delivered</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Total</dt><dd class="data-detail-value">$247.00</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Items</dt><dd class="data-detail-value">1x Minimalist Watch, 1x Running Sneakers, 1x Leather Belt</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Tracking</dt><dd class="data-detail-value">UPS 1Z999AA10123456784</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-order-2" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Order Number</dt><dd class="data-detail-value">ORD-9145</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Shipped</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Total</dt><dd class="data-detail-value">$89.00</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Items</dt><dd class="data-detail-value">1x Canvas Backpack</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Tracking</dt><dd class="data-detail-value">FedEx 794644790132</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-order-3" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Order Number</dt><dd class="data-detail-value">ORD-9023</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Delivered</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Total</dt><dd class="data-detail-value">$412.50</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Items</dt><dd class="data-detail-value">2x Running Sneakers, 1x Minimalist Watch, 1x Wool Scarf, 1x Sunglasses</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Tracking</dt><dd class="data-detail-value">USPS 9405511899223033818452</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-order-4" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Order Number</dt><dd class="data-detail-value">ORD-8891</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Status</dt><dd class="data-detail-value">Delivered</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Total</dt><dd class="data-detail-value">$156.00</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Items</dt><dd class="data-detail-value">1x Running Sneakers, 1x Canvas Tote</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Tracking</dt><dd class="data-detail-value">UPS 1Z999AA10987654321</dd></div>
</dl>
</div></div>
</div>
</div>

### Wishlist

**File:** `gated-pages/account/wishlist.md`

```
data: my-wishlist
data-display: cards
data-auth: required
data-title: product_name
data-text: ${{product_price}}
data-image: product_image
data-link: View Product: /products/detail?slug={{product_slug}}
```

<div class="sitemd-data" style="margin:var(--space-lg) 0">
<div class="sitemd-data-content">
<div class="card-grid">
<div class="card">
<img src="https://images.unsplash.com/photo-1523275335684-37898b6baf30?w=600&h=400&fit=crop" alt="Watch" loading="lazy" class="card-image">
<div class="card-body">
<h3 class="card-title">Minimalist Watch</h3>
<p class="card-text">$195.00</p>
<span class="card-link"><a href="#" class="data-detail-trigger" data-demo-modal="demo-wish-1">View Product &#8594;</a></span>
</div>
</div>
<div class="card">
<img src="https://images.unsplash.com/photo-1491553895911-0055eca6402d?w=600&h=400&fit=crop" alt="Sneakers" loading="lazy" class="card-image">
<div class="card-body">
<h3 class="card-title">Running Sneakers</h3>
<p class="card-text">$129.00</p>
<span class="card-link"><a href="#" class="data-detail-trigger" data-demo-modal="demo-wish-2">View Product &#8594;</a></span>
</div>
</div>
<div class="card">
<img src="https://images.unsplash.com/photo-1553062407-98eeb64c6a62?w=600&h=400&fit=crop" alt="Backpack" loading="lazy" class="card-image">
<div class="card-body">
<h3 class="card-title">Canvas Backpack</h3>
<p class="card-text">$78.00</p>
<span class="card-link"><a href="#" class="data-detail-trigger" data-demo-modal="demo-wish-3">View Product &#8594;</a></span>
</div>
</div>
</div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-wish-1" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Product</dt><dd class="data-detail-value">Minimalist Watch</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Price</dt><dd class="data-detail-value">$195.00</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Description</dt><dd class="data-detail-value">Swiss movement, sapphire crystal, Italian leather strap. 40mm case in brushed steel.</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">In Stock</dt><dd class="data-detail-value">Available</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-wish-2" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Product</dt><dd class="data-detail-value">Running Sneakers</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Price</dt><dd class="data-detail-value">$129.00</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Description</dt><dd class="data-detail-value">Lightweight mesh upper, responsive foam midsole, carbon fiber plate. Available in 6 colorways.</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">In Stock</dt><dd class="data-detail-value">Available</dd></div>
</dl>
</div></div>
</div>
</div>

<div class="modal-overlay" data-modal-id="demo-wish-3" role="dialog" aria-modal="true" hidden>
<div class="modal-wrap">
<button class="modal-close" type="button" aria-label="Close">&times;</button>
<div class="modal-dialog"><div class="modal-body content">
<dl class="sitemd-data-detail">
<div class="data-detail-row"><dt class="data-detail-label">Product</dt><dd class="data-detail-value">Canvas Backpack</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Price</dt><dd class="data-detail-value">$78.00</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">Description</dt><dd class="data-detail-value">Waxed cotton canvas, leather trim, padded laptop sleeve (fits 15"). Lifetime warranty.</dd></div>
<div class="data-detail-row"><dt class="data-detail-label">In Stock</dt><dd class="data-detail-value">Available</dd></div>
</dl>
</div></div>
</div>
</div>

### Saved addresses

**File:** `gated-pages/account/addresses.md`

```
data: my-addresses
data-display: list
data-auth: required
data-title: label
data-text: {{street}}, {{city}}, {{state}} {{zip}}
```

<div class="sitemd-data" style="margin:var(--space-lg) 0">
<div class="sitemd-data-content">
<ul class="sitemd-data-list">
<li class="data-list-item">
<div class="data-list-body">
<span class="data-list-title">Home (Default)</span>
<p class="data-list-text">742 Evergreen Terrace, Springfield, IL 62704</p>
</div>
</li>
<li class="data-list-item">
<div class="data-list-body">
<span class="data-list-title">Office</span>
<p class="data-list-text">100 Industrial Way, Suite 400, Springfield, IL 62711</p>
</div>
</li>
</ul>
</div>
</div>

---

{#building-your-own}
## Building your own portal

Every example on this page follows the same pattern:

1. **Define data sources** in `settings/data.md` — one per collection, with `{{currentUser.id}}` filters for user-scoped data
2. **Create listing pages** with `data-display: cards`, `list`, or `table` — put them in `gated-pages/` if they require login
3. **Create detail pages** with `data-display: detail` and `data-param`/`data-key` for URL-based record lookup
4. **Gate by user type** with `gated: admin, member` in frontmatter for role-based access

Mix and match display modes on the same page. A project detail page can show the project record as a detail view and its invoices as a table below it. A course page can show the course info as detail fields and its lessons as a list.

The data sources, display modes, and auth gating are all documented in detail:

<script>
(function(){
  document.addEventListener('click',function(e){
    var trigger=e.target.closest('[data-demo-modal]');
    if(trigger){e.preventDefault();var id=trigger.dataset.demoModal;var overlay=document.querySelector('[data-modal-id="'+id+'"]');if(overlay){overlay.hidden=false;document.body.style.overflow='hidden';overlay.querySelector('.modal-close').focus();}return;}
    var close=e.target.closest('.modal-close');
    if(close){var ov=close.closest('.modal-overlay');if(ov){ov.hidden=true;document.body.style.overflow='';}return;}
    if(e.target.classList&&e.target.classList.contains('modal-overlay')){e.target.hidden=true;document.body.style.overflow='';}
  });
  document.addEventListener('keydown',function(e){if(e.key==='Escape'){var open=document.querySelector('.modal-overlay:not([hidden])');if(open){open.hidden=true;document.body.style.overflow='';}}});
})();
</script>

button: Dynamic Data reference: /docs/dynamic-data
button: User Auth & Gating: /docs/user-auth
button: Forms (for input): /docs/forms