Not released yet. PeltyCMS is under development and not released yet; these docs describe the upcoming release and may change.
PeltyCMS Developer docs
User docsDevelopers
v0.1.0

Developer docs/Extension reference

Widgets and slots

Every place where an addon can inject UI: 82 admin pages and 27 client pages, each with its own page slots, 8 layout slots and 11 hand-placed named slots (579 slot names in total, wildcards not counted). Generated from frontend/src/App.tsx, frontend/src/layouts/Shell.tsx and the <PluginSlot> / <PluginWidgets> calls; a test fails when the frontend renders a position the docs do not list.

#Two ways to render

#Registering a slot contribution

List contributions in addon.json ui.slots. order sorts contributions in the same slot (lower first). Text that starts with plugin.<addon-id>. is translated from the manifest i18n. Page context is available as {{ctx.*}}.

JSON
{
  "ui": {
    "slots": [
      {
        "body": {
          "text": "{{t:plugin.my-addon.badge}}",
          "type": "badge"
        },
        "order": 5,
        "slot": "admin.invoices.toolbar"
      },
      {
        "body": {
          "children": [
            {
              "label": "plugin.my-addon.score",
              "type": "stat",
              "value": "{{data.score.value}}"
            }
          ],
          "type": "card"
        },
        "data": {
          "score": {
            "get": "/api/v1/addons/my-addon/score?customer={{ctx.id}}"
          }
        },
        "slot": "admin.customers.detail-panel"
      },
      {
        "frame": {
          "height": 64,
          "src": "assets/banner.html"
        },
        "slot": "client.layout.banner"
      }
    ]
  }
}

The example addon's real manifest is on Addon UI.

#Slot names

Page slots are <area>.<route-key>.<position>, with area = admin or client. Use * as route key for every page (admin.*.toolbar). Positions: before, after, toolbar, row-actions, tabs, detail-panel. Layout slots are <area>.layout.<position> with header, sidebar, footer, banner.

PositionWhere it rendersContext
beforeAbove the page content, below the layout bannerctx.route, ctx.id on detail pages
toolbarIn the page header, next to the page's own buttonssame
tabsExtra tabs after the page; body.label is the tab titlesame
detail-panelCards below the content, only on pages with an idsame
afterBelow the page contentsame
row-actionsAn extra actions column on the page's tablesctx.row_id, row
replace:<section>Replaces a section wrapped in <Replaceable section>same
layout.headerTop bar, before the search (desktop)ctx.route
layout.sidebarBottom of the sidebarctx.route
layout.bannerAbove every pagectx.route
layout.footerBelow every pagectx.route

Replaceable sections: none are wrapped yet, so replace: slots currently render nothing.

#Named slots

Fixed slots placed on specific pages. render slots take a node tree or frame (ui.slots). widget and nav slots take stat cards and menu links from webhook plugins (ui.widgets, ui.menu).

SlotKindContextRendered in
admin.navnavfrontend/src/layouts/AdminLayout.tsx
client.navnavfrontend/src/layouts/ClientLayout.tsx
admin.customer.detailrenderctx.customer_idfrontend/src/pages/admin/ClientExtras.tsx
admin.dashboardrenderfrontend/src/pages/admin/Dashboard.tsx
admin.invoice.detailrenderctx.invoice_idfrontend/src/pages/admin/Billing.tsx
admin.order.detailrenderctx.order_idfrontend/src/pages/admin/OrderDetail.tsx
admin.service.detailrenderctx.service_idfrontend/src/pages/admin/Servers.tsx
client.dashboardrenderfrontend/src/pages/Dashboard.tsx
client.homerenderfrontend/src/components/HomeWidgets.tsx
admin.dashboardwidgetfrontend/src/pages/admin/Dashboard.tsx
client.dashboardwidgetfrontend/src/pages/Dashboard.tsx

#Admin pages

