Skip to content
Snippets Groups Projects
Unverified Commit a94d58fc authored by Jeff Bruemmer's avatar Jeff Bruemmer Committed by GitHub
Browse files

docs - embedded analytics sdk (#48530)

parent c6ac90b4
No related branches found
No related tags found
No related merge requests found
Showing
with 1169 additions and 42 deletions
docs/embedding/images/04-preview.png

220 KiB | W: | H:

docs/embedding/images/04-preview.png

276 KiB | W: | H:

docs/embedding/images/04-preview.png
docs/embedding/images/04-preview.png
docs/embedding/images/04-preview.png
docs/embedding/images/04-preview.png
  • 2-up
  • Swipe
  • Onion skin
docs/embedding/images/05-code.png

327 KiB | W: | H:

docs/embedding/images/05-code.png

365 KiB | W: | H:

docs/embedding/images/05-code.png
docs/embedding/images/05-code.png
docs/embedding/images/05-code.png
docs/embedding/images/05-code.png
  • 2-up
  • Swipe
  • Onion skin
docs/embedding/images/embedded-components.png

169 KiB

docs/embedding/images/pug-and-play.png

417 KiB

docs/embedding/images/sharing-embed.png

174 KiB

......@@ -8,19 +8,19 @@ redirect_from:
You can embed Metabase tables, charts, and dashboards—even Metabase's query builder—in your website or application.
## Different ways to embed
Here are the different ways you can embed Metabase.
There are three ways to embed Metabase in your app:
## Embedding SDK with React (BETA)
- [Interactive embedding](#interactive-embedding)
- [Static embedding](#static-embedding)
- [Public links and embeds](#public-links-and-embeds)
With the [Embedding SDK](./sdk/introduction.md), you can embed individual Metabase components with React (like standalone charts, dashboards, the query builder, and more). You can manage access and interactivity per component, and you have advanced customization for seamless styling.
**When to use the Embedded analytics SDK**: you want the most control over how you embed Metabase in your React app.
## Interactive embedding
Interactive embedding is the only kind of embedding that [integrates with SSO and data permissions](./interactive-embedding.md) to enable true self-service access to the underlying data.
**When to use interactive embedding**: when you want to [offer multi-tenant, self-service analytics](https://www.metabase.com/blog/why-full-app-embedding). With interactive embedding, people can create their own questions, dashboards, models, and more, all in their own data sandbox.
**When to use interactive embedding**: you want to [offer multi-tenant, self-service analytics](https://www.metabase.com/blog/why-full-app-embedding). With interactive embedding, people can create their own questions, dashboards, models, and more, all in their own data sandbox.
## Static embedding
......@@ -36,16 +36,18 @@ If you'd like to share your data with the good people of the internet, admins ca
## Comparison of embedding types
| Action | [Interactive](./interactive-embedding.md) | [Static](./static-embedding.md) | [Public](../questions/sharing/public-links.md) |
| ------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | ------------------------------- | ---------------------------------------------- |
| Display charts and dashboards | ✅ | ✅ | ✅ |
| Display interactive [filter widgets](https://www.metabase.com/glossary/filter_widget) | ✅ | ✅ | ✅ |
| Restrict data with [locked filters](./static-embedding-parameters.md#restricting-data-in-a-static-embed-with-locked-parameters) | ❌ | ✅ | ❌ |
| Restrict data with [sandboxes](../permissions/data-sandboxes.md) | ✅ | ❌ | ❌ |
| Use the [drill-through menu](https://www.metabase.com/learn/questions/drill-through) | ✅ | ❌ | ❌ |
| Self-serve via [query builder](https://www.metabase.com/glossary/query_builder) | ✅ | ❌ | ❌ |
| View usage of embeds with [usage analytics](../usage-and-performance-tools/usage-analytics.md) | ✅ | ❌ | ❌ |
| [Actions on dashboards](../dashboards/actions.md) | ✅ | ❌ | ❌ |
| Action | [Embedding SDK](./sdk/introduction.md) | [Interactive](./interactive-embedding.md) | [Static](./static-embedding.md) | [Public](../questions/sharing/public-links.md) |
| ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------------- | ------------------------------- | ---------------------------------------------- |
| Display charts and dashboards | ✅ | ✅ | ✅ | ✅ |
| Display interactive [filter widgets](https://www.metabase.com/glossary/filter_widget) | ✅ | ✅ | ✅ | ✅ |
| Restrict data with [locked filters](./static-embedding-parameters.md#restricting-data-in-a-static-embed-with-locked-parameters) | ❌ | ❌ | ✅ | ❌ |
| Restrict data with [sandboxes](../permissions/data-sandboxes.md) | ✅ | ✅ | ❌ | ❌ |
| Use the [drill-through menu](https://www.metabase.com/learn/questions/drill-through) | ✅ | ✅ | ❌ | ❌ |
| Self-serve via [query builder](https://www.metabase.com/glossary/query_builder) | ✅ | ✅ | ❌ | ❌ |
| View usage of embeds with [usage analytics](../usage-and-performance-tools/usage-analytics.md) | ✅ | ✅ | ❌ | ❌ |
| [Actions on dashboards](../dashboards/actions.md) | ✅ | ✅ | ❌ | ❌ |
| Embed individual Metabase components | ✅ | ❌ | ❌ | ❌ |
| Manage access and interactivity per component | ✅ | ❌ | ❌ | ❌ |
## Switching from static to interactive embedding
......
---
title: "Embedded analytics SDK - appearance"
---
# Embedded analytics SDK - appearance
You can style your embedded Metabase components with a theme.
Here's an example that includes the various styling options available:
```js
const theme = {
// Specify a font to use from the set of fonts supported by Metabase.
// You can set the font to "Custom" to use the custom font
// configured in your Metabase instance.
fontFamily: "Lato",
// Override the base font size for every component.
// This does not usually need to be set, as the components
// inherit the font size from the parent container, such as the body.
fontSize: "16px",
// Override the base line height for every component.
lineHeight: 1.5,
// Match your application's color scheme
colors: {
// The primary color of your application
brand: "#9B5966",
// The color of text that is most prominent
"text-primary": "#4C5773",
// The color of text that is less prominent
"text-secondary": "#696E7B",
// The color of text that is least prominent
"text-tertiary": "#949AAB",
// Default background color
background: "#FFFFFF",
// Slightly darker background color used for hover and accented elements
"background-hover": "#F9FBFC",
// Color used for borders
border: "#EEECEC",
// Color used for filters context
filter: "#7172AD",
// Color used for aggregations and breakouts context
summarize: "#88BF4D",
// Color used to indicate successful actions and positive values/trends
positive: "#BADC58",
// Color used to indicate dangerous actions and negative values/trends
negative: "#FF7979",
/** Color used for popover shadows */
shadow: "rgba(0,0,0,0.08)",
// Overrides the chart colors. Supports up to 8 colors
// Limitation: this does not affect charts with custom series color
charts: [
// can either be a hex code
"#9B59B6",
// or a color object. tint and shade represents lighter and darker variations
// only base color is required, while tint and shade are optional
{base: "#E74C3C", tint: "#EE6B56", shade: "#CB4436"},
],
},
components: {
// Dashboard
dashboard: {
// Background color for all dashboards
backgroundColor: "#2F3640",
card: {
// Background color for all dashboard cards
backgroundColor: "#2D2D30",
// Apply a border color instead of shadow for dashboard cards.
// Unset by default.
border: "1px solid #EEECEC",
},
},
// Question
question: {
// Background color for all questions
backgroundColor: "#2D2D30",
},
// Data table
table: {
cell: {
// Text color of cells, defaults to `text-primary`
textColor: "#4C5773",
// Default background color of cells, defaults to `background`
backgroundColor: "#FFFFFF",
// Font size of cell values, defaults to ~12.5px
fontSize: "12.5px",
},
idColumn: {
// Text color of ID column, defaults to `brand`
textColor: "#9B5966",
// Background color of ID column, defaults to a lighter shade of `brand`
backgroundColor: "#F5E9EB",
},
},
// Number chart
number: {
// Value displayed on number charts.
// This also applies to the primary value in trend charts.
value: {
fontSize: "24px",
lineHeight: "21px",
},
},
// Cartesian chart
cartesian: {
// Padding around the cartesian charts.
// Uses CSS's `padding` property format.
padding: "4px 8px",
},
// Pivot table
pivotTable: {
cell: {
// Font size of cell values, defaults to ~12px
fontSize: "12px",
},
// Pivot row toggle to expand or collapse row
rowToggle: {
textColor: "#FFFFFF",
backgroundColor: "#95A5A6",
},
},
collectionBrowser: {
breadcrumbs: {
expandButton: {
textColor: "#8118F4",
backgroundColor: "#767D7C",
hoverTextColor: "#CE8C8C",
hoverBackgroundColor: "#69264B",
},
},
},
// Popover are used in components such as click actions in interactive questions.
popover: {
// z-index of the popover. Useful for embedding components in a modal. defaults to 4.
zIndex: 4,
},
},
};
```
---
title: Embedded analytics SDK - authentication
---
# Embedded analytics SDK - authentication
{% include beta-blockquote.html %}
{% include plans-blockquote.html feature="Embedded analytics SDK" %}
Notes on handling authentication when working with the SDK.
## Getting Metabase authentication status
You can query the Metabase authentication status using the `useMetabaseAuthStatus` hook. This is useful if you want to completely hide Metabase components when the user is not authenticated.
This hook can only be used within components wrapped by `MetabaseProvider`.
```jsx
const auth = useMetabaseAuthStatus();
if (auth.status === "error") {
return <div>Failed to authenticate: {auth.error.message}</div>;
}
if (auth.status === "success") {
return <InteractiveQuestion questionId={110} />;
}
```
## Customizing JWT authentication
You can customize how the SDK fetches the refresh token by specifying the `fetchRefreshToken` function in the `config` prop:
```typescript jsx
/**
* This is the default implementation used in the SDK.
* You can customize this function to fit your needs, such as adding headers or excluding cookies.
* The function must return a JWT token object, or return "null" if the user is not authenticated.
* @returns {Promise<{id: string, exp: number} | null>}
*/
async function fetchRequestToken(url) {
const response = await fetch(url, {
method: "GET",
credentials: "include",
});
return await response.json();
}
// Pass this configuration to MetabaseProvider.
// Wrap the fetchRequestToken function in useCallback if it has dependencies to prevent re-renders.
const config = { fetchRequestToken };
```
## Reloading Metabase components
In case you need to reload a Metabase component, for example, your users modify your application data and that data is used to render a question in Metabase. If you embed this question and want to force Metabase to reload the question to show the latest data, you can do so by using the `key` prop to force a component to reload.
```typescript jsx
// Inside your application component
const [data, setData] = useState({});
// This is used to force reloading Metabase components
const [counter, setCounter] = useState(0);
// This ensures we only change the `data` reference when it's actually changed
const handleDataChange = newData => {
setData(prevData => {
if (isEqual(prevData, newData)) {
return prevData;
}
return newData;
});
};
useEffect(() => {
/**
* When you set `data` as the `useEffect` hook's dependency, it will trigger the effect
* and increment the counter which is used in a Metabase component's `key` prop, forcing it to reload.
*/
if (data) {
setCounter(counter => counter + 1);
}
}, [data]);
return <InteractiveQuestion key={counter} questionId={yourQuestionId} />;
```
---
title: Embedded analytics SDK - collections
---
## Embedded analytics SDK - collections
{% include beta-blockquote.html %}
{% include plans-blockquote.html feature="Embedded analytics SDK" %}
You can embed Metabase's collection browser so that people can explore items in your Metabase from your application.
## `CollectionBrowser` props
| Prop | Type | Description |
| ------------------ | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| collectionId | `number` | The numerical ID of the collection. You can find this ID in the URL when accessing a collection in your Metabase instance. For example, the collection ID in `http://localhost:3000/collection/1-my-collection` would be `1`. If no ID is provided, the collection browser will start at the root `Our analytics` collection, which is ID = 0. |
| onClick | `(item: CollectionItem) => void` | An optional click handler that emits the clicked entity. |
| pageSize | `number` | The number of items to display per page. The default is 25. |
| visibleEntityTypes | `("question" \| "model" \| "dashboard" \| "collection")[]` | The types of entities that should be visible. If not provided, all entities will be shown. |
## Example embedding code with `CollectionBrowser`
```tsx
import React from "react";
import { CollectionBrowser } from "@metabase/embedding-sdk-react"
export default function App() {
const collectionId = 123; // This is the collection ID you want to browse
const handleItemClick = item => {
console.log("Clicked item:", item);
};
// Define the collection item types you want to be visible
const visibleEntityTypes = ["dashboard", "question", "collection"];
return (
<CollectionBrowser
collectionId={collectionId}
onClick={handleItemClick}
pageSize={10}
visibleEntityTypes={visibleEntityTypes}
/>
);
}
```
---
title: "Embedded analytics SDK - dashboards"
---
## Embedded analytics SDK - dashboards
{% include beta-blockquote.html %}
{% include plans-blockquote.html feature="Embedded analytics SDK" %}
You can embed an interactive, editable, or static dashboard.
## Embedding a dashboard
You can embed a dashboard using the one of the dashboard components:
- `InteractiveDashboard`
- `StaticDashboard`
- `EditableDashboard`
## Dashboard component props
| Prop | Type | Description |
| ---------------------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| dashboardId | `number \| string` | The ID of the dashboard. This is either:<br>- the numerical ID when accessing a dashboard link, i.e. `http://localhost:3000/dashboard/1-my-dashboard` where the ID is `1`<br>- the string ID found in the `entity_id` key of the dashboard object when using the API directly or using the SDK Collection Browser to return data |
| initialParameterValues | `Record<string, string \| string[]>` | Query parameters for the dashboard. For a single option, use a `string` value, and use a list of strings for multiple options. |
| withTitle | `boolean` | Whether the dashboard should display a title. |
| withCardTitle | `boolean` | Whether the dashboard cards should display a title. |
| withDownloads | `boolean \| null` | Whether to hide the download button. |
| hiddenParameters | `string[] \| null` | A list of [parameters to hide](../../questions/sharing/public-links.md#appearance-parameters). |
| questionHeight\* | `number \| null` | Height of a question component when drilled from the dashboard to a question level. |
| questionPlugins\* | `{ mapQuestionClickActions: Function } \| null` | Additional mapper function to override or add drill-down menu. See the implementing custom actions section for more details. |
| onLoad | `(dashboard: Dashboard \| null) => void` | Event handler that triggers after dashboard loads with all visible cards and their content. |
| onLoadWithoutCards | `(dashboard: Dashboard \| null) => void` | Event handler that triggers after dashboard loads, but without its cards - at this stage dashboard title, tabs and cards grid is rendered, but cards content is not yet loaded. |
_\* Not available for `StaticDashboard`._
## Example embedded dashboard with `InteractiveDashboard` component
```typescript jsx
import React from "react";
import {MetabaseProvider, InteractiveDashboard} from "@metabase/embedding-sdk-react";
const config = {...}
export default function App() {
const dashboardId = 1; // This is the dashboard ID you want to embed
const initialParameterValues = {}; // Define your query parameters here
// choose parameter names that are in your dashboard
const hiddenParameters = ["location", "city"]
return (
<MetabaseProvider config={config}>
<InteractiveDashboard
dashboardId={dashboardId}
initialParameterValues={initialParameterValues}
withTitle={false}
withDownloads={false}
hiddenParameters={hideParameters}
/>
</MetabaseProvider>
);
}
```
## Dashboard plugins
### `dashcardMenu`
This plugin allows you to add, remove, and modify the custom actions on the overflow menu of dashboard cards. The plugin appears as a dropdown menu on the top right corner of the card.
The plugin's default configuration looks like this:
```typescript jsx
const plugins = {
dashboard: {
dashcardMenu: {
withDownloads: true,
withEditLink: true,
customItems: [],
},
},
};
```
`dashcardMenu`: can be used in the InteractiveDashboard like this:
```typescript jsx
<InteractiveDashboard
questionId={1}
plugins={{
dashboard: {
dashcardMenu: null,
},
}}
/>
```
#### Enabling/disabling default actions
To remove the download button from the dashcard menu, set `withDownloads` to `false`. To remove the edit link from the dashcard menu, set `withEditLink` to `false`.
```typescript jsx
const plugins = {
dashboard: {
dashcardMenu: {
withDownloads: false,
withEditLink: false,
customItems: [],
},
},
};
```
#### Adding custom actions to the existing menu:
You can add custom actions to the dashcard menu by adding an object to the `customItems` array. Each element can either be an object or a function that takes in the dashcard's question, and outputs a list of custom items in the form of:
```typescript jsx
{
iconName: string;
label: string;
onClick: () => void;
disabled ? : boolean;
}
```
Here's an example:
```typescript jsx
const plugins: SdkPluginsConfig = {
dashboard: {
dashcardMenu: {
customItems: [
{
iconName: "chevronright",
label: "Custom action",
onClick: () => {
alert(`Custom action clicked`);
},
},
({ question }) => {
return {
iconName: "chevronright",
label: "Custom action",
onClick: () => {
alert(`Custom action clicked ${question.name}`);
},
};
},
],
},
},
};
```
#### Replacing the existing menu with your own component
If you want to replace the existing menu with your own component, you can do so by providing a function that returns a React component. This function also can receive the question as an argument.
```typescript jsx
const plugins: SdkPluginsConfig = {
dashboard: {
dashcardMenu: ({ question }) => (
<button onClick={() => console.log(question.name)}>Click me</button>
),
},
};
```
## Creating dashboards
Creating a dashboard could be done with `useCreateDashboardApi` hook or `CreateDashboardModal` component.
### Hook
```typescript jsx
const { createDashboard } = useCreateDashboardApi();
const handleDashboardCreate = async () => {
const dashboard = await createDashboard(props);
// do something with created empty dashboard, e.g., use the dashboard in EditableDashboard component
};
return <Button onClick={handleDashboardCreate}>Create new dashboard</Button>;
```
Props:
| Prop | Type | Description |
| ------------ | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| name | `string` | (required) Dashboard title |
| description | `string \| null` | Optional dashboard description |
| collectionId | `number \| 'root' \| 'personal' \| null` | Collection where to create a new dashboard. You can use predefined system values like `root` or `personal`. |
### Component
```typescript jsx
const [dashboard, setDashboard] = useState<Dashboard | null>(null);
if (dashboard) {
return <EditableDashboard dashboardId={dashboard.id} />;
}
return <CreateDashboardModal onClose={handleClose} onCreate={setDashboard} />;
```
Supported component props:
| Prop | Type | Description |
| ------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------- |
| collectionId? | `number \| 'root' \| 'personal' \| null` | Initial collection field value. You can use predefined system values like `root` or `personal`. |
| onCreate | `(dashboard: Dashboard) => void` | Handler to react on dashboard creation. |
| onClose | `() => void` | Handler to close modal component |
---
title: Embedded analytics SDK
---
# Embedded analytics SDK
{% include beta-blockquote.html %}
{% include plans-blockquote.html feature="Embedded analytics SDK" %}
With the Embedded analytics SDK, you can embed individual Metabase components with React (like standalone charts, dashboards, the query builder, and more). You can manage access and interactivity per component, and you have advanced customization for seamless styling.
The Embedded analytics SDK is currently in beta, but you should check it out and kick the tires; you can do a lot of cool stuff with it.
## Example apps built with the embedded analytics SDK
To give you and idea of what's possible with the SDK, we've put together example sites at [metaba.se/sdk-demo](https://metaba.se/sdk-demo). Navigate between three different shop websites: The Stitch, Luminara Beauty, and Pug & Play. Check them out and poke around their products and analytics sections, as well as the New Question and New Dashboard options.
![Pug and play example app built with embedding SDK](../images/pug-and-play.png)
# Embedding SDK prerequisites
- React application. The SDK is tested to work with React 18 or higher, though it may work with earlier versions.
- [Metabase Pro or Enterprise subscription or free trial](https://www.metabase.com/pricing/).
- Metabase version 1.50 or higher.
- [Node.js 18.x LTS](https://nodejs.org/en) or higher.
## Embedding SDK on NPM
Check out the [Metabase embedding SDK on NPM: [metaba.se/sdk](https://metaba.se/sdk).
## Installation
You'll need to enable the SDK in your Metabase, and install the SDK as a dependency in your app.
### In Metabase
Enable the Embedded Analytics SDK by going to **Admin settings > Settings > Embedding**. Toggle on the SDK, and hit **Configure**. Enter the origins for your website or app where you want to allow SDK embedding, separated by a space. Localhost is automatically included.
### In your React application
You can install the Embedded Analytics SDK for React via npm:
```bash
npm install @metabase/embedding-sdk-react@51-stable
```
or with yarn:
```bash
yarn add @metabase/embedding-sdk-react@51-stable
```
## Developing with the embedded analytics SDK
- [Quickstart](./quickstart.md)
- [Questions](./questions.md)
- [Dashboards](./dashboards.md)
- [Collections](./collections.md)
- [Appearance](./appearance.md)
- [Plugins](./plugins.md)
- [Versioning](./version.md)
- [Authentication](./authentication.md)
## Embedding SDK source code
You can find the [embedding SDK source code in the Metabase repo](https://github.com/metabase/metabase/tree/master/enterprise/frontend/src/embedding-sdk).
## SDK limitations
- Unsupported features:
- Verified content
- Official collections
- Subscriptions
- Alerts
- The Metabase Embedding SDK doesn't support server-side rendering (SSR).
- You can't embed multiple interactive dashboards on the same application page. If you need to embed multiple dashboards on the same application page, you can embed static dashboards.
## Feedback
- Email the team at [sdk-feedback@metabase.com](mailto:sdk-feedback@metabase.com).
- Message the team on Slack. If you don't have a Slack channel set up, please reach out to us at [sdk-feedback@metabase.com](mailto:sdk-feedback@metabase.com).
---
title: Embedded analytics SDK - plugins
---
# Embedded analytics SDK - plugins
{% include beta-blockquote.html %}
{% include plans-blockquote.html feature="Embedded analytics SDK" %}
The Metabase Embedding SDK supports plugins to customize the behavior of components. These plugins can be used in a global context or on a per-component basis.
## Global plugins
To use a plugin globally, add the plugin to the `MetabaseProvider`'s `pluginsConfig` prop:
```typescript jsx
<MetabaseProvider
config={config}
theme={theme}
pluginsConfig={{
mapQuestionClickActions: [...] // Add your custom actions here
}}
>
{children}
</MetabaseProvider>
```
## Component plugins
To use a plugin on a per-component basis, pass the plugin as a prop to the component:
```typescript jsx
<InteractiveQuestion
questionId={1}
plugins={{
mapQuestionClickActions: [...],
}}
/>
```
## Further reading
- [Interactive question plugins](./questions.md#interactive-question-plugins)
- [Dashboard plugins](./dashboards.md#interactive-dashboard-plugins)
---
title: "Embedded analytics SDK - components"
---
# Embedded analytics SDK - questions
{% include beta-blockquote.html %}
{% include plans-blockquote.html feature="Embedded analytics SDK" %}
There are different ways you can embed questions:
- [`StaticQuestion`](#embedding-a-static-question). Embeds a chart. Clicking on the chart doesn't do anything.
- [`InteractiveQuestion`](#embedding-an-interactive-question). Clicking on the chart gives you the drill-through menu.
- [`CreateQuestion`]()
- [`ModifyQuestion`](#embedding-an-editable-question). Embeds the interactive question and the query builder.
## Embedding a static question
You can embed a static question using the `StaticQuestion` component.
The component has a default height, which can be customized by using the `height` prop. To inherit the height from the parent container, you can pass `100%` to the height prop.
```typescript jsx
import React from "react";
import {MetabaseProvider, StaticQuestion} from "@metabase/embedding-sdk-react";
const config = {...}
export default function App() {
const questionId = 1; // This is the question ID you want to embed
return (
<MetabaseProvider config={config}>
<StaticQuestion questionId={questionId} showVisualizationSelector={false}/>
</MetabaseProvider>
);
}
```
You can pass parameter values to questions defined with SQL via `parameterValues` prop, in the format of `{parameter_name: parameter_value}`. Learn more about [SQL parameters](../../questions/native-editor/sql-parameters.md).
```jsx
<StaticQuestion questionId={questionId} parameterValues={{ product_id: 50 }} />
```
## Embedding an interactive question
You can embed an interactive question using the `InteractiveQuestion` component.
```typescript jsx
import React from "react";
import {MetabaseProvider, InteractiveQuestion} from "@metabase/embedding-sdk-react";
const config = {...}
export default function App() {
const questionId = 1; // This is the question ID you want to embed
return (
<MetabaseProvider config={config}>
<InteractiveQuestion questionId={questionId}/>
</MetabaseProvider>
);
}
const questionId = 1; // This is the question ID you want to embed
```
## Question props
| Prop | Type | Description |
| ---------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| questionId | `number \| string` | (required) The ID of the question. This is either:<br>- The numerical ID when accessing a question link, e.g., `http://localhost:3000/question/1-my-question` where the ID is `1`.<br>- The `entity_id` key of the question object. You can find a question's entity ID in the info panel when viewing a question. |
| plugins | `{ mapQuestionClickActions: Function } \| null` | Additional mapper function to override or add drill-down menu. |
| height | `number \| string` | (optional) A number or string specifying a CSS size value that specifies the height of the component |
| entityTypeFilter | `("table" \| "question" \| "model" \| "metric")[]` | (optional) An array that specifies which entity types are available in the data picker |
| isSaveEnabled | `boolean` | (optional) Whether people can save the question. |
| withResetButton | `boolean` | (optional, default: `true`) Determines whether a reset button is displayed. Only relevant when using the default layout |
| withTitle | `boolean` | (optional, default: `false`) Determines whether the question title is displayed. Only relevant when using the default layout. |
| customTitle | `string \| undefined` | (optional) Allows a custom title to be displayed instead of the default question title. Only relevant when using the default layout. |
| onBeforeSave | `() => void` | (optional) A callback function that triggers before saving. Only relevant when `isSaveEnabled = true`. |
| onSave | `() => void` | (optional) A callback function that triggers when a user saves the question. Only relevant when `isSaveEnabled = true`. |
## Customizing interactive questions
By default, the Embedded Analytics SDK provides a default layout for interactive questions that allows you to view your questions, apply filters and aggregations, and access functionality within the query builder.
Here's an example of using the `InteractiveQuestion` component with its default layout:
```typescript jsx
<InteractiveQuestion questionId={95} />
```
To customize the layout, use namespaced components within the `InteractiveQuestion` component. For example:
```typescript jsx
<InteractiveQuestion questionId={95}>
<div
style={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}}
>
<div style={{ display: "grid", placeItems: "center" }}>
<InteractiveQuestion.Title />
<InteractiveQuestion.ResetButton />
</div>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "flex-start",
overflow: "hidden",
}}
>
<div style={{ width: "100%" }}>
<InteractiveQuestion.QuestionVisualization />
</div>
<div style={{ display: "flex", flex: 1, overflow: "scroll" }}>
<InteractiveQuestion.Summarize />
</div>
</div>
<div style={{ display: "flex", flexDirection: "column" }}>
<InteractiveQuestion.Filter />
</div>
</div>
</InteractiveQuestion>
```
## Interactive question components
These components are available via the `InteractiveQuestion` namespace (e.g., `<InteractiveQuestion.Filter />`).
| Component | Info |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `BackButton` | The back button, which provides `back` functionality for the InteractiveDashboard |
| `FilterBar` | The row of badges that contains the current filters that are applied to the question |
| `Filter` | The Filter pane containing all possible filters |
| `FilterButton` | The button used in the default layout to open the Filter pane. You can replace this button with your own implementation. |
| `ResetButton` | The button used to reset the question after the question has been modified with filters/aggregations/etc |
| `Title` | The question's title |
| `SaveButton` | Button for saving the question. |
| `Summarize` | The Summarize pane containing all possible aggregations |
| `SummarizeButton` | The button used in the default layout to open the Summarize pane. You can replace this button with your own implementation. |
| `Notebook` | The Notebook editor that allows for more filter, aggregation, and custom steps |
| `NotebookButton` | The button used in the default layout to open the Notebook editor. You can replace this button with your own implementation. |
| `QuestionVisualization` | The chart visualization for the question |
## Interactive question plugins
### `mapQuestionClickActions`
This plugin allows you to add custom actions to
the click-through menu of an interactive question. You can add and
customize the appearance and behavior of the custom actions.
```typescript jsx
// You can provide a custom action with your own `onClick` logic.
const createCustomAction = clicked => ({
buttonType: "horizontal",
name: "client-custom-action",
section: "custom",
type: "custom",
icon: "chevronright",
title: "Hello from the click app!!!",
onClick: ({ closePopover }) => {
alert(`Clicked ${clicked.column?.name}: ${clicked.value}`);
closePopover();
},
});
// Or customize the appearance of the custom action to suit your need.
const createCustomActionWithView = clicked => ({
name: "client-custom-action-2",
section: "custom",
type: "custom",
view: ({ closePopover }) => (
<button
className="tw-text-base tw-text-yellow-900 tw-bg-slate-400 tw-rounded-lg"
onClick={() => {
alert(`Clicked ${clicked.column?.name}: ${clicked.value}`);
closePopover();
}}
>
Custom element
</button>
),
});
const plugins = {
/**
* You will have access to default `clickActions` that Metabase renders by default.
* So you could decide if you want to add custom actions, remove certain actions, etc.
*/
mapQuestionClickActions: (clickActions, clicked) => {
return [
...clickActions,
createCustomAction(clicked),
createCustomActionWithView(clicked),
];
},
};
const questionId = 1; // This is the question ID you want to embed
return (
<MetabaseProvider config={config} pluginsConfig={plugins}>
<InteractiveQuestion questionId={questionId} />
</MetabaseProvider>
);
```
## Creating a question
With the `CreateQuestion` component, you can create a new question from scratch with Metabase's query builder.
```tsx
import React from "react";
import {MetabaseProvider, CreateQuestion} from "@metabase/embedding-sdk-react";
const config = {...}
export default function App() {
return (
<MetabaseProvider config={config}>
<CreateQuestion/>
</MetabaseProvider>
);
}
```
## Embedding an editable question
With the `ModifyQuestion` component, you can edit an existing question using the query builder by passing the question's ID.
```tsx
import React from "react";
import {MetabaseProvider, ModifyQuestion} from "@metabase/embedding-sdk-react";
const config = {...}
export default function App() {
return (
<MetabaseProvider config={config}>
<ModifyQuestion questionId={1}/>
</MetabaseProvider>
);
}
```
---
title: Embedded analytics SDK quickstart guide
---
# Embedded analytics SDK quickstart guide
{% include beta-blockquote.html %}
{% include plans-blockquote.html feature="Embedded analytics SDK" %}
This guide sets up the embedded analytics SDK with the [sample React app](https://github.com/metabase/metabase-nodejs-react-sdk-embedding-sample), but you can follow along with your own application.
## Prerequisites
- [Node.js 18.x LTS or higher](https://nodejs.org/en) (for the sample application).
## Overview of the quickstart
We're going to do some setup in Metabase, and in the sample application.
### Set up Metabase for embedding
1. [Set up Metabase Enterprise Edition](#set-up-metabase-for-embedding) (if you haven't already)
2. [Enable embedding](#enable-embedding-in-metabase)
3. [Enable SSO with JWT](#enable-sso-with-jwt)
### Start up the sample application
4. [Get the sample application](#set-up-the-sample-application).
5. [Set up the application environment](#set-up-the-application-environment).
6. [Run the app server](#set-up-the-application-server) to handle authentication with JWT and server the embedded Metabase components.
7. [Run the client application](#set-up-the-client-application) that will contain Metabase components built with the SDK.
And then fiddle around with styling.
Let's go.
## Set up Metabase for embedding
- [Run Metabase Pro on a Cloud plan (with a free trial)](https://www.metabase.com/pricing)
- Run Metabase Enterprise Edition locally. This sample app is compatible with [Metabase version v1.50 or higher](https://www.metabase.com/docs/latest/releases). When running locally, you'll need to [activate your license](https://www.metabase.com/docs/latest/paid-features/activating-the-enterprise-edition) to enable SSO with JWT.
You can also use your existing Metabase, if you prefer.
### Enable embedding in Metabase
From any Metabase page, click on the **gear** icon in the upper right and select **Admin Settings** > **Settings** > **Embedding**.
Turn on:
- Embedded analytics SDK
- Static embedding
Otherwise, this whole thing is hopeless.
### Enable SSO with JWT
From any Metabase page, click on the **gear** icon in the upper right and select **Admin Settings** > **Settings** > **Authentication**.
On the card that says **JWT**, click the **Setup** button.
#### JWT Identity provider URI
In **JWT IDENTITY PROVIDER URI** field, paste
```
localhost:9090/sso/metabase
```
Or substitute your Cloud URL for /localhost.
#### String used by the JWT signing key
Click the **Generate key** button.
Copy the key and paste it in your `.env` file into the env var `METABASE_JWT_SHARED_SECRET`.
The application server will use this key to sign tokens so Metabase knows the application's requests for content are authorized.
### Save and enable JWT
Be sure to hit the **Save and enable** button, or all is void.
## Set up the sample application
Clone the [Metabase Node JS React SDK embedding sample app](https://github.com/metabase/metabase-nodejs-react-sdk-embedding-sample).
```sh
git clone git@github.com:metabase/metabase-nodejs-react-sdk-embedding-sample.git
```
## Set up the application environment
In the sample app's main directory, copy the `.env.example` template to `.env`.
```sh
cp .env.example .env
```
In `.env`, make sure `REACT_APP_METABASE_INSTANCE_URL` and `METABASE_INSTANCE_URL` point to your Metabase instance URL, e.g., `http://localhost:3000`.
You're `.env` will look something like:
```
# FRONTEND
PORT=3100
REACT_APP_METABASE_INSTANCE_URL="http://localhost:3000"
REACT_APP_JWT_PROVIDER_URI="http://localhost:9090/sso/metabase"
# BACKEND
BACKEND_PORT=9090
METABASE_INSTANCE_URL="http://localhost:3000"
METABASE_JWT_SHARED_SECRET="TODO"
```
## Set up the application server
Change into the `server` directory:
```sh
cd server
```
Install packages:
```sh
npm install
```
Start the server:
```sh
npm start
```
## Set up the client application
Change into the `client` directory.
Install packages:
```sh
npm install
```
This command will install the [Metabase embedded analytics SDK](https://metaba.se/sdk), in addition to the application's other dependencies.
## Start the client
In a different terminal, change into the `client` directory:
```sh
cd client
```
Install dependencies:
```sh
npm install
```
Start the client app:
```sh
npm start
```
Your browser should automatically open the app. By default, the app runs on [http://localhost:3100](localhost:3100).
## At this point, you should be up and running
In your app, you'll see an embedded `InteractiveQuestion` component.
```javascript
<MetabaseProvider config={config} theme={theme}>
<InteractiveQuestion questionId={questionId} />
</MetabaseProvider>
```
![Embedded Metabase components](../images/embedded-components.png)
Try changing some of the `theme` options in the [client app](https://github.com/metabase/metabase-nodejs-react-sdk-embedding-sample/blob/main/client/src/App.js) to style the components.
---
title: Embedded analytics SDK - versions
---
# Embedded analytics SDK - versions
{% include beta-blockquote.html %}
{% include plans-blockquote.html feature="Embedded analytics SDK" %}
The SDK version tracks with the Metabase version.
So, for example, if you're on Metabase version `1.51.1`, you should use the SDK `1.51`.
## Version pinning when using the SDK with Metabase Cloud
To pin your version of Metabase, go to **Admin settings > Settings > Embedding**. Go to the Embedded analytics SDK card and scroll to **Version pinning** and click **Request version pinning**.
## Version pinning requirements
To pin a version of Metabase, you must:
- Be on Metabase Cloud (obviously)
- Be on the Pro or Enterprise plans
## Why you'd want to pin your Metabase Cloud version
Normally, Metabase Cloud upgrades your Metabase as new versions roll out so that you don't have to deal with upgrades.
But if you're using the SDK with Metabase Cloud, you'll want to upgrade manually to make sure your embeds don't break when you upgrade both your Metabase and your SDK version.
To upgrade manually, you can pin your Metabase version so that it stays in sync with the SDK version you're using. You can choose when to upgrade your Metabase.
......@@ -12,10 +12,18 @@ What is embedding, and how does it work?
The solution to self-service customer analytics: embed the full Metabase app in your app. Interactive embedding integrates with your data permissions to let people slice and dice data on their own using Metabase's query builder.
## [Interactive embedding quick start](./interactive-embedding-quick-start-guide.md)
## [Interactive embedding quickstart](./interactive-embedding-quick-start-guide.md)
You'll embed the full Metabase application in your app. Once logged in, people can view a Metabase dashboard in your web app, and be able to use the full Metabase application to explore their data, and only their data.
## [Embedding SDK](./sdk/introduction.md)
With the Embedding SDK, you can embed individual Metabase components with React (like standalone charts, dashboards, the query builder, and more). You can manage access and interactivity per component, and you have advanced customization for seamless styling.
## [Embedding SDK quickstart](./sdk/quickstart.md)
Jump to a SDK quickstart with a sample React application.
## [Static embedding](./static-embedding.md)
Also known as Signed Embedding, Static embedding is a secure way to embed charts and dashboards. Static embeds are view only; people won't be able to drill-through charts and tables.
......
......@@ -168,6 +168,8 @@ Because Metabase doesn't display locked parameters as filter widgets, you can us
## Customizing the appearance of a static embed
![Look and feel: appearance settings on static embed](./images/04-preview.png)
You can change the appearance of an embedded item by adding hash parameters to the end of the URL in your iframe's `src` attribute.
For example, the following embedding URL will display an embedded item in dark mode, without a border, and with its original title:
......@@ -176,30 +178,28 @@ For example, the following embedding URL will display an embedded item in dark m
your_embedding_url#theme=night&bordered=false&titled=true
```
You can preview appearance settings from your question or dashboard's [embedded appearance settings](./static-embedding.md#customizing-the-appearance-of-static-embeds).
You can preview appearance settings from your question or dashboard's embedded appearance settings.
| Parameter name | Possible values |
| ----------------------------------------- | --------------------------------------------- |
| `bordered` | true, false |
| `titled` | true, false |
| `theme` | null, transparent, night |
| `refresh` (dashboard only) | integer (seconds, e.g., `refresh=60`) |
| `font`\* | [font name](../configuring-metabase/fonts.md) |
| `hide_download_button`\* (questions only) | true, false |
| Parameter name | Possible values |
| -------------------------- | --------------------------------------------- |
| `bordered` | true, false |
| `titled` | true, false |
| `theme` | null (default), night |
| `refresh` (dashboard only) | integer (seconds, e.g., `refresh=60`) |
| `font`\* | [font name](../configuring-metabase/fonts.md) |
| `downloads`\* | true, false |
\* Available on [Pro](https://www.metabase.com/product/pro) and [Enterprise](https://www.metabase.com/product/enterprise) plans.
For global appearance settings, such as the colors and fonts used across your entire Metabase instance, see [Customizing Metabase's appearance](../configuring-metabase/appearance.md).
## Allow people to download the results of an embedded question
## Allow people to download the results of an embedded question or dashboard
{% include plans-blockquote.html feature="Downloading results" %}
By default, Metabase will include a **Download** button on embedded questions. You can remove the download button by setting `hide_download_button=true` in the embedding URL in the iframe's `src` attribute, see [customizing the appearance of static embeds](./static-embedding.md#customizing-the-appearance-of-static-embeds).
If the download button is missing when you expected it to be available, check that the URL in the `src` attribute for your iframe has the parameter `hide_download_button=false`.
By default, Metabase will include a **Download** button on embedded questions, and an **Export to PDF** option on embedded dashboards. You can remove the download option by setting `downloads=false` in the embedding URL in the iframe's `src` attribute, see [customizing the appearance of static embeds](./static-embedding.md#customizing-the-appearance-of-static-embeds).
> Downloading results is available only for questions, not dashboards.
If the download option is missing when you expected it to be available, check that the URL in the `src` attribute for your iframe has the parameter `downloads=true`.
## Maximum request size
......
......@@ -41,15 +41,17 @@ If you want to embed charts with additional interactive features, like [drill-do
## Making a question or dashboard embeddable
![Sharing button to embed dashboard](./images/sharing-embed.png)
To create a static embed:
1. Go to the question or dashboard that you want to embed in your website.
2. Click on the **sharing icon**. On dashboards, the icon is in the top right. On questions, it's in the bottom right.
2. Click on the **sharing icon**.
3. Select **Embed**.
4. On the **Static embed** card, click the button: **Set this up**.
5. Optional: [Preview the appearance of the embed](#customizing-the-appearance-of-static-embeds).
6. Optional: [Add parameters to the embed](./static-embedding-parameters.md).
7. Click **Publish**.
5. Select **Static embedding**.
6. Optional: [customize the appearance of the embed](./static-embedding-parameters.md#customizing-the-appearance-of-a-static-embed)
7. Optional: [Add parameters to the embed](./static-embedding-parameters.md).
8. Click **Publish**.
![Preview](./images/04-preview.png)
......@@ -77,7 +79,7 @@ For more examples, see our [reference apps repo](https://github.com/metabase/emb
2. Click **Code**.
3. In the top code block, you'll find the sample code for your web server. You'll also find the iframe snippet to plug into your HTML template or single page app.
When you make changes to the style, appearance, or parameter preview settings, Metabase will update the code and highlight the changes. Make sure to copy these changes to your actual server code.
When you make changes to the look and feel or parameter preview settings, Metabase will update the code and highlight the changes. Make sure to copy these changes to your actual server code.
![Code samples for embedding](./images/05-code.png)
......@@ -99,17 +101,19 @@ For iframe snippets:
If you change the [parameters](./static-embedding-parameters.md) of your embedded item:
1. After making your changes, copy the code Metabase generates.
1. Click **Publish** again.
2. [Update the code](#adding-the-embedding-url-to-your-website) on your server so that it matches the code generated by Metabase (**Code** > top block).
3. [Update the code](#adding-the-embedding-url-to-your-website) on your server so that it matches the code generated by Metabase.
## Disabling embedding for a question or dashboard
You can find a list of all embedded questions and dashboards from **Admin settings** > **Embedding**.
You can find a list of all static embeds of questions and dashboards from **Admin settings** > **Embedding** > **Static embedding** > **Manage**.
1. Go to the embeddable question or dashboard.
1. Visit the embeddable question or dashboard.
2. Click on the **sharing icon** (square with an arrow pointing to the top right).
3. Select **Embed this item in an application**.
4. Click **Unpublish**.
3. Select **Embed**.
4. Select **Static embedding**
5. Click **Unpublish**.
## Customizing the appearance of static embeds
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment