Skip to content

Documentation

Dashboard Widget Development

Hub for building, packaging, and publishing SveltyCMS dashboard widgets โ€” self-contained marketplace-portable packages.

8/23/2026
3 min read Edit on GitHub

The admin Dashboard is a widget-based grid. Each widget is a self-contained package living in its own kebab-case folder under src/routes/(app)/dashboard/widgets/<folder>/. Packages are discovered at build time by Vite import.meta.glob โ€” no manual registration, no runtime filesystem scans.

Core commerce packages (freemium, 14-day trial): Commerce Orders (commerce-orders) and Commerce Inventory (commerce-inventory). They read the optional ecommerce preset collections and stay empty on a non-store CMS. Catalog data can be imported with Smart Importer (WooCommerce / Shopify). Product map: E-Commerce Overview.

๐Ÿ“š Documentation Map

Guide Description
Architecture Folder structure, widget.json manifest, registry, and licensing.
Development Step-by-step guide to building your own dashboard widget.
Marketplace Publishing dashboard widgets to marketplace.sveltycms.com.

๐Ÿ—‚๏ธ Package Layout (1 folder = 1 widget)

Every dashboard widget must ship a co-located .mdx file that describes the widget โ€” the marketplace uses it for the package listing card and detail page:

src/routes/(app)/dashboard/widgets/
  system-health/
    index.svelte    # Entry component (fixed name)
    widget.json     # Marketplace manifest (required)
    readme.mdx      # Marketplace description (REQUIRED, fixed name)
  logs/
    index.svelte
    widget.json
    readme.mdx
  commerce-orders/   # freemium, 14-day trial
    index.svelte
    widget.json
    readme.mdx
  • Folder โ€” kebab-case package id (system-health, logs, last5-content).
  • Component โ€” always index.svelte. The folder id is the registry key saved in user layouts, so renaming the implementation file never breaks saved dashboards.
  • widget.json โ€” machine-readable metadata for the marketplace, the in-app catalog, and telemetry.
  • <component>.mdx โ€” human-readable marketplace description: features, licensing, data source, and metadata. Required for every package.

๐Ÿ” How Discovery Works

Layer Mechanism
Client registry +page.svelte โ€” optional widgets; picker from page data; Svelte chunk only when added / visible
Server widget picker +page.server.ts โ€” widget.json via getInstalledDashboardWidgets() (no Svelte eval)
Saved layout Hydrated in load() from system.preferences; client skips /api/system-preferences on first paint
Manifest registry manifest-registry.ts โ€” import.meta.glob("./*/widget.json")
Telemetry Reports installed package ids via the manifest registry
Marketplace catalog Local packages appear in GET /api/marketplace (offline-first merge)

Drop a new folder into widgets/, restart the dev server, and the widget appears in the picker โ€” the same flow a marketplace install uses.


๐Ÿงช Testing Policy

  • Shell tests (tests/unit/routes/dashboard-page-server.test.ts) assert the registry shape, never a fixed widget list โ€” the catalog is install-specific.
  • Runtime helpers (tests/unit/dashboard/dashboard-runtime.test.ts) cover picker mapping, CMS-range filtering, layout unwrap, and hidden-tab poll gating.
  • Widget defaults are unit-tested in tests/unit/dashboard/widget-defaults.test.ts.
  • Per-widget tests live in the widgetโ€™s own folder (widgets/<folder>/tests/) โ€” optional but encouraged for marketplace submissions.

Related

dashboardwidgetsdevelopmentmarketplace
Was this page helpful?