React

shadcn charts with Recharts

ChartContainer turns config colours into CSS variables, but it needs a container with height in a client component: without both, the chart stays empty.

Key points

  • Every `ChartConfig` key becomes a `--color-` variable used by `fill` and `stroke`.
  • `ChartContainer` includes `ResponsiveContainer`: without a parent with height the chart measures zero.
  • Recharts runs only in the browser: the chart file needs `"use client"`.

Short answer: npx shadcn@latest add chart installs a wrapper around Recharts; define a ChartConfig, put the chart inside ChartContainer with an explicit height, and use var(--color-key) in fill and stroke. The file must be a client component.

The config is the colour map

Recharts wants a colour on every series. shadcn moves it into one object: the key must match the dataKey, the color field becomes a CSS variable, and label ends up in the tooltip and the legend. When the key does not match, the chart draws but the series stays colourless.

"use client";

import { Bar, BarChart, CartesianGrid, XAxis } from "recharts";
import {
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  type ChartConfig,
} from "@/components/ui/chart";

const data = [
  { month: "Gen", desktop: 186, mobile: 80 },
  { month: "Feb", desktop: 305, mobile: 200 },
  { month: "Mar", desktop: 237, mobile: 120 },
];

const config = {
  desktop: { label: "Desktop", color: "var(--chart-1)" },
  mobile: { label: "Mobile", color: "var(--chart-2)" },
} satisfies ChartConfig;

export function VisitsChart() {
  return (
    
      
        
        
        } />
        
        
      
    
  );
}

The mechanism: ChartContainer reads the config and writes --color-desktop and --color-mobile onto the element wrapping the chart. fill="var(--color-desktop)" reads that variable, so switching the theme switches the chart without touching the component.

Why the chart stays empty

SymptomCauseFix
Blank area, no barsThe parent has no height: ResponsiveContainer measures 0.className="h-[280px] w-full" on ChartContainer.
width(0) and height(0) warningThe chart sits in a grid or flex child without min-width.Add min-w-0 to the grid child.
Hydration or import errorThe file is not a client component.Add "use client" at the top of the chart file.
Transparent seriesThe config key does not match the dataKey.Align both strings, without renaming just one of them.

Tooltip and legend

ChartTooltip replaces the default Recharts tooltip and ChartTooltipContent applies the design system's styling. labelFormatter formats the date or month; formatter changes the displayed value, from 186 to 186 visits for instance. The legend works the same way, with ChartLegend and ChartLegendContent.

 `Mese: ${value}`}
      formatter={(value) => `${value} visite`}
    />
  }
/>

Accessibility

accessibilityLayer makes the chart reachable by keyboard and announces points with the arrow keys. That is not enough: a chart is a picture of data, and a screen reader user needs the same numbers as text. Add a hidden table or a summary next to the chart, not a generic alt.

A named limitation

Recharts measures its container in the browser: during SSR the chart does not exist and the first paint shows an empty slot. When the chart sits above the fold, reserve the height with aspect-video or an h-[280px] wrapper, otherwise the content below jumps when the chart appears and CLS gets worse. The catalogue, measured on 1 November 2026, holds 70 blocks in the charts category: they are static compositions, not accessibility recipes.

Where to continue

In the catalogue you find a chart block with preview, the chart category and the chart component record. For colours read what shadcn/ui is and how to theme shadcn/ui; the block selection is in the best chart blocks of 2026.

Frequently asked questions

Why is the chart invisible?

Almost always because the container has zero height: ResponsiveContainer measures the parent and draws nothing without an explicit height. Add h-[280px] or aspect-video to ChartContainer.

Why is the series transparent?

Because the ChartConfig key does not match the series dataKey. The colour comes from var(--color-key), so both names must be identical.

Can I use the chart in a Server Component?

No. Recharts measures the DOM and keeps state in the browser: the file holding ChartContainer needs "use client" at the top. You can pass the data from the server as props.

How do I change series colours?

Change the color field in ChartConfig, or point it at a theme token such as var(--chart-1). ChartContainer rewrites the variables and the chart follows the light and dark theme.

Is the chart accessible?

With accessibilityLayer it is reachable by keyboard, but the data stays invisible to a screen reader. Add a hidden table or a text summary next to the chart.