Dashboard extension or viz extension?
Tableau has two things called extensions. They have similar names, live in different parts of the product, use different manifests and different APIs, and are not convertible into one another. Choosing wrong doesn't cost you an afternoon: it costs you the build.
The two of them
Dashboard extension
- Sits in the dashboard layout like a container or an image
- Can read every worksheet on the dashboard
- Can apply filters and change parameters
- Available since 2018, works nearly everywhere
- Root:
<dashboard-extension>
Viz extension
- Renders as the viz, filling the whole pane
- Sees only the fields you declare as encodings
- Travels with the sheet everywhere it's used
- Needs Tableau 2024.2 or later
- Root:
<worksheet-extension>
The clearest way to hold them apart: a dashboard extension is a widget that reads the dashboard. A viz extension is a chart type that replaces the mark. One looks at your work; the other is the work.
Ninety seconds to a decision
The one that genuinely surprises people is the third. A viz extension is scoped to its own worksheet by design and has no route to the rest of the dashboard. If your feature is fundamentally about relating sheets to each other, no amount of clever code makes a viz extension the right shape.
What differs once you're building
| Dashboard extension | Viz extension | |
|---|---|---|
| Manifest root | <dashboard-extension> |
<worksheet-extension> plus <encoding> blocks |
| API entry point | extensions.dashboardContent |
extensions.worksheetContent |
| How you get data | getSummaryDataAsync() on any worksheet |
getVisualSpecificationAsync() for the encodings, then a data reader |
| Minimum API | 1.4 |
1.11 (Tableau 2024.2+) |
| Where it renders | A fixed-size object you position | The entire worksheet pane, whatever size that is |
| Configuration UI | Right-click → Configure works reliably | Needs a button inside the viz: the Marks-card menu won't fire the dialog |
| Layout burden | Low: you control the box | High: must look right from a tiny tile to a full sheet, without scrollbars |
The bottom two rows are where the real cost difference lives, and neither is obvious from the documentation. A viz extension renders into whatever pane it's given, so a card laid out in fixed pixels looks lost on a full sheet and clipped on a small one. The fix is to size everything fluidly against the smaller pane dimension and shed detail only near the limits, but you have to know that before you write the CSS, not after.
You cannot port one to the other.
Different manifest root, different API surface, different data model, different layout assumptions. Roughly the rendering code survives a switch; everything that touches Tableau does not. This is a decision to make deliberately at the start.
If it's genuinely both
Some things legitimately want to exist twice: a KPI card is the usual example. As a dashboard extension it can read several sheets and compare them. As a viz extension it travels with the worksheet and users configure it by dragging fields, exactly like a native chart.
Build the dashboard version first. It's the more forgiving API, it runs on more Tableau versions, and the rendering code carries over. Then decide whether the viz version earns its second build.
Seventeen of these, already built, both kinds.
The TableauOps Extension Kit ships working scaffolds for both (a dashboard extension and a viz extension, each with correct manifests, the API wiring done, and the layout rules already applied) plus seventeen finished extensions to pull apart: three KPI cards, a sankey, a chord diagram, two data tables, a scatter with brush selection, three radial charts, and more. The Complete Kit adds the whole nine-lesson course for $20 more: $119 instead of $148 bought separately.
It also includes the skill file that makes Claude Code route this decision correctly on its own, so it doesn't cheerfully build you the wrong kind. Next up: what goes in the manifest file both kinds need, in what's actually inside a .trex.
New pieces land as the work throws them up. Leave your email and I'll send the next one, no more than that.