What is the documentation issue?
The cacheComponents docs mention that effects are cleaned up on hide and recreated on reappear, and links to the Preserving UI State guide for common patterns. However, the guide's "Effect and media cleanup" section only covers timers and media elements <video>, <audio>, it's missing a critical third category
Libraries like Mapbox GL, Three.js, Leaflet, and Google Maps destroy their internal DOM references during useEffect cleanup (e.g., map.remove() sets _container = null). When Activity reappears the route, effects re-run but the library instance is in a "destroyed" state, leading to a crash:
TypeError: Cannot read properties of undefined (reading 'appendChild')
at Marker.addTo
at recursivelyTraverseReappearLayoutEffects
Critical detail: This only crashes in production builds (Webpack). Dev mode (Turbopack) never triggers it, making it extremely difficult to diagnose.
Proposed Fix: Remount the library from scratch on reappear instead of reusing the stale, destroyed instance.
A warning and example for this pattern in the Preserving UI State guide would prevent significant debugging time for anyone using mapping, 3D, or canvas-based libraries.
Is there any context that might help us understand?
Context:
I'd be happy to contribute a docs PR adding this pattern to the Preserving UI State guide if the team confirms the recommended approach. Let me know if this would be welcomed.
Does the docs page already exist? Please link to it.
https://nextjs.org/docs/app/guides/preserving-ui-state
What is the documentation issue?
The
cacheComponentsdocs mention that effects are cleaned up on hide and recreated on reappear, and links to the Preserving UI State guide for common patterns. However, the guide's "Effect and media cleanup" section only covers timers and media elements<video>,<audio>, it's missing a critical third categoryLibraries like Mapbox GL, Three.js, Leaflet, and Google Maps destroy their internal DOM references during
useEffectcleanup (e.g.,map.remove()sets_container = null). When Activity reappears the route, effects re-run but the library instance is in a "destroyed" state, leading to a crash:Critical detail: This only crashes in production builds (Webpack). Dev mode (Turbopack) never triggers it, making it extremely difficult to diagnose.
Proposed Fix: Remount the library from scratch on reappear instead of reusing the stale, destroyed instance.
A warning and example for this pattern in the Preserving UI State guide would prevent significant debugging time for anyone using mapping, 3D, or canvas-based libraries.
Is there any context that might help us understand?
Context:
react-map-glv8 / Mapbox GL JS v3.I'd be happy to contribute a docs PR adding this pattern to the Preserving UI State guide if the team confirms the recommended approach. Let me know if this would be welcomed.
Does the docs page already exist? Please link to it.
https://nextjs.org/docs/app/guides/preserving-ui-state