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
| Symptom | Cause | Fix |
|---|---|---|
| Blank area, no bars | The parent has no height: ResponsiveContainer measures 0. | className="h-[280px] w-full" on ChartContainer. |
| width(0) and height(0) warning | The chart sits in a grid or flex child without min-width. | Add min-w-0 to the grid child. |
| Hydration or import error | The file is not a client component. | Add "use client" at the top of the chart file. |
| Transparent series | The 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.