Skip to main content
The Metabase Embedding SDK provides comprehensive theming capabilities to customize the appearance of embedded components.

Basic theming

Use the defineMetabaseTheme helper to create type-safe theme configurations:
import { MetabaseProvider, defineMetabaseTheme } from '@metabase/embedding-sdk-react';

const theme = defineMetabaseTheme({
  colors: {
    brand: '#9333EA',
    'text-primary': '#1F2937',
  },
  fontFamily: 'Inter, sans-serif',
});

function App() {
  return (
    <MetabaseProvider authConfig={authConfig} theme={theme}>
      {/* Your app */}
    </MetabaseProvider>
  );
}

Theme presets

Start with a built-in theme preset:
const theme = defineMetabaseTheme({
  preset: 'light',
  colors: {
    brand: '#9333EA',
  },
});

Typography

Font family

const theme = defineMetabaseTheme({
  fontFamily: 'Inter, system-ui, sans-serif',
});
The SDK supports common web fonts and Google Fonts:
const theme = defineMetabaseTheme({
  fontFamily: 'Roboto', // Google Font
});

Font size

Set the base font size (supports px, em, and rem):
const theme = defineMetabaseTheme({
  fontSize: '16px',
});

Line height

const theme = defineMetabaseTheme({
  lineHeight: 1.6,
});

Color customization

Brand colors

const theme = defineMetabaseTheme({
  colors: {
    brand: '#9333EA',
    'brand-hover': '#7C3AED',
    'brand-hover-light': '#A78BFA',
  },
});

Text colors

const theme = defineMetabaseTheme({
  colors: {
    'text-primary': '#1F2937',
    'text-secondary': '#6B7280',
    'text-tertiary': '#9CA3AF',
    'text-white': '#FFFFFF',
    'text-hover': '#111827',
  },
});

Background colors

const theme = defineMetabaseTheme({
  colors: {
    background: '#FFFFFF',
    'background-secondary': '#F9FAFB',
    'background-hover': '#F3F4F6',
    'background-disabled': '#E5E7EB',
    'background-light': '#F9FAFB',
  },
});

Border and shadow

const theme = defineMetabaseTheme({
  colors: {
    border: '#E5E7EB',
    shadow: 'rgba(0, 0, 0, 0.1)',
  },
});

Status colors

const theme = defineMetabaseTheme({
  colors: {
    positive: '#10B981',
    negative: '#EF4444',
    error: '#DC2626',
    'background-error': '#FEE2E2',
  },
});

Query builder colors

const theme = defineMetabaseTheme({
  colors: {
    filter: '#7C3AED',
    summarize: '#2563EB',
  },
});

Chart colors

Customize the color palette used in visualizations:
const theme = defineMetabaseTheme({
  colors: {
    charts: [
      '#9333EA',
      '#3B82F6',
      '#10B981',
      '#F59E0B',
      '#EF4444',
    ],
  },
});

Advanced chart colors with tints and shades

const theme = defineMetabaseTheme({
  colors: {
    charts: [
      {
        base: '#9333EA',
        tint: '#C4B5FD',
        shade: '#6B21A8',
      },
      {
        base: '#3B82F6',
        tint: '#93C5FD',
        shade: '#1E40AF',
      },
    ],
  },
});

Component theming

Dashboard

const theme = defineMetabaseTheme({
  components: {
    dashboard: {
      backgroundColor: '#F9FAFB',
      gridBorderColor: '#E5E7EB',
      card: {
        backgroundColor: '#FFFFFF',
        border: '1px solid #E5E7EB',
      },
    },
  },
});

Question

const theme = defineMetabaseTheme({
  components: {
    question: {
      backgroundColor: '#FFFFFF',
      toolbar: {
        backgroundColor: '#F9FAFB',
      },
    },
  },
});

Table visualization

const theme = defineMetabaseTheme({
  components: {
    table: {
      stickyBackgroundColor: '#FFFFFF',
      cell: {
        textColor: '#1F2937',
        backgroundColor: '#FFFFFF',
        fontSize: '14px',
      },
      idColumn: {
        textColor: '#9333EA',
        backgroundColor: '#F3E8FF',
      },
    },
  },
});

Pivot table

const theme = defineMetabaseTheme({
  components: {
    pivotTable: {
      cell: {
        fontSize: '13px',
      },
      rowToggle: {
        textColor: '#1F2937',
        backgroundColor: '#F3F4F6',
      },
    },
  },
});

Number visualization

const theme = defineMetabaseTheme({
  components: {
    number: {
      value: {
        fontSize: '3rem',
        lineHeight: '1',
      },
    },
  },
});

Cartesian charts

