AdminKitDocs
Charts

Next.js Area Chart

A Next.js area chart for the App Router: an ApexCharts client component in AdminKit PRO with filled, smooth series that follow light and dark mode.

Pro

This component is only available in AdminKit PRO. Learn more.

An area chart tracks a quantity over time and fills the space under each line. You see the trend and the volume in one view, which suits figures like visits per hour. In AdminKit for Next.js you draw it with ApexChart, which wraps ApexCharts. Chart setup describes the wrapper.

ApexCharts needs the browser, so ApexChart is a client component: its file starts with "use client". While Next.js renders the page on the server, and during hydration (the browser taking over the HTML Next.js built), the wrapper shows a skeleton. Then it imports ApexCharts and draws the chart.

In the App Router, pages are server components, and a server component cannot pass a function to a client component. The options prop is a function of the theme colors. So the chart goes in a client component file of its own, and your page renders that file.

Example

src/components/visits-area-chart.tsx
"use client";

import { ApexChart } from "@/components/plugins/apexcharts";

export function VisitsAreaChart() {
  return (
    <div className="position-relative" style={{ minHeight: 365 }}>
      <ApexChart
        options={() => ({
          chart: { height: 350, type: "area" },
          dataLabels: { enabled: false },
          stroke: { curve: "smooth" },
          series: [
            { name: "series1", data: [31, 40, 28, 51, 42, 109, 100] },
            { name: "series2", data: [11, 32, 45, 32, 34, 52, 41] },
          ],
          xaxis: {
            type: "datetime",
            categories: [
              "2026-09-19T00:00:00",
              "2026-09-19T01:30:00",
              "2026-09-19T02:30:00",
              "2026-09-19T03:30:00",
              "2026-09-19T04:30:00",
              "2026-09-19T05:30:00",
              "2026-09-19T06:30:00",
            ],
          },
          tooltip: { x: { format: "dd/MM/yy HH:mm" } },
        })}
      />
    </div>
  );
}

The page stays a server component and renders the chart in a card. pageMetadata() reads the title and description of the route from src/data/pages.json, so list the route there (see Add a page):

src/app/(dashboard)/analytics/page.tsx
import { VisitsAreaChart } from "@/components/visits-area-chart";
import { pageMetadata } from "@/lib/site";

export const metadata = pageMetadata("/analytics");

export default function AnalyticsPage() {
  return (
    <div className="card">
      <div className="card-header">
        <h2 className="card-title mb-0">Visits</h2>
      </div>
      <div className="card-body">
        <VisitsAreaChart />
      </div>
    </div>
  );
}

Give the position-relative element the height of the chart: the demo uses 365px for a 350px chart. The static HTML then already reserves the space, and the page does not shift when the chart draws.

Props

PropTypeDefaultDescription
options(theme: Theme) => ApexOptionsThe ApexCharts options, with series and chart.type. Called again with the new colors when the color mode changes

ApexChart is in src/components/plugins/apexcharts.tsx. Other props, such as id, role and aria-label, go to the chart's <div>.

Data from the page

Sometimes the page should own the data. It can pass the data from the server component as props, because arrays of numbers and strings can cross to a client component. The options function cannot, so it stays in the chart file.

With the static export (output: "export"), the page runs at build time, so this data is fixed in the build. For live data, fetch it in the client component instead.

src/components/visits-area-chart.tsx
"use client";

import { ApexChart } from "@/components/plugins/apexcharts";

export function VisitsAreaChart({ visits }: { visits: number[] }) {
  return (
    <div className="position-relative" style={{ minHeight: 365 }}>
      <ApexChart
        options={(theme) => ({
          chart: { height: 350, type: "area" },
          colors: [theme.primary],
          dataLabels: { enabled: false },
          stroke: { curve: "smooth" },
          series: [{ name: "Visits", data: visits }],
        })}
      />
    </div>
  );
}

Time axis and stacking

  • xaxis.type: "datetime" takes dates as categories, as ISO strings or timestamps. tooltip.x.format sets the date in the tooltip. ApexCharts shows the axis labels in UTC unless xaxis.labels.datetimeUTC is false.
  • chart.stacked: true stacks the series, so the top line is the total. The AI dashboard stacks the tokens per model this way, with fill: { type: "gradient", gradient: { opacityFrom: 0.45, opacityTo: 0.05 } }.

Accessibility

  • Tooltips only show on hover. Give the chart a visible title, such as the card title, and put the key figures in text or a table as well.
  • Other props of ApexChart go to its <div>: role="figure" and aria-label="Visits per hour" name the chart.
  • Each series has a name in the legend, so color is not the only way to tell them apart.
  • Under prefers-reduced-motion: reduce the chart draws without animation. A color mode change never animates.

Last updated on

On this page