# How MapLibre Control Class Names Get Mirrored for the Record Video Feature in GeoLibre

> Discover how GeoLibre mirrors MapLibre control class names for video recording using MAP_PANEL_SELECTOR to capture on-map UI panels during export.

- Repository: [Open Geospatial Solutions/GeoLibre](https://github.com/opengeos/GeoLibre)
- Tags: internals
- Published: 2026-08-05

---

**GeoLibre mirrors MapLibre control class names through a static CSS selector constant named `MAP_PANEL_SELECTOR` that targets `.maplibre-gl-html-control`, `.maplibre-gl-legend`, `.maplibre-gl-colorbar`, and `.geolibre-legend-panel` to raster-capture on-map UI panels during video export.**

The **Record Video** feature in GeoLibre allows users to export animated map recordings. When the *Include map panels* option is enabled, the application raster-captures HTML control panels, legends, and color-bars directly from the DOM and embeds them into each video frame. Since the underlying `maplibre-gl-components` library does not export these class names, GeoLibre's implementation mirrors them through a carefully maintained CSS selector.

## The MAP_PANEL_SELECTOR Constant

In [`apps/geolibre-desktop/src/components/layout/RecordVideoDialog.tsx`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/components/layout/RecordVideoDialog.tsx), the selector is defined as a static constant at lines 57–58:

```typescript
const MAP_PANEL_SELECTOR =
  ".maplibre-gl-html-control, .maplibre-gl-legend, .maplibre-gl-colorbar, .geolibre-legend-panel";

```

This selector identifies four distinct panel types:

- **`.maplibre-gl-html-control`** – the HTML control panel rendered by the Components plugin
- **`.maplibre-gl-legend`** – the discrete symbol legend panel
- **`.maplibre-gl-colorbar`** – the continuous color scale panel
- **`.geolibre-legend-panel`** – GeoLibre's custom `MapLegendPanel` component

## DOM Query During Recording

When a user initiates recording with panels enabled, the dialog queries the map container using this selector. From lines 27–30 of [`RecordVideoDialog.tsx`](https://github.com/opengeos/GeoLibre/blob/main/RecordVideoDialog.tsx):

```typescript
const domOverlays = includePanels
  ? Array.from(map.getContainer().querySelectorAll<HTMLElement>(MAP_PANEL_SELECTOR))
  : null;

```

The resulting `domOverlays` array contains references to all matched DOM elements. These references are passed to `recordMapCanvas` in [`apps/geolibre-desktop/src/lib/map-recorder.ts`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/lib/map-recorder.ts), which handles the actual rasterization by drawing each panel onto the canvas before encoding the video frame.

## Maintenance Risk and Documentation

The class names mirrored in `MAP_PANEL_SELECTOR` are **internal implementation details** of `maplibre-gl-components`. Because they are not part of the library's public API, version updates may change them without warning.

The repository documents this fragility in [`CLAUDE.md`](https://github.com/opengeos/GeoLibre/blob/main/CLAUDE.md) at line 96:

> "`MAP_PANEL_SELECTOR` [...] mirrors the **rendered** control class names from `maplibre-gl-components` — `maplibre-gl-html-control`, `maplibre-gl-legend`, `maplibre-gl-colorbar` — so the Record Video *Include map panels* option can rasterize those on‑map overlays into the recording."

If the selector drifts from the library's actual rendered output, the checkbox may disable itself or panels will silently fail to appear in recordings. No build-time error occurs because these are runtime DOM queries.

## Complete Usage Example

The following pattern demonstrates how the panel capture integrates into the recording workflow:

```tsx
// State management for panel inclusion
const [includePanels, setIncludePanels] = useState(false);

// UI control
<Checkbox
  checked={includePanels}
  disabled={!panelsAvailable}
  onCheckedChange={setIncludePanels}
>
  {t("recordVideo.includePanels")}
</Checkbox>

```

```typescript
// Recording invocation with captured overlays
await recordMapCanvas({
  map,
  region: mode === "region" ? region : null,
  caption: hasCaptionText(captionOpts) ? captionOpts : null,
  domOverlays,               // panels captured via MAP_PANEL_SELECTOR
  fps,
  signal: controller.signal,
  onStarted: () => setStatus("recording"),
  onElapsed: setElapsed,
});

```

## Key Implementation Files

| File | Purpose |
|------|---------|
| [`apps/geolibre-desktop/src/components/layout/RecordVideoDialog.tsx`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/components/layout/RecordVideoDialog.tsx) | Defines `MAP_PANEL_SELECTOR` and executes DOM queries |
| [`apps/geolibre-desktop/src/lib/map-recorder.ts`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/lib/map-recorder.ts) | Consumes `domOverlays` to rasterize panels onto video frames |
| [`apps/geolibre-desktop/src/components/legend/MapLegendPanel.tsx`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/components/legend/MapLegendPanel.tsx) | Implements the custom `.geolibre-legend-panel` component |
| [`CLAUDE.md`](https://github.com/opengeos/GeoLibre/blob/main/CLAUDE.md) | Documents the mirroring requirement for maintainers |

## Summary

- **Mirror strategy**: GeoLibre uses a hardcoded CSS selector (`MAP_PANEL_SELECTOR`) to target internal MapLibre class names
- **Runtime dependency**: Panel capture relies on DOM queries, not type-safe imports, making it vulnerable to upstream changes
- **Manual maintenance**: Developers must verify selector accuracy whenever `maplibre-gl-components` is updated
- **Silent failure mode**: Mismatched selectors disable features without compile-time or runtime errors

## Frequently Asked Questions

### What happens if `maplibre-gl-components` changes its class names?

The *Include map panels* checkbox may disable itself or the panels will fail to appear in exported videos. No error is thrown because the selector runs at runtime against the live DOM. The [`CLAUDE.md`](https://github.com/opengeos/GeoLibre/blob/main/CLAUDE.md) file explicitly instructs maintainers to verify `MAP_PANEL_SELECTOR` after any dependency update.

### Why doesn't GeoLibre import these class names directly?

The `maplibre-gl-components` library does not export its rendered class names as part of its public API. They are internal implementation details generated at runtime by the Components plugin, DOM rendering logic, and legend system. Hardcoding the selector is the only available integration point.

### How does `recordMapCanvas` use the captured DOM elements?

The function receives the `domOverlays` array and iterates through each element, drawing its visual representation onto the recording canvas using standard browser rasterization APIs. This embeds the UI panels into each frame of the video output before encoding.

### What is `.geolibre-legend-panel` doing in a MapLibre selector?

This class targets GeoLibre's own `MapLegendPanel` component, a custom implementation separate from `maplibre-gl-components`. Including it in `MAP_PANEL_SELECTOR` ensures consistency: both external library panels and native GeoLibre panels are captured through the same query mechanism.