Skip to main content
Version: Next

Download Menu Extension Points

Extensions can add items to the download menus for charts and dashboards. An item runs a command and passes it a context object that describes the chart or dashboard, including a function that returns the query behind the export.

Locations​

Register a menu item at one of these locations with menus.registerMenuItem, using the primary group.

LocationSurfaceWhere the item appears
explore.chart.downloadExplore, chart actions menuAfter "Export to Excel"
explore.chart.download.pivotedExplore, chart actions menuAfter "Export to Pivoted Excel"
explore.standalone.downloadExplore, standalone download controlAfter "Export to Excel"
dashboard.chart.downloadDashboard, chart menuAfter "Export to Excel"
dashboard.chart.download.pivotedDashboard, chart menuAfter "Export to Pivoted Excel"
chart.drillDetail.downloadDrill to detail paneAfter "Export to Excel"
chart.drillBy.downloadDrill by modalAfter "Export to Excel"
dashboard.downloadDashboard download menuAfter the Excel export entries

The pivoted locations appear only where the chart offers "Export to Pivoted Excel". For those locations, getPayload() returns the query for the post-processed (pivoted) result.

Context​

The seven chart locations pass a ChartDownloadContext to the command:

interface ChartDownloadContext {
getPayload: () => Promise<ChartDataRequest>;
chartName: string;
canDownload: boolean;
}

interface ChartDataRequest {
datasource: { id: number; type: string };
queries: object[];
result_type: string;
result_format: string;
force?: boolean;
form_data?: object;
}
  • getPayload() is evaluated when called, so call it from the command. It resolves to the /api/v1/chart/data request body that the CSV export sends, with result_format: 'json'. Chart query builders run in CSV export mode before the response format is changed to JSON, preserving export row limits, filters and column order. Paginated tables export from the first row up to the configured row limit, rather than only the visible page.
  • chartName is the chart's title as shown, including a name set on the dashboard.
  • canDownload is false when the current user lacks the permission to export the chart's data.

The dashboard.download location passes a DashboardDownloadContext:

interface DashboardDownloadContext {
dashboardId: number;
dashboardTitle: string;
activeDataMask: Record<
string,
{
extraFormData: object;
filterState: { value?: unknown; label?: string };
}
>;
canDownload: boolean;
}

activeDataMask lists the applied native filters only, keyed by filter ID. Each entry carries extraFormData and filterState with value and label. Cross-filters and ownState are not included.

Rules​

  • Chart items are disabled when canDownload is false.
  • The dashboard item appears only where "Export Data to Excel" does, so it is hidden from users who cannot export.
  • Image-only charts get no items in the Explore and dashboard chart menus. The standalone control keeps them, because it offers CSV and Excel for every chart.
  • The context is read when the item is clicked, so getPayload() and canDownload reflect the state at that moment.
  • Register the command before its menu item. An item whose command is not registered yet is skipped, and it appears only after the menu next re-renders.
  • A command that throws or rejects is logged and does not break the menu.

Example​

import { commands, menus } from '@apache-superset/core';

commands.registerCommand(
{ id: 'my-extension.export-rows', title: 'Export rows to My Service' },
async ctx => {
const payload = await ctx.getPayload();
// Send the payload to the service, for example with `fetch`.
},
);

menus.registerMenuItem(
{ view: 'explore.chart.download', command: 'my-extension.export-rows' },
'explore.chart.download',
'primary',
);

To report progress and the result to the user, see Toasts.