Skip to main content
This is the reference for the values a contribution names: a widget names a page and a slot on it, a tab names a page, a series names a chart, a row action names a table, and a banner names a page. A key outside these lists fails the manifest schema, and so does a widget whose slot is not on the page it names.
Leave the flags off and the command offers the slots that belong to the page you picked, so a mismatch is not possible interactively. The live values are also served at https://api.tappify.ai/api/v1/extensions/registry.

Pages

The Tabs and Banners columns are host anchors, not schema rules: a tab on ai_chat or a banner on deployments validates, passes doctor, publishes and renders nothing. Check them here before you build against a page. ai_chat is a page key only for assistant contributions. Nothing renders into it as a widget or a tab, and the assistant draws its own cards from what your tools return. Of the three pages the Tabs column marks, the anchor is live on Analytics and Deployments; Home accepts tab contributions and does not draw them yet.

Slots

Every slot is the same grid, so a size that works in one works in all of them. On Analytics, kpi-row and below-chart are on the Overview tab, and sidebar is under the page whichever tab is open. A slot lays its widgets out on a grid of columns at least 240 pixels wide and rows at least 132 pixels tall, with a 12-pixel gap. A widget’s size is how many cells it takes: The column count comes from the width of the page, so a 2x1 widget is one column wide on a narrow window. Every widget has to be readable at 320 pixels whatever size it declares. Size against your own mount with container queries — see Style with host tokens. The host draws the card around your mount: the vendor tile, your title, and an Expand button when you set expandable. You render the body.

Charts

A series contribution names one of three charts, and each chart lives on one page:
The host draws a series on the chart it names, with the vendor in the legend, and a marker’s glyph on that chart’s time axis. Where the page has no host chart under that key, the vendor lines and markers are drawn in a card of their own on the same page. See Add a connector.

Tables

A row action names one of these. Your component mounts in the expand panel with that row as tap.context, opened from the row’s own menu with your vendor tile beside the title.

The filters a page publishes

tap.filters carries range, platform and country, and every mount of your install reads the same values. The range control on the Analytics Overview tab is the only one wired to them today: it publishes 7d, 30d, 90d or 1y, and range.preset carries that value for every preset but 1y. Elsewhere range holds the last value Analytics set, and platform and country hold their defaults. Read them through useTapFilters and pass range straight into a query — see Follow the page’s filters.

Banners and pages of your own

Banner anchors sit at the top of overview and analytics. A banner’s content comes from a webhook you declare with as: "banner", which is delivered with the connector work, so a banner contribution renders nothing yet. A page of your own gets its own route at /projects/:id/ext/:extensionId/:pageId. tap.params.pageId is the page you declared, tap.params.path is everything after it, and each segment of that path is also its own numbered entry — "funnels/123" arrives as { pageId: "explore", path: "funnels/123", "0": "funnels", "1": "123" }. With nav: true the page also gets an entry in the project navigation carrying your vendor tile.

Categories

category places you in the Tap Store’s filter. One of eighteen: market_data, subscriptions, product_analytics, crashes, attribution, experiments, messaging, session_replay, localization, design, ci_cd, trackers, support, chat, ad_monetization, warehouse, compliance, additional_stores.

Scopes

Rendering anything on these pages needs ui:render.