Support/Builder Guide/Professional Template Foundation

Builder Guide

Professional Template Foundation

Build polished, responsive SaaS pages from registry-backed components, copyable compositions, token-safe themes and server-scoped data bindings.

Open raw .md
Components
18
Page compositions
7
Theme presets
3
Data scope
Server enforced

The Professional Template Foundation is a registry-backed starting point for polished BuildWithHQ applications. Developer Kit 1.20.66 combines the eleven Foundation components with seven interactive API presentation components, seven complete page compositions, a named icon vocabulary, flexible responsive grids, 25 first-class module presentation recipes, eighteen contract-backed product API recipes, portable and full runtime page embedding, app-wide organization/user lifecycle webhooks, a complete webhook receiver and background-job poller, marketplace service discovery and per-app OpenAPI, a tested pagination/filtering/rate-limit policy, the complete API Map and recursive Record Graph guide, governed Skills, durable REST/MCP installed-service Tasks, three theme presets, separate draft/live page credentials, an HTML-to-Puck converter, a self-contained local Puck binding editor, a safe account-overlay sync tool, a tested DeepSeek Harness MCP setup, and an exact tenant-provisioning and authentication map without creating a second renderer, a second permission system, or a client-side data layer.

The current kit includes separate secured Contacts and Global Search counts, fast-row defaults, and an executable progressive-loading SDK example with cancellation and error-state tests. Search runs before the 5,000-match browsing limit; full authorized counts remain uncapped. See progressive loading, searchable paging and exact counts.

Note

The page compositions work as immediate static previews. Live values must use a registered server-side binding. Existing SaaS databases need the reviewed component-registry release migration before these blocks appear in Puck; builders must never insert registry or theme rows directly.

Download the Builder Developer Kit

Download the shared BuildWithHQ / API43 Developer Kit 1.20.66 (1110.3 KiB). Verify SHA-256 334428bd93e4788852438e2df2969e0c9e3605fa53e2998d86fb63117832d081, or download the adjacent checksum file.

A builder working entirely in BuildWithHQ does not need the repository or its maintainer test commands. Install the exact published Template Library version, open its pages in Puck, and customize them. Download the kit when you want standalone styled and unstyled React, canonical page and theme JSON, the public capability catalog, OpenAPI, the server-side TypeScript SDK, or MCP/CLI setup material.

Version 1.20.16 activates durable installed-service Tasks through typed REST/SDK status and cancellation plus negotiated MCP tasks/get, tasks/update, and tasks/cancel. Every task call reauthorizes and cancellation reports requested, effective, or too-late without claiming to undo committed work. Version 1.20.15 added governed Skills discovery, digest-bound exact resources, and delegated-owner GoClaw assignment. Skills and Tasks extension methods remain distinct from the curated MCP tool map, and declarations never grant authority. Version 1.20.14 added organization-owned support lanes and SMS ticketing.

The ZIP catalogs 315 published API paths and 392 operations. A trusted API43/ISV server can provision passwordless external users, edit unpublished page JSON with a draft key, publish with a separate live key, issue a narrow bwu_live_ browser token, embed published pages, and generate a typed client for its installed marketplace endpoints without exposing either app credential.

Developer Kit 1.20.66 release notes describe the review corrections, OpenAPI-generated contract guidance, four additional SDK page-size guards and packaged verification evidence. Strict request-field validation and the restored Mail Reader routes remain available. Download the exact release-gate report. Historical 1.20.61 corrections and 1.20.60 revision guidance remain available.

Install and type-check the portable React examples
cd react
npm install
npm run typecheck