PageRoute keyComponentSlots
/admindashboardAdminDashboardPageadmin.dashboard.before admin.dashboard.after admin.dashboard.toolbar admin.dashboard.row-actions admin.dashboard.tabs
/admin/p/:plugin/:pagep-<plugin>-<page>AdminPluginPageadmin.p-<plugin>-<page>.before admin.p-<plugin>-<page>.after admin.p-<plugin>-<page>.toolbar admin.p-<plugin>-<page>.row-actions admin.p-<plugin>-<page>.tabs
/admin/usersusersAdminUsersPageadmin.users.before admin.users.after admin.users.toolbar admin.users.row-actions admin.users.tabs
/admin/staffstaffAdminStaffPageadmin.staff.before admin.staff.after admin.staff.toolbar admin.staff.row-actions admin.staff.tabs
/admin/campaignscampaignsAdminCampaignsPageadmin.campaigns.before admin.campaigns.after admin.campaigns.toolbar admin.campaigns.row-actions admin.campaigns.tabs
/admin/billing-toolsbilling-toolsAdminBillingToolsPageadmin.billing-tools.before admin.billing-tools.after admin.billing-tools.toolbar admin.billing-tools.row-actions admin.billing-tools.tabs
/admin/gift-cardsgift-cardsAdminGiftCardsPageadmin.gift-cards.before admin.gift-cards.after admin.gift-cards.toolbar admin.gift-cards.row-actions admin.gift-cards.tabs
/admin/transactionstransactionsAdminTransactionsPageadmin.transactions.before admin.transactions.after admin.transactions.toolbar admin.transactions.row-actions admin.transactions.tabs
/admin/customerscustomersAdminCustomersPageadmin.customers.before admin.customers.after admin.customers.toolbar admin.customers.row-actions admin.customers.tabs
/admin/productsproductsAdminProductsPageadmin.products.before admin.products.after admin.products.toolbar admin.products.row-actions admin.products.tabs
/admin/ordersordersAdminOrdersPageadmin.orders.before admin.orders.after admin.orders.toolbar admin.orders.row-actions admin.orders.tabs
/admin/orders/:idordersAdminOrderPageadmin.orders.before admin.orders.after admin.orders.toolbar admin.orders.row-actions admin.orders.tabs admin.orders.detail-panel
/admin/invoicesinvoicesAdminInvoicesPageadmin.invoices.before admin.invoices.after admin.invoices.toolbar admin.invoices.row-actions admin.invoices.tabs
/admin/invoices/:idinvoicesAdminInvoicePageadmin.invoices.before admin.invoices.after admin.invoices.toolbar admin.invoices.row-actions admin.invoices.tabs admin.invoices.detail-panel
/admin/servicesservicesAdminServicesPageadmin.services.before admin.services.after admin.services.toolbar admin.services.row-actions admin.services.tabs
/admin/domainsdomainsAdminDomainsPageadmin.domains.before admin.domains.after admin.domains.toolbar admin.domains.row-actions admin.domains.tabs
/admin/domains/:iddomainsAdminDomainPageadmin.domains.before admin.domains.after admin.domains.toolbar admin.domains.row-actions admin.domains.tabs admin.domains.detail-panel
/admin/ticketsticketsAdminTicketsPageadmin.tickets.before admin.tickets.after admin.tickets.toolbar admin.tickets.row-actions admin.tickets.tabs
/admin/tickets/:idticketsAdminTicketPageadmin.tickets.before admin.tickets.after admin.tickets.toolbar admin.tickets.row-actions admin.tickets.tabs admin.tickets.detail-panel
/admin/support-settingssupport-settingsAdminSupportSettingsPageadmin.support-settings.before admin.support-settings.after admin.support-settings.toolbar admin.support-settings.row-actions admin.support-settings.tabs
/admin/couponscouponsAdminCouponsPageadmin.coupons.before admin.coupons.after admin.coupons.toolbar admin.coupons.row-actions admin.coupons.tabs
/admin/order-formsorder-formsAdminOrderFormsPageadmin.order-forms.before admin.order-forms.after admin.order-forms.toolbar admin.order-forms.row-actions admin.order-forms.tabs
/admin/quotesquotesAdminQuotesPageadmin.quotes.before admin.quotes.after admin.quotes.toolbar admin.quotes.row-actions admin.quotes.tabs
/admin/affiliatesaffiliatesAdminAffiliatesPageadmin.affiliates.before admin.affiliates.after admin.affiliates.toolbar admin.affiliates.row-actions admin.affiliates.tabs
/admin/downloadsdownloadsAdminDownloadsPageadmin.downloads.before admin.downloads.after admin.downloads.toolbar admin.downloads.row-actions admin.downloads.tabs
/admin/email-logemail-logAdminEmailLogPageadmin.email-log.before admin.email-log.after admin.email-log.toolbar admin.email-log.row-actions admin.email-log.tabs
/admin/serversserversAdminServersPageadmin.servers.before admin.servers.after admin.servers.toolbar admin.servers.row-actions admin.servers.tabs
/admin/module-queuemodule-queueAdminModuleQueuePageadmin.module-queue.before admin.module-queue.after admin.module-queue.toolbar admin.module-queue.row-actions admin.module-queue.tabs
/admin/module-logmodule-logAdminModuleLogPageadmin.module-log.before admin.module-log.after admin.module-log.toolbar admin.module-log.row-actions admin.module-log.tabs
/admin/cancellationscancellationsAdminCancellationsPageadmin.cancellations.before admin.cancellations.after admin.cancellations.toolbar admin.cancellations.row-actions admin.cancellations.tabs
/admin/jobsjobsAdminJobsPageadmin.jobs.before admin.jobs.after admin.jobs.toolbar admin.jobs.row-actions admin.jobs.tabs
/admin/auditauditAdminAuditPageadmin.audit.before admin.audit.after admin.audit.toolbar admin.audit.row-actions admin.audit.tabs
/admin/themesthemesAdminThemesPageadmin.themes.before admin.themes.after admin.themes.toolbar admin.themes.row-actions admin.themes.tabs
/admin/addonsaddonsAdminAddonsPageadmin.addons.before admin.addons.after admin.addons.toolbar admin.addons.row-actions admin.addons.tabs
/admin/websitewebsiteAdminWebsitePageadmin.website.before admin.website.after admin.website.toolbar admin.website.row-actions admin.website.tabs
/admin/pluginspluginsAdminPluginsPageadmin.plugins.before admin.plugins.after admin.plugins.toolbar admin.plugins.row-actions admin.plugins.tabs
/admin/plugins/:idpluginsAdminPluginDetailPageadmin.plugins.before admin.plugins.after admin.plugins.toolbar admin.plugins.row-actions admin.plugins.tabs admin.plugins.detail-panel
/admin/plugins/:id/deliveriesplugins-deliveriesAdminPluginDeliveriesPageadmin.plugins-deliveries.before admin.plugins-deliveries.after admin.plugins-deliveries.toolbar admin.plugins-deliveries.row-actions admin.plugins-deliveries.tabs admin.plugins-deliveries.detail-panel
/admin/gatewaysgatewaysAdminGatewaysPageadmin.gateways.before admin.gateways.after admin.gateways.toolbar admin.gateways.row-actions admin.gateways.tabs
/admin/taxtaxAdminTaxPageadmin.tax.before admin.tax.after admin.tax.toolbar admin.tax.row-actions admin.tax.tabs
/admin/overdueoverdueAdminOverduePageadmin.overdue.before admin.overdue.after admin.overdue.toolbar admin.overdue.row-actions admin.overdue.tabs
/admin/email-templatesemail-templatesAdminEmailTemplatesPageadmin.email-templates.before admin.email-templates.after admin.email-templates.toolbar admin.email-templates.row-actions admin.email-templates.tabs
/admin/contentcontentAdminContentPageadmin.content.before admin.content.after admin.content.toolbar admin.content.row-actions admin.content.tabs
/admin/client-groupsclient-groupsAdminClientGroupsPageadmin.client-groups.before admin.client-groups.after admin.client-groups.toolbar admin.client-groups.row-actions admin.client-groups.tabs
/admin/fraudfraudAdminFraudPageadmin.fraud.before admin.fraud.after admin.fraud.toolbar admin.fraud.row-actions admin.fraud.tabs
/admin/securitysecurityAdminSecurityPageadmin.security.before admin.security.after admin.security.toolbar admin.security.row-actions admin.security.tabs
/admin/oauth-clientsoauth-clientsAdminOAuthClientsPageadmin.oauth-clients.before admin.oauth-clients.after admin.oauth-clients.toolbar admin.oauth-clients.row-actions admin.oauth-clients.tabs
/admin/samlsamlAdminSamlPageadmin.saml.before admin.saml.after admin.saml.toolbar admin.saml.row-actions admin.saml.tabs
/admin/gdprgdprAdminGdprPageadmin.gdpr.before admin.gdpr.after admin.gdpr.toolbar admin.gdpr.row-actions admin.gdpr.tabs
/admin/reportsreportsAdminReportsPageadmin.reports.before admin.reports.after admin.reports.toolbar admin.reports.row-actions admin.reports.tabs
/admin/mail-settingsmail-settingsAdminMailSettingsPageadmin.mail-settings.before admin.mail-settings.after admin.mail-settings.toolbar admin.mail-settings.row-actions admin.mail-settings.tabs
/admin/sessionssessionsSessionsPageadmin.sessions.before admin.sessions.after admin.sessions.toolbar admin.sessions.row-actions admin.sessions.tabs
/admin/api-keysapi-keysAdminApiKeysPageadmin.api-keys.before admin.api-keys.after admin.api-keys.toolbar admin.api-keys.row-actions admin.api-keys.tabs
/admin/developer-docsdeveloper-docsDeveloperDocsPageadmin.developer-docs.before admin.developer-docs.after admin.developer-docs.toolbar admin.developer-docs.row-actions admin.developer-docs.tabs
/admin/network-statusnetwork-statusAdminNetworkStatusPageadmin.network-status.before admin.network-status.after admin.network-status.toolbar admin.network-status.row-actions admin.network-status.tabs
/admin/system-healthsystem-healthAdminSystemHealthPageadmin.system-health.before admin.system-health.after admin.system-health.toolbar admin.system-health.row-actions admin.system-health.tabs
/admin/translationstranslationsAdminTranslationsPageadmin.translations.before admin.translations.after admin.translations.toolbar admin.translations.row-actions admin.translations.tabs
/admin/customers/:idcustomersAdminClientSummaryPageadmin.customers.before admin.customers.after admin.customers.toolbar admin.customers.row-actions admin.customers.tabs admin.customers.detail-panel
/admin/my-notesmy-notesAdminMyNotesPageadmin.my-notes.before admin.my-notes.after admin.my-notes.toolbar admin.my-notes.row-actions admin.my-notes.tabs
/admin/noticeboardnoticeboardAdminNoticeboardPageadmin.noticeboard.before admin.noticeboard.after admin.noticeboard.toolbar admin.noticeboard.row-actions admin.noticeboard.tabs
/admin/tracked-linkstracked-linksAdminTrackedLinksPageadmin.tracked-links.before admin.tracked-links.after admin.tracked-links.toolbar admin.tracked-links.row-actions admin.tracked-links.tabs
/admin/calendarcalendarAdminCalendarPageadmin.calendar.before admin.calendar.after admin.calendar.toolbar admin.calendar.row-actions admin.calendar.tabs
/admin/general-settingsgeneral-settingsAdminGeneralSettingsPageadmin.general-settings.before admin.general-settings.after admin.general-settings.toolbar admin.general-settings.row-actions admin.general-settings.tabs
/admin/login-historylogin-historyAdminLoginHistoryPageadmin.login-history.before admin.login-history.after admin.login-history.toolbar admin.login-history.row-actions admin.login-history.tabs
/admin/backupsbackupsAdminBackupsPageadmin.backups.before admin.backups.after admin.backups.toolbar admin.backups.row-actions admin.backups.tabs
/admin/notificationsnotificationsAdminNotificationsPageadmin.notifications.before admin.notifications.after admin.notifications.toolbar admin.notifications.row-actions admin.notifications.tabs
/admin/client-fieldsclient-fieldsAdminClientFieldsPageadmin.client-fields.before admin.client-fields.after admin.client-fields.toolbar admin.client-fields.row-actions admin.client-fields.tabs
/admin/todostodosAdminTodosPageadmin.todos.before admin.todos.after admin.todos.toolbar admin.todos.row-actions admin.todos.tabs
/admin/projectsprojectsAdminProjectsPageadmin.projects.before admin.projects.after admin.projects.toolbar admin.projects.row-actions admin.projects.tabs
/admin/marketplacemarketplaceAdminMarketplacePageadmin.marketplace.before admin.marketplace.after admin.marketplace.toolbar admin.marketplace.row-actions admin.marketplace.tabs
/admin/kyckycAdminKycPageadmin.kyc.before admin.kyc.after admin.kyc.toolbar admin.kyc.row-actions admin.kyc.tabs
/admin/getting-startedgetting-startedAdminGettingStartedPageadmin.getting-started.before admin.getting-started.after admin.getting-started.toolbar admin.getting-started.row-actions admin.getting-started.tabs
/admin/projects/:idprojectsAdminProjectDetailPageadmin.projects.before admin.projects.after admin.projects.toolbar admin.projects.row-actions admin.projects.tabs admin.projects.detail-panel
/admin/currenciescurrenciesAdminCurrenciesPageadmin.currencies.before admin.currencies.after admin.currencies.toolbar admin.currencies.row-actions admin.currencies.tabs
/admin/legal-entitieslegal-entitiesAdminLegalEntitiesPageadmin.legal-entities.before admin.legal-entities.after admin.legal-entities.toolbar admin.legal-entities.row-actions admin.legal-entities.tabs
/admin/billable-itemsbillable-itemsAdminBillableItemsPageadmin.billable-items.before admin.billable-items.after admin.billable-items.toolbar admin.billable-items.row-actions admin.billable-items.tabs
/admin/csv-importcsv-importAdminCsvImportPageadmin.csv-import.before admin.csv-import.after admin.csv-import.toolbar admin.csv-import.row-actions admin.csv-import.tabs
/admin/live-chatlive-chatAdminLiveChatPageadmin.live-chat.before admin.live-chat.after admin.live-chat.toolbar admin.live-chat.row-actions admin.live-chat.tabs
/admin/bundlesbundlesAdminBundlesPageadmin.bundles.before admin.bundles.after admin.bundles.toolbar admin.bundles.row-actions admin.bundles.tabs
/admin/usage-metricsusage-metricsAdminUsageMetricsPageadmin.usage-metrics.before admin.usage-metrics.after admin.usage-metrics.toolbar admin.usage-metrics.row-actions admin.usage-metrics.tabs
/admin/settingssettingsHubPageadmin.settings.before admin.settings.after admin.settings.toolbar admin.settings.row-actions admin.settings.tabs
/admin/hub/:idhub-<id>HubPageadmin.hub-<id>.before admin.hub-<id>.after admin.hub-<id>.toolbar admin.hub-<id>.row-actions admin.hub-<id>.tabs

