Self-service analytics for your team
Fast, flexible customer-facing analytics
Watch 5-minute demo
The React toolkit for in-app reporting that looks, acts, and smells like it’s part of your app. Get full control to prototype, style, and ship sophisticated analytics without complicated development.
npx @metabase/embedding-sdk-react@latest start
Explore the live demo
Go to quickstart
Make sure customers only see what they need to. Your data never leaves your server.
Install the SDK and embed your first chart fast. Build out advanced analytics as needs grow.
Developer-first tools and expert support to keep the integration process on your schedule.
Embed standalone components—from individual charts to the query builder—that blend into your product. Pixel-perfect placement with no fixed width or height for responsive designs. Override menus, rearrange fields, move buttons, and lay out components to fit your UI.
import {
MetabaseProvider,
InteractiveQuestion,
defineEmbeddingSdkConfig
} from "@metabase/embedding-sdk-react";
const config = defineEmbeddingSdkConfig({
metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL
authProviderUri: "https://app.example.com/sso/metabase", // Required: An endpoint in your app that signs the user in and returns a session
});
<MetabaseProvider config={config}>
<InteractiveQuestion
questionId={questionId}
isSaveEnabled={false}
withResetButton={true}
customTitle="Orders over time"
/>
</MetabaseProvider>
Style each component to match your app’s look and feel. Customize fonts, background colors, tooltips, shading, and more. Apply different styles per organization, team, or even per user.
const metabase: MetabaseTheme = {
fontFamily: "Inter",
fontSize: "14px",
colors: {
brand: colors.primary,
"brand-hover": colors.darkGrey,
"brand-hover-light": colors.darkGrey,
filter: colors.filter,
"text-primary": colors.lighterGrey,
"text-secondary": colors.lighterGrey,
"text-tertiary": colors.lighterGrey,
border: colors.darkGrey,
background: colors.background,
"background-secondary": colors.darkGrey,
"background-hover": colors.background,
"background-disabled": colors.darkGrey,
charts: [
colors.primary,
colors.filter,
"#ED6A5A",
"#FED18C",
"#82A74B",
"#FF8D69",
"#ED6A5A",
"#FED18C",
],
positive: "#45DF4C",
negative: "#FF3389",
},
components: {
cartesian: {
padding: "6px 16px",
},
dashboard: {
card: {
border: `"1px solid ${colors.darkGrey}"`,
backgroundColor: "#212426",
},
},
number: {
value: {
fontSize: "18px",
lineHeight: "22px",
},
},
popover: {
zIndex: 201,
},
},
};
const metabase: MetabaseTheme = {
fontFamily: "Arsenal",
fontSize: "14px",
colors: {
brand: colors.primary,
"brand-hover": "#fff",
"brand-hover-light": "#fff",
filter: colors.viz1,
summarize: "#BE54C0",
"text-primary": colors.green3,
"text-secondary": colors.green3,
"text-tertiary": colors.green3,
border: colors.green1,
background: colors.background,
"background-secondary": colors.background,
"background-hover": colors.background,
"background-disabled": colors.green2,
charts: [
colors.viz1,
"#E09862",
"#BE54C0",
"#DDA51F",
"#B34332",
"#4998E3",
"#BE54C0",
"#DDA51F",
],
positive: colors.green3,
negative: "#B34332",
shadow: "rgba(0, 0, 0, 0.1)",
},
components: {
cartesian: {
padding: "6px 16px",
},
dashboard: {
backgroundColor: "transparent",
},
number: {
value: {
fontSize: "36px",
lineHeight: "36px",
},
},
popover: {
zIndex: 201,
},
},
};
const metabase: MetabaseTheme = {
fontFamily: "DM Mono",
fontSize: "14px",
colors: {
brand: colors.primary,
filter: colors.secondary,
"text-primary": colors.darkGrey,
"text-secondary": colors.lightGrey,
"text-tertiary": colors.lightGrey,
border: "#3B3F3F",
background: colors.background,
"background-hover": "#FCFAF1",
"background-disabled": colors.lighterGrey,
charts: [
colors.primary,
colors.negative,
"#ECB405",
"#BD37C9",
colors.positive,
"#545455",
colors.primary,
colors.negative,
],
positive: colors.positive,
negative: colors.negative,
},
components: {
cartesian: {
padding: "6px 16px",
},
dashboard: {
card: {
border: "1px solid var(--mantine-color-gray-3)",
},
},
number: {
value: {
fontSize: "24px",
lineHeight: "30px",
},
},
popover: {
zIndex: 201,
},
},
};
Define permissions and interactive tools for data discovery at scale. Give some people read-only access. Some drill-through on charts without saving. Others get an all access pass to create, modify, and save questions, create dashboards and more.
switch(currentUser.role) {
case curator: {
return (
<MetabaseProvider config={config} theme={theme}>
<InteractiveQuestion questionId={questionId} />
</MetabaseProvider>
);
break;
}
default: {
<MetabaseProvider config={config} theme={theme}>
<StaticQuestion questionId={questionId} />
</MetabaseProvider>
}
}
return <GuestGreeting />;
switch (currentUser.role) {
case (curator): {
return (
<MetabaseProvider config={config} theme={theme}>
<InteractiveQuestion questionId={questionId} />
</MetabaseProvider>
);
}
default: {
return (
<MetabaseProvider config={config} theme={theme}>
<StaticQuestion questionId={questionId} />
</MetabaseProvider>
)
}
}
return <GuestGreeting />;
Real life outcomes from real customers shipping custom analytics fast with the SDK.
Marketfuel needed tightly integrated analytics that maintained the brand experience in their eCommerce platform. Using the Embedded Analytics SDK, they got to proof of concept in under a month with a solo dev.
“Using Metabase has been a game-changer for us. It allows us to focus on what we do best without reinventing analytics, saving us time and resources.”
Brian Urso
Co-founder and CTO at Marketfuel
See how Marketfuel builds reporting into their product with the SDKOwlery, needed a solution that would let both their team and customers create and manage dashboards without constant engineering involvement. The SDK gave them the flexibility to integrate analytics seamlessly into their product.
“We’re extremely happy with our decision to use the SDK. It’s given us control to build the future of our product, with the best analytics experience for our customers.”
Travis Downs
Co-founder at Owlery
See how Owlery is getting to market quicker with the SDKCustomize the behaviors and flows per component, like adding custom actions to menu, or overhauling the layout of the query builder. There are no rules.
<MetabaseProvider
config={config}
theme={theme}
pluginsConfig={{
mapQuestionClickActions: (clickActions, clicked) => {
const nextClickActions = [...clickActions]
// If we are drilling down on the user id, add a custom action to view the user profile.
if (clicked.column?.name === "user_id") {
nextClickActions.push({
buttonType: "horizontal",
name: "view-profile",
section: "info",
type: "custom",
icon: "person",
title: "View user profile",
onClick: ({ closePopover }) => {
console.log(`View Profile > user_id = ${clicked.value}`)
closePopover()
},
})
}
return nextClickActions
},
}}
/>
If you’re ready for sophisticated, bespoke customer-facing analytics that’ll keep up as you grow, try the SDK.
npx @metabase/embedding-sdk-react@latest start
Go to quickstart