Run plain npm install from the extracted react/ directory. The shipped npm lock pins React 19.2.8, React types 19.2.18, the Go-based TypeScript compiler 7.0.2, and lucide-react 1.41.0 for verification while the package keeps its React 18-or-19 peer range. The top-level typecheck intentionally excludes react/native/; those starters require the official @buildwithhq/* packages supplied by an extension workspace.

SurfaceUseIdentity boundary
Builder and PuckInstall, edit, validate and publish template pages.Short-lived Builder identity and account ownership.
Developer API and MCPOperate on one SaaS app's authorized data and integrations.App-bound credential with mcp.use plus each tool's scope.
Headless ReactPaint already-authorized results in a custom interface.Your server holds the API credential; the browser never does.

The app-scoped MCP endpoint is https://api.buildwithhq.com/v1/apps/{saasAppId}/mcp. Tool discovery is authoritative, and sensitive mutation tools remain absent unless server policy explicitly enables them.

Copy the MCP connection descriptor
{
  "schemaVersion": 1,
  "name": "BuildWithHQ / API43",
  "transport": "streamable-http",
  "urlTemplate": "https://api.buildwithhq.com/v1/apps/{saasAppId}/mcp",
  "authentication": {
    "type": "bearer",
    "credentialSource": {
      "kind": "environment",
      "name": "BWHQ_API_CREDENTIAL"
    }
  },
  "requiredConfiguration": {
    "saasAppIdEnvironment": "BWHQ_SAAS_APP_ID",
    "minimumScopes": ["mcp.use"],
    "toolScopesAreAdditional": true
  },
  "security": {
    "credentialBoundToExactSaasApp": true,
    "routeAppIsAuthorization": false,
    "physicalRoutingExposed": false,
    "sensitiveMutationsDefaultDenied": true
  }
}
Copy the CLI profile setup
# Install bwhq 0.1.0 from your approved BuildWithHQ package channel first.
# Secrets stay in your environment or secret manager, not in the profile.
bwhq auth profile add `
  --name my-saas `
  --saas-app-id <your-saas-app-id> `
  --base-url https://api.buildwithhq.com `
  --credential-env BWHQ_API_CREDENTIAL `
  --control-plane-base-url https://hello.buildwithhq.com `
  --builder-token-env BWHQ_BUILDER_TOKEN `
  --set-current

bwhq doctor --profile my-saas
bwhq status --profile my-saas
Important

The ZIP contains CLI instructions, not a signed bwhq executable. Publish the CLI through an approved package channel as a separate release. Never ask a builder to compile the repository, and never put BWHQ_API_CREDENTIAL or BWHQ_BUILDER_TOKEN in page JSON, React source, a ZIP, or a prompt.

What designers can do now

Designers can work visually in BuildWithHQ, while React developers can take the same component and page contracts further. The visual layer can be as art-directed as a premium React template without moving identity, authorization or database routing into the browser.

Build visually

  • Build and rearrange responsive pages in Puck without writing React.
  • Choose an automatic card grid or an opt-in 12-column canvas, then set each block's desktop, tablet and mobile span from 1 through 12.
  • Choose named icons for metrics and navigation; every icon inherits the active theme and unknown names fail closed.
  • Compose Container, Text, page headers, cards, statistics, badges, section labels, list rows, bounded tables, accessible charts and explicit empty states.
  • Start from complete Dashboard, Queue/List and Record Detail compositions instead of a blank canvas.
  • Change color, typography, spacing, borders, radius and light/dark behavior through safe design tokens and the three included theme presets.
  • Bind statistics, charts and tables to reviewed server-scoped results, then preview loading, error, empty and populated states.
  • Publish a coherent page family as an exact-version template so an installed tenant does not change silently.
  • Use the downloadable styled or unstyled React examples when the visual work needs to continue outside Puck.

How React fits together

  • Puck saves canonical page JSON containing stable block identities, registered component keys and validated presentation properties.
  • The React renderer maps each registered key to reviewed, statically bundled component code. Catalog metadata never dynamically executes arbitrary code.
  • The server derives the SaaS app, account, user, DataRoles and Locations; SQL returns only the permitted result; React simply renders that bounded result.
  • Developers can register additional React components, expose only intentional properties to Puck and reuse the existing binding, loading and error contracts.
  • A licensed third-party React design can be adapted into registered components without replacing BuildWithHQ authentication, APIs or server-side data scope.

Reach premium-template visual quality

  • Use one deliberate design system for typography, spacing, color, shadows, borders and corner treatments instead of styling each page independently.
  • Add richer reviewed blocks such as hero sections, navigation, tabs, timelines, activity feeds, forms, pricing cards, kanban boards and command bars.
  • Start with the included named icon vocabulary, then add separately reviewed licensed illustrations, photography and branded empty states to create a distinctive visual language.
  • Add restrained hover effects, transitions, skeleton loaders and page motion through normal React and CSS implementation.
  • Design desktop, tablet and mobile layouts intentionally, including keyboard behavior, focus states, long content and overflow.
  • Design complete loading, empty, error, forbidden and success states rather than only the ideal populated screen.
  • Package several art-directed page families over the same secure bindings; a new skin does not require a new database or authorization model.
Tip

The foundation supplies the secure renderer, bindings and reusable design vocabulary. ThemeForest-level polish comes from art direction, licensed assets, thoughtful motion and a broader library of product-specific blocks — all of which can be added without weakening the data boundary.

1. How the foundation works

LayerWhat it ownsWhat it does not own
Component RegistryStable keys, display names, default props, renderer keys and versions.Tenant identity, data scope or SQL.
Canonical page JSONStable block IDs, layout, component properties, children and approved binding keys.Authorization or physical database routing.
SaaS app themeLight/dark/system mode and allowlisted --runtime-* design tokens.Arbitrary executable CSS, script or permissions.
Runtime binding resolverMaps a registered bindingKey to a reviewed, identity-scoped server operation before JSON is returned.Ad-hoc SQL or browser-selected tenant/account IDs.
Template LibraryOwned page harvest, validation, immutable page/component publication and exact-version installation.Silently changing an already installed tenant copy.

At runtime the server resolves the signed-in SaaS app, account, user, DataRoles and Locations. SQL returns only the permitted result. React receives that already-scoped result and paints it. A component never downloads a broad table and filters it in the browser.

2. Use the professional component vocabulary

Component keyUse it forMain properties
core.page-headerPage title, lead and breadcrumb.title, lead, breadcrumb[]
core.stat-tileOne KPI or bounded scalar.label, value, delta, direction, iconName, tone
core.cardA titled content group.title, description, tone, child blocks
core.chartAn accessible bar or line summary.title, variant, series[], labels[], tone
core.data-tableA bounded server-scoped list.caption, columns[], optional static rows[]
core.list-rowCompact recent activity or person/work summaries.primary, secondary, trailing, initials, tone
core.badgeStatus and category labels.label, tone
core.section-labelA compact section eyebrow.label
core.empty-stateAn explicit zero-result or missing-proof state.title, body

Use core.container with layout: "stack", "row" or "grid" to compose them. Grid containers default to gridMode: "auto-fit". Select "twelve-column" when you want custom proportions, then set child spans under responsive.desktop.span, responsive.tablet.span and responsive.mobile.span. Catalog values outside the reviewed enums or 1-through-12 span range now fail validation with E016 before publication.

Interactive API presentation components included in the current kit

Component keyUse it forBounded contract
core.metric-stripKPI values, deltas and as-of time.Up to 12 metrics.
core.entity-listNames, context, statuses and record navigation.Up to 100 items.
core.progress-listStatus distribution, ranked progress and capacity.Up to 100 items.
core.series-chartInteractive bar/line periods with a semantic table.5 periods, 8 series, 120 points.
core.presentation-gridTyped visible-page rows, local page sorting and declared row actions.24 columns, 500 rows and 8 declared actions.
core.task-listChecklist-style completion rows with revision-fenced toggles.Up to 1,000 items.
core.timelineChronological activity, actors and statuses.Up to 100 items.

The downloadable InteractivePresentationComponents.tsx is semantic and unstyled by default. Pass styled and import interactive-presentation-components.css for the supplied professional treatment. BuildWithHQIcons.tsx exposes the same bounded, theme-aware icon vocabulary without accepting arbitrary SVG or markup. ControlPanelDashboardExample.tsx demonstrates mixed 3/3/3/3, 8/4 and 5/7 layouts without declaring any one of them mandatory. WorkOrderPresentationExample.tsx shows the live Work Orders composition; FirstClassModulePresentationExamples.tsx provides named compositions for all twenty-three cataloged module experiences, backed by six-row fictional design fixtures in catalog/module-presentation-samples.json.

Copy the task and row-action documents

The server emits action keys only when the signed-in user may be offered that operation. React still treats the key as presentation, and the host maps it through a closed handler list to a reviewed API. The API independently rechecks identity, DataRoles, Locations, record scope and concurrency. Unknown action keys must never become dynamic URLs or executable code.

Task-list presentation document
{
  "presentationVersion": 1,
  "kind": "task-list",
  "title": "Closeout tasks",
  "items": [
    {
      "id": "<checklist-run-item-id>",
      "recordId": "<secured-record-id>",
      "label": "Attach completion photo",
      "description": "Show the finished installation and asset label.",
      "checked": false,
      "revision": 7,
      "toggleActionKey": "checklists-signoffs.item.toggle"
    }
  ]
}
Data-grid declared action document
{
  "presentationVersion": 1,
  "kind": "data-grid",
  "columns": [{ "key": "name", "label": "Name", "type": "text", "align": "left" }],
  "actions": [
    { "key": "contacts.favorite", "label": "Favorite", "tone": "primary" }
  ],
  "rows": [
    { "id": "<contact-id>", "recordId": "<record-id>", "cells": { "name": "Ada Rivera" }, "actionKeys": ["contacts.favorite"] }
  ]
}
Copy the complete allowlisted React action dispatcher
import {
  PresentationGrid,
  TaskList,
  type PresentationActionRequest,
  type PresentationActionResult,
} from "./InteractivePresentationComponents";
import { parseLegoActionReceipt } from "@buildwithhq/page-runtime";

export interface PresentationActionExampleProps {
  readonly blockId: string;
  readonly data: unknown;
  readonly getCsrfToken: () => Promise<string>;
  /** Refetch the same server-scoped binding that supplied data. */
  readonly loadData: () => Promise<unknown>;
  readonly pageKey: string;
  readonly styled?: boolean;
}

