Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
Apache ECharts

How to Add Charts to a Next.js App (App Router and Pages Router)

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The reliable pattern is to keep your Next.js route and data fetching on the server, then render the visualization in a focused Client Component when the chart library needs browser APIs, state, effects, or event handlers. Install a React-compatible library, pass serializable data across the component boundary, give the chart a sized container, and load only the code the route needs.

This guide covers a complete Chart.js implementation, a selectively imported Apache ECharts option, bundle and rendering decisions, responsive and empty states, and the failures that commonly appear in development and production.

1. Decide where the chart belongs

In the App Router, pages and layouts are Server Components by default. That makes them a good place to query a database or call an internal API. Add 'use client' only to the component that needs client-side behavior. A chart wrapper can therefore be interactive without turning the entire route into a Client Component.

Use a Client Component when the library touches window or document, creates an instance in an effect, listens for pointer events, or stores hover and zoom state. If a library explicitly supports server rendering for the exact chart you need, you can keep more work on the server, but verify that behavior in its current documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Philips 24 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 241V8LB
  • CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
  • WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
  • A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents

App Router data flow

  1. Fetch and shape data in app/analytics/page.tsx (or another server-side route file).
  2. Pass plain arrays, strings, numbers, and booleans to a chart component.
  3. Put the client boundary in app/analytics/SalesChart.tsx.
  4. Handle loading, errors, empty data, and a chart container height as deliberate UI states.

Pages Router

With pages/, fetch data with getServerSideProps, getStaticProps, or a client-side data hook. The same boundary principle applies: isolate browser-dependent chart code instead of making unrelated components client-only.

2. Install Chart.js

Chart.js documents this installation command:

npm install chart.js

The quickest setup imports chart.js/auto. It registers the common controllers, elements, scales, and plugins for you. For a deliberate production bundle, use selective imports and register exactly what the chart uses; Chart.js describes that approach as tree-shakeable.

3. Build a complete App Router chart with Chart.js

Server page: fetch and serialize the data

import SalesChart from './SalesChart';

export default async function AnalyticsPage() {
  const response = await fetch('https://example.com/api/sales', {
    next: { revalidate: 300 }
  });

  if (!response.ok) {
    throw new Error('Unable to load sales data');
  }

  const rows: { month: string; total: number }[] = await response.json();

  return (
    <main>
      <h1>Sales</h1>
      <SalesChart
        labels={rows.map((row) => row.month)}
        values={rows.map((row) => row.total)}
      />
    </main>
  );
}

Only pass data that can cross a React Server Component boundary. Convert dates to ISO strings (or another explicit string format) and remove database objects, class instances, and functions before rendering.

Client chart component: quick-start configuration

'use client';

import { useEffect, useRef } from 'react';
import Chart from 'chart.js/auto';

type Props = { labels: string[]; values: number[] };

export default function SalesChart({ labels, values }: Props) {
  const canvasRef = useRef<HTMLCanvasElement | null>(null);

  useEffect(() => {
    if (!canvasRef.current || labels.length === 0) return;

    const chart = new Chart(canvasRef.current, {
      type: 'line',
      data: {
        labels,
        datasets: [{
          label: 'Sales',
          data: values,
          borderColor: '#2563eb',
          backgroundColor: 'rgba(37, 99, 235, 0.15)',
          fill: true,
          tension: 0.25
        }]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: { legend: { display: true } },
        scales: { y: { beginAtZero: true } }
      }
    });

    return () => chart.destroy();
  }, [labels, values]);

  if (labels.length === 0) {
    return <p>No sales data for this period.</p>;
  }

  return (
    <div style={{ position: 'relative', height: 360 }}>
      <canvas ref={canvasRef} aria-label="Sales by month" role="img" />
    </div>
  );
}

The cleanup call matters during route transitions and development Strict Mode: it prevents old chart instances from remaining attached to the canvas. The parent wrapper supplies a height because responsive charts cannot calculate a useful aspect ratio from an unconstrained container. In a real application, replace the inline style with a class and a responsive minimum height.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Philips 22 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 221V8LB
  • CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
  • SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors

Selective Chart.js registration

When you know the chart types and features, replace the auto import with explicit pieces. A line chart commonly needs a controller, line element, point element, category and linear scales, and any plugins you use. Register them once at module scope, then construct the chart in the effect. Consult the current Chart.js installation documentation and integration documentation for the exact components required by your version and chart type.

4. Use Apache ECharts when its model fits

Install ECharts with:

npm install echarts

ECharts supports a broad import for convenience and a tree-shakeable interface for smaller, explicit bundles. The selective form requires chart modules, components, and a renderer such as CanvasRenderer or SVGRenderer. Its container must have dimensions before initialization.

'use client';

import { useEffect, useRef } from 'react';
import * as echarts from 'echarts/core';
import { LineChart } from 'echarts/charts';
import { GridComponent, TooltipComponent } from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';

echarts.use([LineChart, GridComponent, TooltipComponent, CanvasRenderer]);

export default function TrafficChart({ labels, values }: {
  labels: string[];
  values: number[];
}) {
  const elementRef = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    if (!elementRef.current || labels.length === 0) return;
    const instance = echarts.init(elementRef.current);
    instance.setOption({
      tooltip: { trigger: 'axis' },
      xAxis: { type: 'category', data: labels },
      yAxis: { type: 'value' },
      series: [{ type: 'line', data: values, smooth: true }]
    });

    const resize = () => instance.resize();
    window.addEventListener('resize', resize);
    return () => {
      window.removeEventListener('resize', resize);
      instance.dispose();
    };
  }, [labels, values]);

  return <div ref={elementRef} style={{ width: '100%', height: 360 }} />;
}

