visgl / visgl/react-map-gl

[Bug] Marker crashes with "appendChild" error during rapid client-side navigation (React 19 / Next.js 16)

Open
#2,584 1 comment 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
TypeScript
Stars
8.5k
Forks
1.4k
Avg merge
5d 17h
Merged PRs (30d)
3

Description

Description

The Marker component crashes with Cannot read properties of undefined (reading 'appendChild') during rapid client-side navigation (e.g., quickly navigating between a random page and a page that contains a <Map> with <Marker> children).

Expected Behavior

No response

Steps to Reproduce

TL:DR steps to reproduce:

Quickly navigate back and forth between pages which contain a <Map> with <Marker> children.

Steps to Reproduce

  1. Create a Next.js 16 app with React 19
  2. Page A: a list page (no map)
  3. Page B: a detail page with containing children
  4. Navigate rapidly between Page A and Page B using client-side navigation (clicking links, not full page loads)
  5. After a few rapid back-and-forth navigations, the error appears

Root Cause

The Marker component's useEffect at marker.ts#L86 calls marker.addTo(map.getMap()) with [] deps. During rapid unmount/remount cycles in React 19, the new mount's useEffect can fire before the previous mount's cleanup has run. At that point, mapbox-gl's Map instance still exists but its internal DOM container sub-elements have been torn down, causing marker.addTo() to fail when it tries to appendChild into a destroyed container.

Through instrumentation, I confirmed:

  • map.getMap() returns a valid Map instance (truthy)
  • map._container exists (truthy)
  • But inside marker.addTo(), deeper container child elements are undefined
  • The error is intermittent and depends on navigation speed

Suggested Fix

Wrap marker.addTo(map.getMap()) in a try-catch in the useEffect

useEffect(() => {
    try {
        marker.addTo(map.getMap());
    } catch {
        // Map container was destroyed during rapid navigation — safe to ignore
        return;
    }
    return () => {
        marker.remove();
    };
}, []);
Environment
  • react-map-gl: 8.1.0 (via @vis.gl/react-mapbox)
  • mapbox-gl: 3.11.0
  • React: 19.1.0
  • Next.js: 16.2.2 (App Router, Turbopack)
  • Browser: Chrome
Logs

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with modules/react-mapbox/src/components/marker.ts, especially the useEffect around the linked line, and reproduce the rapid client-side navigation described in the issue. Check the suggested handling against the marker lifecycle and cleanup behavior. Done means rapid navigation no longer produces the appendChild crash without breaking normal Marker mounting and removal.

Written by the indexing model from the issue text.

Assessment

Tech stack
nextjs, react, typescript
Domain
data-visualization, frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.