const mutationError = async (response: Response, operation: string): Promise<Error> => {
  let correlationId = response.headers.get("x-correlation-id") ?? undefined;
  try {
    const body = await response.json() as { correlationId?: unknown };
    if (typeof body.correlationId === "string") correlationId = body.correlationId;
  } catch {
    // The stable status and optional response header are sufficient for a safe error.
  }
  return new Error(`${operation} failed (${response.status})${correlationId ? `; correlation ${correlationId}` : ""}`);
};

/**
 * Submit only a server-issued action ID through the fixed Lego broker route.
 * The saved page/block and current authorized catalog are re-resolved by the
 * tenant runtime; neither this example nor page JSON selects implementation.
 */
export const createPresentationActionBroker = (
  getCsrfToken: () => Promise<string>,
  pageKey: string,
  blockId: string,
): ((request: PresentationActionRequest) => Promise<PresentationActionResult>) =>
  async (request) => {
    const response = await fetch("/api/runtime/lego/actions", {
      method: "POST",
      credentials: "same-origin",
      headers: { "Content-Type": "application/json", "X-CSRF-Token": await getCsrfToken() },
      body: JSON.stringify({
        contractVersion: 1,
        pageKey,
        blockId,
        actionId: request.actionId,
        recordId: request.recordId,
        expectedRevision: request.expectedRevision,
        values: request.values,
      }),
    });
    if (!response.ok) throw await mutationError(response, "Lego action");
    const receipt = parseLegoActionReceipt(await response.json(), request.actionId);
    return {
      conflict: receipt.conflict === true,
      refreshBindingId: receipt.refreshBindingId,
      revision: receipt.revision,
    };
  };

export const CloseoutTasks = ({ blockId, data, getCsrfToken, loadData, pageKey, styled = false }: PresentationActionExampleProps) => (
  <TaskList data={data} styled={styled} onAction={createPresentationActionBroker(getCsrfToken, pageKey, blockId)} onRefreshData={loadData} />
);

export const ContactActionGrid = ({ blockId, data, getCsrfToken, loadData, pageKey, styled = false }: PresentationActionExampleProps) => (
  <PresentationGrid data={data} styled={styled} onAction={createPresentationActionBroker(getCsrfToken, pageKey, blockId)} onRefreshData={loadData} />
);

The same compiling onAction example is included as react/PresentationActionExample.tsx. It maps only the reviewed Contacts favorite and checklist-item toggle APIs. The checklist callback returns the new revision so a second toggle cannot accidentally reuse a stale concurrency token. Contacts writes request a refetch because the row's available favorite action changes. A checklist HTTP 409 requests the same scoped document again and displays the other session's authoritative value; it does not retry stale state. Without onAction, task checkboxes are disabled and row-action buttons are not rendered.

3. Start from a complete page composition

Each source below is canonical BuildWithHQ page content. The dashboard demonstrates KPIs, a chart and activity. The queue demonstrates status, a bounded table and the correct empty state. The record page is a base for Files, Conversations, Checklists, Workflow, Record Activity and other first-class blocks. The control-panel showcase demonstrates several responsive proportions and visual rhythms. The live action page combines checklist toggles and Contacts favorites through real API contracts; its page JSON still contains no database or authorization identity.