#Client area pages

PageRoute keyComponentSlots
/dashboarddashboardDashboardPageclient.dashboard.before client.dashboard.after client.dashboard.toolbar client.dashboard.row-actions client.dashboard.tabs
/hub/:idhub-<id>HubPageclient.hub-<id>.before client.hub-<id>.after client.hub-<id>.toolbar client.hub-<id>.row-actions client.hub-<id>.tabs
/sessionssessionsSessionsPageclient.sessions.before client.sessions.after client.sessions.toolbar client.sessions.row-actions client.sessions.tabs
/api-keysapi-keysApiKeysPageclient.api-keys.before client.api-keys.after client.api-keys.toolbar client.api-keys.row-actions client.api-keys.tabs
/connected-appsconnected-appsConnectedAppsPageclient.connected-apps.before client.connected-apps.after client.connected-apps.toolbar client.connected-apps.row-actions client.connected-apps.tabs
/servicesservicesClientServicesPageclient.services.before client.services.after client.services.toolbar client.services.row-actions client.services.tabs
/orders/:idordersOrderStatusPageclient.orders.before client.orders.after client.orders.toolbar client.orders.row-actions client.orders.tabs client.orders.detail-panel
/accountaccountAccountPageclient.account.before client.account.after client.account.toolbar client.account.row-actions client.account.tabs
/invoicesinvoicesClientInvoicesPageclient.invoices.before client.invoices.after client.invoices.toolbar client.invoices.row-actions client.invoices.tabs
/billingbillingClientBillingPageclient.billing.before client.billing.after client.billing.toolbar client.billing.row-actions client.billing.tabs
/invoices/:idinvoicesClientInvoicePageclient.invoices.before client.invoices.after client.invoices.toolbar client.invoices.row-actions client.invoices.tabs client.invoices.detail-panel
/invoices/:id/payinvoices-payClientPayInvoicePageclient.invoices-pay.before client.invoices-pay.after client.invoices-pay.toolbar client.invoices-pay.row-actions client.invoices-pay.tabs client.invoices-pay.detail-panel
/domainsdomainsClientDomainsPageclient.domains.before client.domains.after client.domains.toolbar client.domains.row-actions client.domains.tabs
/domains/:iddomainsClientDomainPageclient.domains.before client.domains.after client.domains.toolbar client.domains.row-actions client.domains.tabs client.domains.detail-panel
/ticketsticketsClientTicketsPageclient.tickets.before client.tickets.after client.tickets.toolbar client.tickets.row-actions client.tickets.tabs
/tickets/:idticketsClientTicketPageclient.tickets.before client.tickets.after client.tickets.toolbar client.tickets.row-actions client.tickets.tabs client.tickets.detail-panel
/projectsprojectsClientProjectsPageclient.projects.before client.projects.after client.projects.toolbar client.projects.row-actions client.projects.tabs
/verificationverificationClientVerificationPageclient.verification.before client.verification.after client.verification.toolbar client.verification.row-actions client.verification.tabs
/projects/:idprojectsClientProjectDetailPageclient.projects.before client.projects.after client.projects.toolbar client.projects.row-actions client.projects.tabs client.projects.detail-panel
/quotesquotesClientQuotesPageclient.quotes.before client.quotes.after client.quotes.toolbar client.quotes.row-actions client.quotes.tabs
/quotes/:idquotesClientQuotePageclient.quotes.before client.quotes.after client.quotes.toolbar client.quotes.row-actions client.quotes.tabs client.quotes.detail-panel
/downloadsdownloadsClientDownloadsPageclient.downloads.before client.downloads.after client.downloads.toolbar client.downloads.row-actions client.downloads.tabs
/emailsemailsClientEmailHistoryPageclient.emails.before client.emails.after client.emails.toolbar client.emails.row-actions client.emails.tabs
/affiliateaffiliateClientAffiliatePageclient.affiliate.before client.affiliate.after client.affiliate.toolbar client.affiliate.row-actions client.affiliate.tabs
/network-statusnetwork-statusNetworkStatusPageclient.network-status.before client.network-status.after client.network-status.toolbar client.network-status.row-actions client.network-status.tabs
/my-detailsmy-detailsClientFieldsPageclient.my-details.before client.my-details.after client.my-details.toolbar client.my-details.row-actions client.my-details.tabs
/p/:plugin/:pagep-<plugin>-<page>ClientPluginPageclient.p-<plugin>-<page>.before client.p-<plugin>-<page>.after client.p-<plugin>-<page>.toolbar client.p-<plugin>-<page>.row-actions client.p-<plugin>-<page>.tabs

A key with <param> contains the actual value of that URL segment (/admin/hub/system → hub-system). Ids (numbers, UUIDs, long hex, ABC-123) are always dropped.

#Example: native widget and iframe widget

JSON
{
  "body": {
    "text": "{{t:plugin.integration-guide.hello}}",
    "type": "alert"
  },
  "slot": "client.dashboard"
}
HTML
<!-- assets/banner.html -->
<!doctype html><meta charset="utf-8">
<p id="msg">Loading…</p>
<script>
  const send = (m) => parent.postMessage(m, "*");
  addEventListener("message", (e) => {
    if (e.data?.type === "pelty:response" && e.data.id === 1) document.getElementById("msg").textContent = e.data.body.message;
  });
  send({ type: "pelty:ready" });
  send({ type: "pelty:request", id: 1, method: "GET", path: "/api/v1/addons/my-addon/hello" });
  send({ type: "pelty:resize", height: document.body.scrollHeight });
</script>