const theme = defineMetabaseTheme({
  components: {
    cartesian: {
      padding: '16px',
      label: {
        fontSize: '12px',
      },
      goalLine: {
        label: {
          fontSize: '12px',
        },
      },
      splitLine: {
        lineStyle: {
          color: '#E5E7EB',
        },
      },
    },
  },
});

Tooltip

const theme = defineMetabaseTheme({
  components: {
    tooltip: {
      textColor: '#FFFFFF',
      secondaryTextColor: '#D1D5DB',
      backgroundColor: 'rgba(0, 0, 0, 0.9)',
      focusedBackgroundColor: 'rgba(0, 0, 0, 0.95)',
    },
  },
});

Popover z-index

Useful for embedding components in a modal:
const theme = defineMetabaseTheme({
  components: {
    popover: {
      zIndex: 1000,
    },
  },
});

Collection browser

const theme = defineMetabaseTheme({
  components: {
    collectionBrowser: {
      breadcrumbs: {
        expandButton: {
          backgroundColor: '#F3F4F6',
          hoverBackgroundColor: '#E5E7EB',
          textColor: '#1F2937',
          hoverTextColor: '#111827',
        },
      },
      emptyContent: {
        icon: {
          width: '120px',
          height: '120px',
        },
        title: {
          fontSize: '1.5rem',
        },
        subtitle: {
          fontSize: '1rem',
        },
      },
    },
  },
});

Complete theme example

import { defineMetabaseTheme } from '@metabase/embedding-sdk-react';

const theme = defineMetabaseTheme({
  preset: 'light',
  fontFamily: 'Inter, sans-serif',
  fontSize: '14px',
  lineHeight: 1.5,
  colors: {
    brand: '#9333EA',
    'brand-hover': '#7C3AED',
    'brand-hover-light': '#A78BFA',
    'text-primary': '#1F2937',
    'text-secondary': '#6B7280',
    'text-tertiary': '#9CA3AF',
    background: '#FFFFFF',
    'background-secondary': '#F9FAFB',
    border: '#E5E7EB',
    positive: '#10B981',
    negative: '#EF4444',
    charts: [
      '#9333EA',
      '#3B82F6',
      '#10B981',
      '#F59E0B',
      '#EF4444',
    ],
  },
  components: {
    dashboard: {
      backgroundColor: '#F9FAFB',
      card: {
        backgroundColor: '#FFFFFF',
        border: '1px solid #E5E7EB',
      },
    },
    question: {
      backgroundColor: '#FFFFFF',
    },
    table: {
      cell: {
        textColor: '#1F2937',
        fontSize: '14px',
      },
      idColumn: {
        textColor: '#9333EA',
      },
    },
    cartesian: {
      label: {
        fontSize: '12px',
      },
    },
  },
});

Dynamic theming

Create theme switchers for your users:
import { MetabaseProvider, defineMetabaseTheme } from '@metabase/embedding-sdk-react';
import { useState } from 'react';

const lightTheme = defineMetabaseTheme({
  preset: 'light',
  colors: {
    brand: '#9333EA',
  },
});

const darkTheme = defineMetabaseTheme({
  preset: 'dark',
  colors: {
    brand: '#A78BFA',
  },
});

function App() {
  const [isDark, setIsDark] = useState(false);

  return (
    <>
      <button onClick={() => setIsDark(!isDark)}>
        Toggle {isDark ? 'Light' : 'Dark'} Mode
      </button>
      
      <MetabaseProvider 
        authConfig={authConfig} 
        theme={isDark ? darkTheme : lightTheme}
      >
        {/* Your app */}
      </MetabaseProvider>
    </>
  );
}

TypeScript types

import type {
  MetabaseTheme,
  MetabaseThemePreset,
  MetabaseColors,
  MetabaseComponentTheme,
  MetabaseFontFamily,
  ChartColor,
} from '@metabase/embedding-sdk-react';

Theme reference

Color properties

colors.brand
string
Primary brand color for buttons and links
colors.brand-hover
string
Hover state for brand elements
colors.text-primary
string
Main text color
colors.background
string
Default background color
colors.charts
ChartColor[]
Array of colors for chart series

Component properties

components.dashboard.card.border
string
CSS border property for dashboard cards (e.g., "1px solid #E5E7EB")
components.table.cell.fontSize
string
Font size for table cells
components.popover.zIndex
number
Z-index for popovers and overlays

Best practices

Use CSS variables

For dynamic themes, consider using CSS variables:
const theme = defineMetabaseTheme({
  colors: {
    brand: 'var(--primary-color)',
    background: 'var(--bg-color)',
  },
});

Maintain contrast

Ensure sufficient color contrast for accessibility:
  • Text on backgrounds: minimum 4.5:1 ratio
  • Large text: minimum 3:1 ratio

Test with real data

Always test your theme with:
  • Different chart types
  • Various data densities
  • Multiple dashboard layouts
  • Light and dark environments