Follow the current ECharts import guide and getting-started guide when adding additional series, components, or a different renderer.

5. Choose a library against your requirements

There is no evidence here for a universal winner. Make the decision from the chart and product you are actually shipping:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Sale
Dell 24 Monitor - SE2426H - 23.8-inch FHD (1920x1080) 144Hz 1ms Display, in-Plane Switching (IPS) Technology, AMD FreeSync™, TÜV 3-Star 2X HDMI, Tilt
  • Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
  • Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
  • Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
  • In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
  • Ultra-thin bezels: Maximize your viewing experience with thin bezels.
Question What to establish before choosing
Chart types Do you need lines and bars only, or specialized charts and multiple coordinated views?
Interaction List required tooltips, zooming, brushing, selection, annotations, and drill-down behavior.
Accessibility Verify keyboard behavior, screen-reader output, focus handling, and a text alternative for the specific chart.
Rendering Confirm whether Canvas or SVG is appropriate and where browser-only initialization occurs.
Bundle strategy Use Chart.js selective registration or ECharts selective imports when the route does not need every module.
Maintenance and license Check current project documentation, release activity, license terms, TypeScript support, and React integration for your dependency versions.

6. Keep chart JavaScript out of the initial route when useful

Next.js documents lazy loading as a way to defer Client Components and imported libraries. This can help when a chart is below the fold, hidden behind a tab, or used on a route where its library would otherwise inflate initial JavaScript. The gain depends on your application, so inspect the production build and user-perceived loading rather than assuming a fixed threshold.

import dynamic from 'next/dynamic';

const SalesChart = dynamic(() => import('./SalesChart'), {
  ssr: false,
  loading: () => <p>Loading chart…</p>
});

Use ssr: false only for a Client Component that cannot render during SSR. Keep the server page and its data work outside the dynamically loaded module. See the Next.js lazy-loading guide.

7. Production checklist

  • Give every chart a predictable width and height before initialization.
  • Render an explicit empty state instead of creating a chart with no points.
  • Show a loading state and surface fetch failures with a retry path where appropriate.
  • Destroy Chart.js instances or dispose ECharts instances during cleanup.
  • Debounce or otherwise control expensive updates when filters change rapidly.
  • Format dates, units, and large numbers in labels and tooltips consistently with the page.
  • Provide a text summary or table for users who cannot use the visual rendering.
  • Test narrow viewports, high-density displays, long labels, right-to-left text if applicable, and keyboard navigation.
  • Run the production build; development behavior can hide import, hydration, or cleanup mistakes.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

8. Troubleshooting

“window is not defined” or a server-render error

The library is being evaluated in a Server Component or during server rendering. Move the import and initialization into a Client Component; if necessary, dynamically import that component with ssr: false.

The canvas is blank

Check that the data arrays are non-empty, labels and values have matching lengths, the chart type has all required registered components, and the parent has a non-zero height. Inspect the browser console for configuration errors.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Samsung 27" Essential S3 (S36GD) Series FHD 1800R Curved Computer Monitor
  • CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
  • SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
  • MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
  • KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
  • INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient

The chart appears twice

An effect is creating a second instance without destroying the first. Return a cleanup function and avoid creating an instance outside the effect. Also verify that changing props does not leave stale canvases attached.

ECharts reports an initialization or zero-size problem

Initialize only after the container is mounted and styled with explicit dimensions. Call resize() when its parent changes size, and dispose the instance on unmount.

Hydration mismatch

Do not generate random values, locale-dependent markup, or time-sensitive labels differently on server and client. Pass stable serialized data and let the client chart draw after mount.

The route became unexpectedly large

Replace broad imports with selective registration, lazy-load a chart that is not needed immediately, and inspect the production bundle. Do not assume a smaller source file automatically means a smaller shipped bundle.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Sale
Sceptre New 22-Inch Gaming Monitor, FHD 1080p, Up to 144Hz, HDMI, DisplayPort, Built-in Speakers, Machine Black (E225W-FW144 Series, 2026)
  • 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
  • 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
  • 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.

Or skip the browser setup

If your goal is to create screenshots of a chart page, ScreenshotNeo provides a website screenshot API and MCP server. After your Next.js page is deployed, one request returns a PNG, JPEG, WebP, or PDF:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for options. It accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots, and every feature is available on every plan. Create a free ScreenshotNeo account.

FAQ

Frequently Asked Questions

Can I fetch chart data directly inside a Client Component?

Yes, but server-side fetching is often simpler for initial route data and keeps credentials away from the browser. Use a client fetch when the interaction genuinely requires it, and expose only the data the browser may access.

Should I use Canvas or SVG for a chart?

Choose based on the library’s renderer support, the amount of data, interaction needs, and accessibility testing for your specific visualization. ECharts requires you to select a renderer in its tree-shakeable setup.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Do I need a chart library for a single bar?

Not necessarily. A small HTML or CSS visualization may be sufficient, but a library becomes useful when you need scales, tooltips, legends, responsive resizing, or multiple chart types.

The Bottom Line

Keep the route and data work server-side, isolate browser-dependent chart code in a small Client Component, register or load only what the visualization needs, and test the production build with real empty, error, and responsive states.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.