Highcharts Grid with Next.js
The official React packages work with Next.js but require client-side rendering
since Grid uses browser APIs. This guide covers that setup. Configure the grid
with options or with components, the same as in
Getting started.
1. Install the Grid React package
npm install @highcharts/grid-lite-react# ornpm install @highcharts/grid-pro-react
The core Grid library is included as a dependency and will be installed automatically.
Updating to newer versions
- Minor and patch updates: Run
npm updateto get the latest compatible version - Major updates: Install the latest React package which will include the new major version:npm install @highcharts/grid-lite-react@latest
2. Use dynamic import with SSR disabled
The Grid component must be loaded dynamically with ssr: false to avoid
"window is not defined" errors during server-side rendering. A type-only
GridOptions import is safe in this file; Grid is loaded on the client:
'use client';import { useState } from 'react';import dynamic from 'next/dynamic';import { type GridOptions } from '@highcharts/grid-lite-react';const Grid = dynamic(() => import('@highcharts/grid-lite-react').then((mod) => mod.Grid),{ ssr: false });export default function Page() {const [options] = useState<GridOptions>({data: {columns: {name: ['Alice', 'Bob', 'Charlie', 'David'],age: [23, 34, 45, 56],city: ['New York', 'Oslo', 'Paris', 'Tokyo']}}});return <Grid options={options} />;}
Data, Column, and the other components are value imports, so they cannot
sit in a Server Component. Put that grid in a client module and load the
module with ssr: false. The markup inside the client file is the same as in
Getting started.
import dynamic from 'next/dynamic';const TeamGrid = dynamic(() => import('./team-grid'), { ssr: false });export default function Page() {return <TeamGrid />;}
For Grid Pro, swap the imports to @highcharts/grid-pro-react.
3. Access the Grid instance (optional)
Use the gridRef prop or a callback to access the underlying Grid instance:
'use client';import { useState, useRef } from 'react';import dynamic from 'next/dynamic';import {type GridInstance,type GridOptions,type GridRefHandle} from '@highcharts/grid-lite-react';const Grid = dynamic(() => import('@highcharts/grid-lite-react').then((mod) => mod.Grid),{ ssr: false });export default function Page() {const [options] = useState<GridOptions>({data: {columns: {name: ['Alice', 'Bob', 'Charlie', 'David'],age: [23, 34, 45, 56]}},pagination: {enabled: true,pageSize: 3}});const gridRef = useRef<GridRefHandle<GridOptions> | null>(null);const onButtonClick = () => {console.log('Grid instance:', gridRef.current?.grid);};const onGridCallback = (grid: GridInstance<GridOptions>) => {console.log('Grid initialized:', grid);};return (<><Grid options={options} gridRef={gridRef} callback={onGridCallback} /><button onClick={onButtonClick}>Access Grid</button></>);}
The same gridRef and callback props work when the grid is configured with
components. See
Grid.
4. Updating the Grid
When options change, the Grid component updates. Store that object in
useState so the grid updates only when you change the state:
'use client';import { useState } from 'react';import dynamic from 'next/dynamic';import { type GridOptions } from '@highcharts/grid-lite-react';const Grid = dynamic(() => import('@highcharts/grid-lite-react').then((mod) => mod.Grid),{ ssr: false });export default function Page() {const [options, setOptions] = useState<GridOptions>({data: {columns: {name: ['Alice', 'Bob'],age: [23, 34]}}});const loadNewData = () => {setOptions({data: {columns: {name: ['Charlie', 'Diana', 'Eve'],age: [45, 56, 67]}}});};return (<><Grid options={options} /><button onClick={loadNewData}>Load new data</button></>);}
With components, keep the row data in state and pass it to Data. See
Data.
See the live Grid Lite example. See the live Grid Pro example.