Professional dashboard - copy the complete page JSON
{
  "blocks": [
    {
      "_id": "professional-dashboard-header",
      "_type": "core.page-header",
      "props": {
        "title": "Operations overview",
        "lead": "A focused view of the work, service level, and team activity that need attention today.",
        "breadcrumb": ["Operations", "Overview"]
      }
    },
    {
      "_id": "professional-dashboard-stats",
      "_type": "core.container",
      "props": { "layout": "grid" },
      "children": [
        {
          "_id": "professional-dashboard-stat-open",
          "_type": "core.stat-tile",
          "props": { "label": "Open work", "value": "128", "delta": "12 this week", "direction": "up", "tone": "primary" }
        },
        {
          "_id": "professional-dashboard-stat-due",
          "_type": "core.stat-tile",
          "props": { "label": "Due today", "value": "17", "delta": "4 at risk", "direction": "down", "tone": "warning" }
        },
        {
          "_id": "professional-dashboard-stat-sla",
          "_type": "core.stat-tile",
          "props": { "label": "Within service level", "value": "96%", "delta": "2.4%", "direction": "up", "tone": "success" }
        },
        {
          "_id": "professional-dashboard-stat-waiting",
          "_type": "core.stat-tile",
          "props": { "label": "Waiting on customer", "value": "23", "tone": "neutral" }
        }
      ]
    },
    {
      "_id": "professional-dashboard-detail-grid",
      "_type": "core.container",
      "props": { "layout": "grid" },
      "children": [
        {
          "_id": "professional-dashboard-trend-card",
          "_type": "core.card",
          "props": { "title": "Work completed", "description": "Six-week throughput from the authorized page scope.", "tone": "primary" },
          "children": [
            {
              "_id": "professional-dashboard-trend-chart",
              "_type": "core.chart",
              "props": {
                "title": "Completed work by week",
                "variant": "line",
                "tone": "primary",
                "series": [38, 45, 42, 56, 61, 73],
                "labels": ["W1", "W2", "W3", "W4", "W5", "W6"]
              }
            }
          ]
        },
        {
          "_id": "professional-dashboard-team-card",
          "_type": "core.card",
          "props": { "title": "Recent team activity", "description": "The latest visible changes across this workspace.", "tone": "success" },
          "children": [
            { "_id": "professional-dashboard-team-label", "_type": "core.section-label", "props": { "label": "Recently updated" } },
            { "_id": "professional-dashboard-team-1", "_type": "core.list-row", "props": { "primary": "Preventive maintenance", "secondary": "North facility · Updated 8 minutes ago", "trailing": "Ready", "initials": "PM", "tone": "success" } },
            { "_id": "professional-dashboard-team-2", "_type": "core.list-row", "props": { "primary": "Customer onboarding", "secondary": "West region · Updated 21 minutes ago", "trailing": "Review", "initials": "CO", "tone": "warning" } },
            { "_id": "professional-dashboard-team-3", "_type": "core.list-row", "props": { "primary": "Quarterly inspection", "secondary": "Central office · Updated 46 minutes ago", "trailing": "Open", "initials": "QI", "tone": "primary" } }
          ]
        }
      ]
    }
  ]
}
Professional work queue - copy the complete page JSON
{
  "blocks": [
    {
      "_id": "professional-queue-header",
      "_type": "core.page-header",
      "props": {
        "title": "Work queue",
        "lead": "A bounded, server-scoped table designed for fast triage instead of fetching an entire record graph.",
        "breadcrumb": ["Operations", "Work queue"]
      }
    },
    {
      "_id": "professional-queue-statuses",
      "_type": "core.container",
      "props": { "layout": "row" },
      "children": [
        { "_id": "professional-queue-status-all", "_type": "core.badge", "props": { "label": "All 128", "tone": "primary" } },
        { "_id": "professional-queue-status-progress", "_type": "core.badge", "props": { "label": "In progress 46", "tone": "success" } },
        { "_id": "professional-queue-status-risk", "_type": "core.badge", "props": { "label": "At risk 4", "tone": "warning" } },
        { "_id": "professional-queue-status-blocked", "_type": "core.badge", "props": { "label": "Blocked 3", "tone": "danger" } }
      ]
    },
    {
      "_id": "professional-queue-card",
      "_type": "core.card",
      "props": { "title": "Priority work", "description": "Preview rows; bind this block to an approved list operation for live tenant data.", "tone": "primary" },
      "children": [
        {
          "_id": "professional-queue-table",
          "_type": "core.data-table",
          "props": {
            "caption": "Priority work queue",
            "columns": [
              { "key": "reference", "label": "Reference", "align": "left" },
              { "key": "summary", "label": "Summary", "align": "left" },
              { "key": "owner", "label": "Owner", "align": "left" },
              { "key": "due", "label": "Due", "align": "left" },
              { "key": "status", "label": "Status", "align": "right" }
            ],
            "rows": [
              { "reference": "WO-1048", "summary": "Inspect cooling system", "owner": "Morgan Lee", "due": "Today", "status": "In progress" },
              { "reference": "TK-318", "summary": "Confirm access window", "owner": "Avery Patel", "due": "Today", "status": "Waiting" },
              { "reference": "WO-1051", "summary": "Replace safety signage", "owner": "Jordan Kim", "due": "Tomorrow", "status": "Ready" },
              { "reference": "AP-092", "summary": "Approve completion proof", "owner": "Riley Chen", "due": "Tomorrow", "status": "Review" }
            ]
          }
        }
      ]
    },
    {
      "_id": "professional-queue-empty",
      "_type": "core.empty-state",
      "props": {
        "title": "No work matches this view",
        "body": "Use this state when an approved query returns zero visible rows; do not substitute an unscoped fallback query."
      }
    }
  ]
}
Professional record detail - copy the complete page JSON
{
  "blocks": [
    {
      "_id": "professional-record-header",
      "_type": "core.page-header",
      "props": {
        "title": "WO-1048 · Inspect cooling system",
        "lead": "A composed record view that can sit beside Files, Conversations, Checklists, Workflow, and Record Activity.",
        "breadcrumb": ["Operations", "Work orders", "WO-1048"]
      }
    },
    {
      "_id": "professional-record-statuses",
      "_type": "core.container",
      "props": { "layout": "row" },
      "children": [
        { "_id": "professional-record-status", "_type": "core.badge", "props": { "label": "In progress", "tone": "success" } },
        { "_id": "professional-record-priority", "_type": "core.badge", "props": { "label": "High priority", "tone": "warning" } },
        { "_id": "professional-record-location", "_type": "core.badge", "props": { "label": "North facility", "tone": "neutral" } }
      ]
    },
    {
      "_id": "professional-record-grid",
      "_type": "core.container",
      "props": { "layout": "grid" },
      "children": [
        {
          "_id": "professional-record-summary",
          "_type": "core.card",
          "props": { "title": "Work summary", "description": "Use nested blocks to compose an editable page without bypassing the page contract.", "tone": "primary" },
          "children": [
            { "_id": "professional-record-summary-label", "_type": "core.section-label", "props": { "label": "Scope" } },
            { "_id": "professional-record-summary-text", "_type": "core.text", "props": { "text": "Inspect the rooftop cooling system, capture proof, and submit the completed checklist for approval.", "variant": "body", "align": "left" } },
            { "_id": "professional-record-owner", "_type": "core.list-row", "props": { "primary": "Morgan Lee", "secondary": "Assigned technician", "trailing": "Today", "initials": "ML", "tone": "primary" } }
          ]
        },
        {
          "_id": "professional-record-proof",
          "_type": "core.card",
          "props": { "title": "Completion proof", "description": "Files and photos remain secured native records; the presentation block only explains the state.", "tone": "success" },
          "children": [
            { "_id": "professional-record-proof-empty", "_type": "core.empty-state", "props": { "title": "No proof attached yet", "body": "Attach photos or documents to checklist items before submitting this work for approval." } }
          ]
        }
      ]
    }
  ]
}
Flexible control-panel showcase - copy the complete page JSON
{
  "blocks": [
    {
      "_id": "control-panel-header",
      "_type": "core.page-header",
      "props": {
        "title": "Service command center",
        "lead": "An original BuildWithHQ composition showing live-looking operational rhythm without prescribing one dashboard layout.",
        "breadcrumb": ["Operations", "Today"]
      }
    },
    {
      "_id": "control-panel-kpis",
      "_type": "core.container",
      "props": { "layout": "grid", "gridMode": "twelve-column", "gap": "normal" },
      "children": [
        {
          "_id": "control-panel-kpi-open",
          "_type": "core.stat-tile",
          "props": {
            "label": "Open requests", "value": "248", "delta": "18 since Monday", "direction": "up", "tone": "primary", "iconName": "inbox",
            "responsive": { "desktop": { "span": 3 }, "tablet": { "span": 6 }, "mobile": { "span": 12 } }
          }
        },
        {
          "_id": "control-panel-kpi-response",
          "_type": "core.stat-tile",
          "props": {
            "label": "First response", "value": "8m", "delta": "2m faster", "direction": "up", "tone": "success", "iconName": "clock",
            "responsive": { "desktop": { "span": 3 }, "tablet": { "span": 6 }, "mobile": { "span": 12 } }
          }
        },
        {
          "_id": "control-panel-kpi-completed",
          "_type": "core.stat-tile",
          "props": {
            "label": "Completed today", "value": "73", "delta": "11 above pace", "direction": "up", "tone": "success", "iconName": "check-circle",
            "responsive": { "desktop": { "span": 3 }, "tablet": { "span": 6 }, "mobile": { "span": 12 } }
          }
        },
        {
          "_id": "control-panel-kpi-risk",
          "_type": "core.stat-tile",
          "props": {
            "label": "Needs attention", "value": "12", "delta": "3 due this hour", "direction": "down", "tone": "warning", "iconName": "activity",
            "responsive": { "desktop": { "span": 3 }, "tablet": { "span": 6 }, "mobile": { "span": 12 } }
          }
        }
      ]
    },
    {
      "_id": "control-panel-primary-grid",
      "_type": "core.container",
      "props": { "layout": "grid", "gridMode": "twelve-column", "gap": "relaxed" },
      "children": [
        {
          "_id": "control-panel-demand-card",
          "_type": "core.card",
          "props": {
            "title": "Demand and completion",
            "description": "A seven-day view. Replace the preview document with one approved server-scoped binding.",
            "tone": "primary",
            "responsive": { "desktop": { "span": 8 }, "tablet": { "span": 12 }, "mobile": { "span": 12 } }
          },
          "children": [
            {
              "_id": "control-panel-demand-chart",
              "_type": "core.series-chart",
              "props": {
                "title": "Requests compared with completions",
                "variant": "line",
                "defaultPeriodKey": "week",
                "periods": [
                  {
                    "key": "week",
                    "label": "7 days",
                    "labels": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
                    "series": [
                      { "key": "opened", "label": "Opened", "tone": "primary", "values": [32, 41, 36, 54, 49, 28, 24] },
                      { "key": "completed", "label": "Completed", "tone": "success", "values": [27, 35, 39, 45, 51, 34, 31] }
                    ]
                  },
                  {
                    "key": "month",
                    "label": "4 weeks",
                    "labels": ["Week 1", "Week 2", "Week 3", "Week 4"],
                    "series": [
                      { "key": "opened", "label": "Opened", "tone": "primary", "values": [228, 241, 219, 264] },
                      { "key": "completed", "label": "Completed", "tone": "success", "values": [215, 232, 238, 251] }
                    ]
                  }
                ]
              }
            }
          ]
        },
        {
          "_id": "control-panel-team-card",
          "_type": "core.card",
          "props": {
            "title": "Team pulse", "description": "Recent visible ownership and status.", "tone": "success",
            "responsive": { "desktop": { "span": 4 }, "tablet": { "span": 12 }, "mobile": { "span": 12 } }
          },
          "children": [
            {
              "_id": "control-panel-team-list",
              "_type": "core.entity-list",
              "props": {
                "title": "Active teammates",
                "items": [
                  { "id": "team-avery", "primary": "Avery Chen", "secondary": "Onboarding queue", "initials": "AC", "status": { "key": "available", "label": "Available", "tone": "success" }, "trailing": "12", "trailingLabel": "open" },
                  { "id": "team-morgan", "primary": "Morgan Lee", "secondary": "Field service", "initials": "ML", "status": { "key": "focused", "label": "Focused", "tone": "primary" }, "trailing": "8", "trailingLabel": "open" },
                  { "id": "team-jordan", "primary": "Jordan Patel", "secondary": "Escalations", "initials": "JP", "status": { "key": "busy", "label": "Busy", "tone": "warning" }, "trailing": "5", "trailingLabel": "open" },
                  { "id": "team-riley", "primary": "Riley Brooks", "secondary": "Knowledge review", "initials": "RB", "status": { "key": "available", "label": "Available", "tone": "success" }, "trailing": "9", "trailingLabel": "open" }
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "_id": "control-panel-secondary-grid",
      "_type": "core.container",
      "props": { "layout": "grid", "gridMode": "twelve-column", "gap": "normal" },
      "children": [
        {
          "_id": "control-panel-priority-card",
          "_type": "core.card",
          "props": {
            "title": "Priority mix", "description": "Distribution of the current authorized workload.", "tone": "warning",
            "responsive": { "desktop": { "span": 5 }, "tablet": { "span": 6 }, "mobile": { "span": 12 } }
          },
          "children": [
            {
              "_id": "control-panel-priority-list",
              "_type": "core.progress-list",
              "props": {
                "items": [
                  { "key": "urgent", "label": "Urgent", "value": 12, "maximum": 248, "displayValue": "12", "tone": "danger" },
                  { "key": "high", "label": "High", "value": 54, "maximum": 248, "displayValue": "54", "tone": "warning" },
                  { "key": "normal", "label": "Normal", "value": 146, "maximum": 248, "displayValue": "146", "tone": "primary" },
                  { "key": "low", "label": "Low", "value": 36, "maximum": 248, "displayValue": "36", "tone": "neutral" }
                ]
              }
            }
          ]
        },
        {
          "_id": "control-panel-activity-card",
          "_type": "core.card",
          "props": {
            "title": "Recent activity", "description": "Changes already authorized for this user.", "tone": "primary",
            "responsive": { "desktop": { "span": 7 }, "tablet": { "span": 6 }, "mobile": { "span": 12 } }
          },
          "children": [
            {
              "_id": "control-panel-activity-timeline",
              "_type": "core.timeline",
              "props": {
                "items": [
                  { "id": "event-1", "occurredUtc": "2026-09-05T15:42:00Z", "title": "Ticket BH-1842 resolved", "description": "Proof reviewed and customer notified.", "actor": "Avery Chen", "tone": "success" },
                  { "id": "event-2", "occurredUtc": "2026-09-05T15:31:00Z", "title": "Work order WO-882 assigned", "description": "Assigned to the west field team.", "actor": "Morgan Lee", "tone": "primary" },
                  { "id": "event-3", "occurredUtc": "2026-09-05T15:08:00Z", "title": "Checklist submitted", "description": "Site opening checklist is ready for signoff.", "actor": "Riley Brooks", "tone": "warning" }
                ]
              }
            }
          ]
        }
      ]
    }
  ]
}
Live checklist and Contacts actions - copy the complete page JSON
{
  "blocks": [
    {
      "_id": "live-actions-header",
      "_type": "core.page-header",
      "props": {
        "title": "Live checklist and contact actions",
        "lead": "These components receive only the records and actions authorized for the signed-in user. Checklist toggles use optimistic concurrency; contact actions refetch their scoped presentation after each write."
      }
    },
    {
      "_id": "live-actions-layout",
      "_type": "core.container",
      "props": {
        "layout": "grid",
        "gridMode": "twelve-column",
        "gap": "normal"
      },
      "children": [
        {
          "_id": "live-actions-checklist-card",
          "_type": "core.card",
          "props": {
            "title": "Checklist work",
            "description": "Items outside the user's DataRole and Location scope are never sent to the browser.",
            "responsive": {
              "desktop": { "span": 5 },
              "tablet": { "span": 12 },
              "mobile": { "span": 12 }
            }
          },
          "children": [
            {
              "_id": "live-actions-checklist",
              "_type": "core.task-list",
              "bindingKey": "checklists-signoffs.presentation",
              "dataKey": "tasks",
              "props": {}
            }
          ]
        },
        {
          "_id": "live-actions-contacts-card",
          "_type": "core.card",
          "props": {
            "title": "Recent contacts",
            "description": "The grid is bounded to 25 visible contacts and each row declares only its currently valid favorite action.",
            "responsive": {
              "desktop": { "span": 7 },
              "tablet": { "span": 12 },
              "mobile": { "span": 12 }
            }
          },
          "children": [
            {
              "_id": "live-actions-contacts",
              "_type": "core.presentation-grid",
              "bindingKey": "contacts.presentation",
              "dataKey": "table",
              "props": {}
            }
          ]
        }
      ]
    }
  ]
}
Work Order Home panel - copy the complete page JSON
{
  "blocks": [
    {
      "_id": "home-work-orders-presentation",
      "_type": "core.card",
      "props": {
        "title": "Work order overview",
        "description": "Current workload, status, trends and activity from one server-scoped API presentation.",
        "tone": "neutral"
      },
      "children": [
        {
          "_id": "home-work-orders-metrics",
          "_type": "core.metric-strip",
          "bindingKey": "work-orders.presentation",
          "dataKey": "metrics",
          "props": {}
        },
        {
          "_id": "home-work-orders-summary",
          "_type": "core.container",
          "props": {
            "layout": "grid"
          },
          "children": [
            {
              "_id": "home-work-orders-status",
              "_type": "core.progress-list",
              "bindingKey": "work-orders.presentation",
              "dataKey": "byStatus",
              "props": {}
            },
            {
              "_id": "home-work-orders-recent",
              "_type": "core.entity-list",
              "bindingKey": "work-orders.presentation",
              "dataKey": "recent",
              "props": {}
            }
          ]
        },
        {
          "_id": "home-work-orders-trend",
          "_type": "core.series-chart",
          "bindingKey": "work-orders.presentation",
          "dataKey": "trend",
          "props": {}
        },
        {
          "_id": "home-work-orders-table",
          "_type": "core.presentation-grid",
          "bindingKey": "work-orders.presentation",
          "dataKey": "table",
          "props": {}
        },
        {
          "_id": "home-work-orders-timeline",
          "_type": "core.timeline",
          "bindingKey": "work-orders.presentation",
          "dataKey": "timeline",
          "props": {}
        }
      ]
    }
  ]
}
Work Order command center - copy the complete page JSON
{
  "blocks": [
    {
      "_id": "work-order-command-center-header",
      "_type": "core.page-header",
      "props": {
        "title": "Work order command center",
        "lead": "Live workload, status, trends and recent activity from one server-scoped API presentation.",
        "breadcrumb": ["Operations", "Work orders"]
      }
    },
    {
      "_id": "work-order-command-center-metrics",
      "_type": "core.metric-strip",
      "bindingKey": "work-orders.presentation",
      "dataKey": "metrics",
      "props": {}
    },
    {
      "_id": "work-order-command-center-summary",
      "_type": "core.container",
      "props": {
        "layout": "grid"
      },
      "children": [
        {
          "_id": "work-order-command-center-status",
          "_type": "core.progress-list",
          "bindingKey": "work-orders.presentation",
          "dataKey": "byStatus",
          "props": {}
        },
        {
          "_id": "work-order-command-center-recent",
          "_type": "core.entity-list",
          "bindingKey": "work-orders.presentation",
          "dataKey": "recent",
          "props": {}
        }
      ]
    },
    {
      "_id": "work-order-command-center-trend",
      "_type": "core.series-chart",
      "bindingKey": "work-orders.presentation",
      "dataKey": "trend",
      "props": {}
    },
    {
      "_id": "work-order-command-center-table",
      "_type": "core.presentation-grid",
      "bindingKey": "work-orders.presentation",
      "dataKey": "table",
      "props": {}
    },
    {
      "_id": "work-order-command-center-timeline",
      "_type": "core.timeline",
      "bindingKey": "work-orders.presentation",
      "dataKey": "timeline",
      "props": {}
    }
  ]
}
Tip

Keep every _id stable while editing. Template upgrades use block identity to compare and merge changes. Give a copied block a new unique ID instead of duplicating an existing one.

4. Edit the pages in Puck

  1. Open an account-owned workshop SaaS and create or open a page in Design mode.
  2. Drag a component from BuildWithHQ components, or load one of the complete page sources above through the supported page authoring flow.
  3. Select a Container and choose its Layout, Grid behavior and Spacing. For any block inside a 12-column canvas, choose Desktop, Tablet and Mobile width through desktopSpan, tabletSpan and mobileSpan. Advanced JSON remains available, but routine layout work does not require it.
  4. Preview desktop and mobile layouts, save a draft, then publish through the normal page validator.

For example, this is the complete properties object for a stat tile:

{
  "label": "Open work",
  "value": "128",
  "delta": "12 this week",
  "direction": "up",
  "iconName": "inbox",
  "tone": "primary"
}

The editor round-trips these properties into block.props. It preserves canonical block identity, parent/child structure, responsive settings, event bindings, security metadata, bindingKey and dataKey.

5. Choose a token-safe theme

The presets use the existing SaaS app theme contract: themeJson selects light, dark or system; cssVariables contains allowlisted runtime tokens; and designTokensJson sets base spacing and radius. The runtime parses the document fail-closed, stamps the document element, and applies the tokens to painted components.

BuildWithHQ Indigo Light - copy the complete theme JSON
{
  "schemaVersion": 1,
  "themeKey": "buildwithhq-indigo-light",
  "themeJson": { "schemaVersion": 1, "name": "BuildWithHQ Indigo Light", "mode": "light" },
  "cssVariables": {
    "--runtime-primary": "#4b45e8",
    "--runtime-primary-strong": "#302b8e",
    "--runtime-primary-tint": "rgba(75,69,232,.13)",
    "--runtime-page": "#f4f6fb",
    "--runtime-surface": "#ffffff",
    "--runtime-surface-raised": "#f8f9fc",
    "--runtime-ink": "#17202f",
    "--runtime-ink-muted": "#667085",
    "--runtime-line": "#dfe3ed"
  },
  "designTokensJson": { "spacingBase": 8, "radiusBase": 8 }
}
Executive Slate Dark - copy the complete theme JSON
{
  "schemaVersion": 1,
  "themeKey": "executive-slate-dark",
  "themeJson": { "schemaVersion": 1, "name": "Executive Slate Dark", "mode": "dark" },
  "cssVariables": {
    "--runtime-primary": "#9ea8ff",
    "--runtime-primary-strong": "#c7ccff",
    "--runtime-primary-tint": "rgba(158,168,255,.18)",
    "--runtime-page": "#0e1420",
    "--runtime-surface": "#171e2c",
    "--runtime-surface-raised": "#20293a",
    "--runtime-ink": "#edf1f7",
    "--runtime-ink-muted": "#a8b2c4",
    "--runtime-line": "#303b50"
  },
  "designTokensJson": { "spacingBase": 8, "radiusBase": 10 }
}
Service Emerald Light - copy the complete theme JSON
{
  "schemaVersion": 1,
  "themeKey": "service-emerald-light",
  "themeJson": { "schemaVersion": 1, "name": "Service Emerald Light", "mode": "light" },
  "cssVariables": {
    "--runtime-primary": "#16705a",
    "--runtime-primary-strong": "#0d4f40",
    "--runtime-primary-tint": "rgba(22,112,90,.14)",
    "--runtime-page": "#f2f7f5",
    "--runtime-surface": "#ffffff",
    "--runtime-surface-raised": "#f6faf8",
    "--runtime-ink": "#172521",
    "--runtime-ink-muted": "#61716b",
    "--runtime-line": "#d7e5df"
  },
  "designTokensJson": { "spacingBase": 8, "radiusBase": 8 }
}
Important

Do not paste theme JSON into a tenant table or add an arbitrary CSS/script field. Theme writes must go through the supported version-fenced builder contract. Template-pack artifact schema v2 pins pages and effective components, not the optional legacy live ThemeKey lookup; these presets are instead versioned by the developer-kit integrity manifest and ZIP SHA-256. The public builder theme switcher is still a separate delivery step.

6. Replace preview values with live, scoped data

Static values are useful while designing. For live data, register a reviewed binding and put only its stable key on the block. dataKey may select a bounded property from the returned JSON; it is not a query language.

{
  "_id": "visible-work-table",
  "_type": "core.data-table",
  "bindingKey": "work-orders.current-page",
  "dataKey": "items",
  "props": {
    "caption": "Visible work orders",
    "columns": [
      { "key": "reference", "label": "Reference", "align": "left" },
      { "key": "summary", "label": "Summary", "align": "left" },
      { "key": "status", "label": "Status", "align": "right" }
    ]
  }
}

The approved server operation may return shapes like these:

{
  "stat": { "value": 128, "delta": "12 this week", "direction": "up" },
  "chart": {
    "title": "Completed work",
    "series": [38, 45, 42, 56, 61, 73],
    "labels": ["W1", "W2", "W3", "W4", "W5", "W6"]
  },
  "table": {
    "items": [
      { "reference": "WO-1048", "summary": "Inspect cooling system", "status": "In progress" }
    ]
  }
}
  • A stat accepts a scalar or an object with value, delta and direction.
  • A chart accepts finite numeric series plus short labels.
  • A table accepts an array or an object containing items; columns explicitly select display fields.
  • A failed bound table never falls back to its static preview rows. It shows a loading, error or no-visible-data state.
Important

Page JSON must never contain a database name, connection string, SaaSAppId, AppAccountId, UserId, DataRoleId or LocationId as authorization evidence. The server derives identity and scope from the verified session.

7. Turn the workshop pages into a reusable template

  1. Customize the pages in an account-owned workshop SaaS.
  2. Save the selected theme through the supported version-fenced authoring contract when that builder surface is available.
  3. Harvest each owned Page with POST /api/apps/{saasAppId}/template-harvests.
  4. Attach the harvested artifacts to a draft pack and run the existing pack validator.
  5. Publish an immutable Template Library version.
  6. Install that exact version into a different disposable SaaS and run real auth, permission, binding, layout and failure tests before offering it broadly.
Copy the source-kit manifest
{
  "schemaVersion": 1,
  "templateKey": "professional-foundation",
  "templateName": "BuildWithHQ Professional Foundation",
  "version": "1.0.0",
  "description": "Clean-room professional page compositions and theme presets built from the canonical BuildWithHQ component registry.",
  "delivery": "authoring-source-for-exact-version-template-pack",
  "installRequiresExactVersion": true,
  "runtimeDataAccess": "approved-server-scoped-bindings-only",
  "publicDistribution": {
    "kind": "builder-developer-kit",
    "version": "1.20.66",
    "supportedProducts": [
      "buildwithhq",
      "api43"
    ],
    "apiBaseUrl": "https://api.buildwithhq.com",
    "mcpEndpointTemplate": "https://api.buildwithhq.com/v1/apps/{saasAppId}/mcp",
    "archiveName": "BuildWithHQ-API43-Developer-Kit-1.20.66.zip"
  },
  "requiredComponents": [
    "module.support-lanes",
    "module.support-lanes.toolbar",
    "module.support-lanes.list",
    "module.support-lanes.editor",
    "core.badge",
    "core.card",
    "core.chart",
    "core.container",
    "core.data-table",
    "core.empty-state",
    "core.list-row",
    "core.page-header",
    "core.section-label",
    "core.stat-tile",
    "core.text"
  ],
  "pages": [
    {
      "pageKey": "ProfessionalDashboard",
      "name": "Professional dashboard",
      "path": "pages/professional-dashboard.json"
    },
    {
      "pageKey": "ProfessionalQueue",
      "name": "Professional work queue",
      "path": "pages/professional-queue.json"
    },
    {
      "pageKey": "ProfessionalRecord",
      "name": "Professional record detail",
      "path": "pages/professional-record.json"
    }
  ],
  "themes": [
    {
      "themeKey": "buildwithhq-indigo-light",
      "name": "BuildWithHQ Indigo Light",
      "path": "themes/buildwithhq-indigo-light.json"
    },
    {
      "themeKey": "executive-slate-dark",
      "name": "Executive Slate Dark",
      "path": "themes/executive-slate-dark.json"
    },
    {
      "themeKey": "service-emerald-light",
      "name": "Service Emerald Light",
      "path": "themes/service-emerald-light.json"
    }
  ],
  "publication": {
    "harvestEndpoint": "POST /api/apps/{saasAppId}/template-harvests",
    "artifactTypes": [
      "Page"
    ],
    "ownership": "verified-account-owner",
    "destination": "BuildWithHQ_TemplateLibrary",
    "snapshot": "published-immutable-exact-version",
    "exactVersionContents": [
      "PackSettings",
      "Page",
      "Component"
    ],
    "themePresetDelivery": "checksummed-developer-kit-and-version-fenced-builder-theme-write"
  },
  "security": {
    "identitySource": "verified-server-session",
    "pageJsonCarriesAuthority": false,
    "dataBindings": "tenant+datarole+location scoped before serialization"
  }
}

Template installation is snapshot isolation. A later upstream page or component edit can become a new pack version, but it must not silently mutate a tenant that installed an earlier one. Apply a preset theme separately through the version-fenced theme write; do not claim a live theme catalog lookup is part of the immutable pack.

8. Know the fail-closed limits and verify your template

  • Tables render at most 500 rows and 24 declared columns. Keep pagination and filtering on the server.
  • Task lists render at most 1,000 rows; grids declare at most eight actions and eight action keys per row.
  • Charts render at most 60 finite points. Use a summarized binding rather than sending raw event history.
  • dataKey is at most eight safe path segments. Missing or invalid paths return no selected data.
  • Text, labels, breadcrumbs and cell values are length-bounded and rendered as React text, not executable HTML.
  • No CDN, arbitrary runtime script, direct SQL connection or physical tenant database selector is introduced.

Repository maintainers run the source, renderer, editor and catalog checks below before releasing a new foundation version. Builders installing an approved exact version do not need these commands:

python -m pytest templates\professional-foundation\tests -q
npm --prefix apps\tenant-runtime test -- src\ProfessionalPrimitives.test.tsx src\PageRenderer.test.tsx src\PuckPageDesignerAdapter.test.ts
npm --prefix apps\tenant-runtime run build

# Regenerate the implementation catalog while retaining runtime observations.
python catalog-generator\generate_catalog.py --observations artifacts\catalog-observations\tenant-runtime-2026-09-03.jsonl
python catalog-generator\generate_catalog.py --check

Then run an authenticated browser journey through the real auth, SQL, API and runtime paths. Check the selected theme, all expected blocks, empty/loading/error states, mobile overflow, keyboard access, cross-tenant rejection and exact result cardinality.

Continue with the interactive API presentation guide, complete React component catalog, page authoring guide, and template versioning guide.

Support lane manager

The editable organization-owned email/SMS lane manager is included in the current kit. See support lanes, installation and API contracts.

Capability review: 2026-09-14. See current features and setup requirements, the generated API Map and first-class module inventory.