Subchapter 2.6
references/AUTO_PATTERNS_DASHBOARD.mdMarkdown19 KBView on GitHub
Generates declarative patterns.json + a thin page component (<page-name>.tsx) for simple CRUD dashboard pages using @wix/auto-patterns. Supports both creating new pages and updating existing ones.
wix generate, generate schema, run generator scriptpatterns.json, consult references, edit directly@wix/auto-patterns, @wix/patterns)Auto-patterns calls @wix/data at runtime to CRUD the collection. The app must declare these scopes in the Wix Dev Center — they are NOT added automatically:
SCOPE.DC-DATA.READ — for get, query, count, distinctSCOPE.DC-DATA.WRITE — for insert, update, save, remove, bulk*Add them at: https://manage.wix.com/apps/{app-id}/dev-center-permissions (replace {app-id} with your app ID).
Without these scopes, the dashboard page renders but all data operations fail.
enumConfig is required (implicit or explicit):
label from value (e.g., “dog” -> “Dog”) unless specified.pages array (collectionPage + entityPage).layout array in collectionPage.collectionPage.create action in collectionPage navigating to entityPage.type: 'collectionPage' THEN only collectionPage field allowed.type: 'entityPage' THEN only entityPage field allowed.AppConfig structure.An auto-patterns page is a dashboard page — scaffold it with the Wix CLI:
wix generate --params '{"extensionType":"DASHBOARD_PAGE","title":"<title>","route":"<route>"}'The CLI generates the page folder, the component stub <page-name>.tsx, the builder file <page-name>.extension.ts (which registers the extension and points its component at <page-name>.tsx), a unique UUID, and the src/extensions.ts registration — do NOT hand-write any of these. The folder name comes from route. After scaffolding, the page folder looks like this:
src/extensions/dashboard/pages/<page-name>/
├── <page-name>.extension.ts # Builder file (generated — registration + UUID, component → <page-name>.tsx)
├── <page-name>.tsx # CLI component stub (overwritten in Step 3)
└── patterns.json # Declarative AppConfig — added in Step 3, edit this to iterateWhy this matters for Step 3: the generator writes the auto-patterns wrapper to
<page-name>.tsx— the SAME file the builder already registers — so it overwrites the stub and is wired up automatically. Do NOT let it produce a separatepage.tsx; that would leave the wrapper unregistered next to the empty stub, and the dashboard would render blank.
You must produce the input JSON for the generator script. Top-level keys: collection, schema, relevantCollectionId, extensionName.
collection (from the data collection you scaffolded):
idSuffix — the collection’s short IDfields — array of { key, displayName, type } (types: TEXT, NUMBER, BOOLEAN, DATE, IMAGE, URL, RICH_TEXT, etc.)relevantCollectionId (top-level, sibling to collection and schema) — full scoped collection ID (e.g., @namespace/my-collection)
schema.content — 20 string fields you generate:
collectionRouteId — URL-friendly collection ID (kebab-case, e.g., “cool-gadgets”)singularEntityName — URL-friendly singular form (e.g., “cool-gadget”)pageTitle — Main page title (e.g., “Cool Gadgets Collection”)pageSubtitle — Page descriptionactionButtonLabel — Primary create button (e.g., “Add New Gadget”)toolbarTitle — Table toolbar titletoolbarSubtitle — Table toolbar subtitleemptyStateTitle — Title when no items existemptyStateSubtitle — Empty state descriptionemptyStateButtonText — Empty state CTA button textdeleteModalTitle — Delete confirmation titledeleteModalDescription — Delete confirmation descriptiondeleteSuccessToast — Delete success messagedeleteErrorToast — Delete error messagebulkDeleteModalTitle — Bulk delete titlebulkDeleteModalDescription — Bulk delete descriptionbulkDeleteSuccessToast — Bulk delete successbulkDeleteErrorToast — Bulk delete errorentityPageTitle — Entity detail page titleentityPageSubtitle — Entity detail page subtitleschema.layout — organize ALL collection fields into sections:
{
"main": [
{
"title": "Basic Info",
"subtitle": "Core details",
"fields": ["field1", "field2"]
}
],
"sidebar": [
{ "title": "Status", "subtitle": "Metadata", "fields": ["isActive"] }
]
}Rules: Every field must appear exactly once. Main = user-facing content. Sidebar = metadata/status. If there are no sidebar-worthy fields, use "sidebar": [].
schema.columns — ordered list for the table view:
[{ "id": "fieldKey", "displayName": "Short Name" }]Include ALL fields, primary identifiers first. Display names target ≤10 characters.
schema.gridItem (only if IMAGE fields exist, otherwise null):
{
"titleFieldId": "name",
"subtitleFieldId": "category",
"imageFieldId": "photo"
}🛑 Nesting is required. Content, layout, columns, and gridItem are not top-level keys and not flat siblings under
schema. The generator rejects flat shapes like"schema": { "collectionRouteId": "...", "main": [...] }. Always nest as"schema": { "content": {...}, "layout": {...}, "columns": [...], "gridItem": null }.
The generator script is bundled with this skill at <SKILL_ROOT>/scripts/generate-auto-patterns.js — it is not copied into the user’s app repo. Run it from the project directory using the skill’s absolute path (<SKILL_ROOT> is the folder containing this skill’s SKILL.md).
Write the input JSON to a temp file and run the script, pointing --output at the folder the CLI scaffolded in Step 1:
# Write input to temp file
cat > /tmp/auto-patterns-input.json << 'EOF'
{
"collection": {
"idSuffix": "<collection-id>",
"fields": [
{ "key": "<field-key>", "displayName": "<Field Label>", "type": "<TYPE>" }
]
},
"schema": {
"content": {
"collectionRouteId": "<collection-route-id>",
"singularEntityName": "<singular-entity-name>",
"pageTitle": "<Page Title>",
"pageSubtitle": "<Page subtitle>",
"actionButtonLabel": "<Create button label>",
"toolbarTitle": "<Toolbar title>",
"toolbarSubtitle": "<Toolbar subtitle>",
"emptyStateTitle": "<Empty state title>",
"emptyStateSubtitle": "<Empty state subtitle>",
"emptyStateButtonText": "<Empty state button>",
"deleteModalTitle": "<Delete modal title>",
"deleteModalDescription": "<Delete modal description>",
"deleteSuccessToast": "<Delete success toast>",
"deleteErrorToast": "<Delete error toast>",
"bulkDeleteModalTitle": "<Bulk delete modal title>",
"bulkDeleteModalDescription": "<Bulk delete modal description>",
"bulkDeleteSuccessToast": "<Bulk delete success toast>",
"bulkDeleteErrorToast": "<Bulk delete error toast>",
"entityPageTitle": "<Entity page title>",
"entityPageSubtitle": "<Entity page subtitle>"
},
"layout": {
"main": [
{
"title": "<Section title>",
"subtitle": "<Section subtitle>",
"fields": ["<field-key>"]
}
],
"sidebar": []
},
"columns": [
{ "id": "<field-key>", "displayName": "<Short Name>" }
],
"gridItem": null
},
"relevantCollectionId": "@<namespace>/<collection-id>",
"extensionName": "<Extension Name>"
}
EOF
# Run generator
node <SKILL_ROOT>/scripts/generate-auto-patterns.js --input /tmp/auto-patterns-input.json --output ./src/extensions/dashboard/pages/<page-name>/The --output directory MUST be the exact folder the CLI scaffolded in Step 1 — the script derives the component filename from that folder’s name.
The script produces:
patterns.json — The declarative AppConfig<page-name>.tsx — Thin React wrapper component, written to the SAME filename the CLI scaffolded and the builder already registers (overwrites the stub)The builder file (<page-name>.extension.ts) and src/extensions.ts registration from Step 1 stay as-is — no manual registration edit, and no stray page.tsx.
The CLI template pins @wix/auto-patterns and @wix/patterns to exact versions — keep it that way. Check package.json first: if both are already in dependencies, skip this step.
If one is missing, install only that package:
npm install --save-exact <missing-package>Run validation per APP_VALIDATION.md to verify TypeScript compilation and build.
🛑 STOP — UI changes go through overrides, NOT page-component edits. If you’re adding a banner, custom header, action, slot, custom column rendering, or row sectioning to an auto-patterns page, you MUST use the matching
custom-*-override.mdreference (see the topic index in Step 2). Do NOT add the UI by hand-writing JSX in the page component (<page-name>.tsx) — that bypasses the override registration and breaks the iteration model.
When patterns.json already exists in a page directory, edit it directly. This is the iteration model: changes to layout, columns, actions, and content are made by editing JSON — the page component (<page-name>.tsx) only changes to register new overrides. No React rewrite, no rebuild of CRUD logic.
Component filename: the page component is
<page-name>.tsx(the file the CLI scaffolded and the<page-name>.extension.tsbuilder registers). The override reference files below say “page.tsx“ as shorthand for this component — edit the existing<page-name>.tsx; never create a newpage.tsx, or it will sit unregistered next to the real component.
Read the current patterns.json to understand the configuration structure.
Use the topic index below to find the right reference file for your change:
| Topic | Keywords | Reference File |
|---|---|---|
| AppConfig structure, page types, component types, page.tsx template | AppConfig, PageConfig, CollectionPageConfig, EntityPageConfig | app-config-structure.md |
| Page setup, relationships, routing, URL configuration, sticky columns | page relationships, routing, entityPageId, parentPageId, route parameters | pages-configuration.md |
| Collection page components, table/grid layouts, column configuration | table/grid configuration, columns, customColumns, view switching | collection-page.md |
| Views configuration, presets, categories, filters integration | views, presets, categories, columnPreferences, filters, default view | views.md |
| Page-level actions, create actions, custom collection actions, row click actions | primaryActions, secondaryActions, onRowClick, action menus | collection-page-actions.md |
| Row-level actions, update/delete actions, custom row actions | actionCell, edit, delete, inline actions, custom resolver | action-cell.md |
| Bulk operations, bulk delete, bulk action toolbar | bulk delete, multi-select actions, bulkActionToolbar | bulk-actions.md |
| Entity page layout, grid system, field layout, containers | entity page layout, grid system, column spans, main/sidebar, 12-column grid | entity-page.md |
| Entity page edit mode actions, moreActions, custom entity actions | edit mode actions, moreActions, duplicate, clone | entity-page-actions.md |
| Entity page view mode actions, primaryActions, secondaryActions | view mode actions, read-only entity actions, navigation actions | entity-page-view-actions.md |
| ResolvedAction interface, common return type for custom actions | ResolvedAction, label, icon, onClick, disabled, hidden, tooltip, skin | resolved-action.md |
| AppContext hook, shared collection data, refresh functionality | useAppContext, items, refreshCollection | app-context.md |
| SDK utilities, optimistic actions, schema access | AutoPatternsSDK, optimisticActions, getSchema, createOne, updateOne, deleteOne | sdk-utilities.md |
| Custom action resolvers, action overrides, useActions hook | custom actions, action resolver, useActions, ResolvedAction | custom-actions-override.md |
| Column rendering overrides, IColumnValue, custom column display | column override, IColumnValue, useColumns, custom rendering | custom-columns-override.md |
| Custom form components, useController, entity page customization | custom components, useComponents, useController, form, entity | custom-components-override.md |
| Entity page header, dynamic subtitle, dynamic badges | header override, subtitle, badges, entityPageHeaderSubtitle, entityPageHeaderBadges | custom-header-override.md |
| Table row grouping, section headers, section renderer | sections, grouping, useSections, section renderer, row grouping | custom-sections-override.md |
| Custom slot components, page slots, banners, informational sections | slots, useSlots, banner, custom content, top section | custom-slots-override.md |
Edit patterns.json based on the user’s request. Key constraints:
collectionPage + one entityPageentityPageId in collection component ↔ parentPageId in entity pagebiName is mandatory for every action (kebab-case: {action-purpose}-action)customColumns.enabled: true when > 5 columns/[segment]/:entityIdappMainPage: true across all pagesIf adding custom overrides (actions, columns, components, slots, etc.):
components/ subfolder<page-name>.tsx) to register overrides via PatternsWizardOverridesProvidercustom-*-override.md reference files for implementation patterns🛑 Overrides ALWAYS go in their own file under
components/<type>/(e.g.components/columns/status.tsx) with ause*hook — regardless of size, even for a single small override. This is structural, required by the override-registration model. Never inline override render logic in the page component (<page-name>.tsx), and do NOT apply the general ~300-line “split only if large” rule here — it does not override this requirement.
Do NOT use this skill when:
See auto-patterns-dashboard/example-patterns.json for a complete working example.