#2801·nivo

Missing unique key prop in Choropleth legends (React 19)

Author: MoisesCamacho01Created Oct 16, 2025Updated Feb 20, 2026

Bug Report: "Missing unique key prop" Warning in Choropleth Legends with React 19

Library: @nivo/geo Version: ^0.99.0 React Version: 19.1.0


Bug Description

When using the <ResponsiveChoropleth> component, providing a valid configuration to the legends prop causes React 19 to throw a "Each child in a list should have a unique 'key' prop" warning in the developer console.

The warning's stack trace clearly indicates that the issue originates from an internal Array.map call within the Choropleth.js file of the @nivo/geo library. It appears the list of legend items is being rendered without the required unique key prop.

Steps to Reproduce

  1. Set up a Next.js project using [email protected] and [email protected].
  2. Install @nivo/geo@^0.99.0.
  3. Implement a <ResponsiveChoropleth> component, passing a standard configuration object to the legends prop as shown in the code snippet below.
  4. Run the development server and observe the browser's developer console.

Expected Behavior

The map and its legend should render without any console warnings from React.

Actual Behavior

A "Missing unique key prop" warning is logged for each item in the legend.

Minimal Reproducible Example

This component reliably reproduces the warning.

typescript
// app/components/GeoChart.tsx
'use client';

import { useState, useEffect } from 'react';
import { ResponsiveChoropleth } from '@nivo/geo';
import * as topojson from "topojson-client";
import { Feature, FeatureCollection } from 'geojson';
import { Topology } from 'topojson-specification';

// Data using ISO 3166-1 numeric-3 codes
const geoData = [
    { "id": "840", "value": 450000 }, // USA
    { "id": "356", "value": 210000 }, // IND
    { "id": "826", "value": 180000 }, // GBR
];

const worldCountriesUrl = 'https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json';

export function GeoChart() {
  const [features, setFeatures] = useState<Feature[]>([]);

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch(worldCountriesUrl);
      const world = await response.json() as Topology;
      if (world.objects && world.objects.countries) {
        const countries = topojson.feature(world, world.objects.countries) as FeatureCollection;
        setFeatures(countries.features);
      }
    };
    fetchData();
  }, []);

  return (
    <div style={{ height: "400px" }}>
      <ResponsiveChoropleth
        data={geoData}
        features={features}
        margin={{ top: 0, right: 0, bottom: 0, left: 0 }}
        colors="purples"
        domain={[0, Math.max(...geoData.map(d => d.value))]}
        unknownColor="#E5E7EB"
        label="properties.name"
        valueFormat=".2s"
        projectionTranslation={[0.5, 0.6]}
        projectionRotation={[0, 0, 0]}
        borderWidth={0.5}
        borderColor="#ffffff"
        // The warning is triggered by this 'legends' prop
        legends={[
          {
            anchor: 'bottom-left',
            direction: 'column',
            justify: true,
            translateX: 20,
            translateY: -60,
            itemsSpacing: 0,
            itemWidth: 94,
            itemHeight: 18,
            itemDirection: 'left-to-right',
            itemTextColor: '#444444',
            itemOpacity: 0.85,
            symbolSize: 18,
          },
        ]}
      />
    </div>
  );
}

Relevant Stack Trace

The key frames from the stack trace pointing to the library code:

<unknown>
node_modules/@nivo/geo/src/Choropleth.js (124:33)
Array.map
<anonymous>
<unknown>
node_modules/@nivo/geo/src/Choropleth.js (123:44)
Array.map
<anonymous>
<unknown>
node_modules/@nivo/geo/src/Choropleth.js (106:21)
t.render
node_modules/@nivo/core/src/hocs/withContainer.js (25:21)

I attach an image of the bug

Image