mapbox_gl_flutter_web 0.1.2 copy "mapbox_gl_flutter_web: ^0.1.2" to clipboard
mapbox_gl_flutter_web: ^0.1.2 copied to clipboard

Platformweb

Flutter Web bridge for Mapbox GL JS. Pair with mapbox_maps_flutter on mobile via conditional imports to render the same map on every platform.

mapbox_gl_flutter_web #

Flutter Web bridge for Mapbox GL JS. Renders the same Mapbox style, sources, layers, and gestures that mapbox_maps_flutter exposes natively on Android and iOS, but in the browser via dart:js_interop.

mapbox_maps_flutter ships native bindings for Android and iOS only. This package fills the web gap without forking that plugin: pair it via conditional imports so the same Dart source compiles and runs on every platform.


Install #

dependencies:
  mapbox_maps_flutter: ^2.20.1     # mobile, official
  mapbox_gl_flutter_web: ^0.1.0    # web, this package

Add the Mapbox GL JS script + CSS to your web/index.html:

<link href="https://api.mapbox.com/mapbox-gl-js/v3.7.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v3.7.0/mapbox-gl.js"></script>

If your CSP is restrictive, allow Mapbox tile / sprite endpoints under connect-src and the GL JS CDN under script-src / style-src.


Conditional-import pattern #

Define a single app_map.dart in your project that re-exports whichever package is appropriate:

// lib/services/map/app_map.dart
export 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'
    if (dart.library.js_interop) 'package:mapbox_gl_flutter_web/mapbox_gl_flutter_web.dart';

Then import that file everywhere instead of either underlying package:

import 'package:my_app/services/map/app_map.dart';

void main() {
  MapboxOptions.setAccessToken('pk.YOUR_PUBLIC_TOKEN');
  runApp(const MyApp());
}

class MyMap extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MapboxMapWidget(
      cameraOptions: CameraOptions(
        center: Point(coordinates: Position(77.5946, 12.9716)),
        zoom: 12,
      ),
      onMapCreated: (MapboxMap map) async {
        await map.loadStyleURI(MapboxStyles.STANDARD);
      },
    );
  }
}

Important: use a public Mapbox token (pk.…). Secret tokens (sk.…) are valid for server-to-server calls but the tile API silently rejects them in the browser, leaving you with a black canvas and no error in the console.


What's covered #

Feature Status
Map widget embedding (HtmlElementView + ResizeObserver)
Camera: flyTo, easeTo, getCameraState, setBounds, getBounds
pixelForCoordinate / coordinateForPixel
cameraForCoordinatesPadding (bounds-based on web)
GeoJSON sources with clustering + cluster properties
Symbol + Line layers (icon, text, paint properties)
Runtime setStyleLayerProperty (layout vs paint routed automatically)
Style image registration from ui.Image (raw RGBA)
queryRenderedFeatures
setStyleImportConfigProperty (Mapbox Standard lightPreset etc.)
Scale bar / compass / gesture toggles
triggerRepaint
Annotations API ❌ (PRs welcome)
Location puck
Terrain / fog / atmosphere
Raster, raster-DEM, 3D model layers
Vector tile sources beyond the style URI

If you need any of the unchecked items, file an issue (or a PR — the JS-interop pattern in lib/src/impl.dart is straight-line mechanical).


Gotchas #

  1. Container layout timingnew mapboxgl.Map({}) locks the canvas at 400×300 if the container has no layout yet. We defer construction by two frames and attach a ResizeObserver to call map.resize(). If you wrap the widget in something that hides it (display: none) and then shows it, you may need to call triggerRepaint after the show.

  2. CSP. mapbox-gl-js needs connect-src access to https://api.mapbox.com (sprites, tiles, models), plus your local dev origin for hot-reload.

  3. Custom headers on tiled sources aren't wired up; this package only exposes the subset of the API the SpeakX app actually uses.

  4. Wasm dry-run. dart:js_interop is wasm-compatible, but dart:js_interop_unsafe (used for property access) currently is not. Wasm builds will fail until upstream lands. Compile to js for now.


Why not just contribute to mapbox_maps_flutter? #

This package was originally written inside SpeakX to ship the web build of a production Flutter app. We considered upstreaming, but the official plugin re-generates its API surface from a shared cross-platform schema and the maintainer team has been clear web isn't on the official roadmap. Publishing this as a separate community plugin lets other Flutter Web teams skip the JS-interop boilerplate without us signing up to maintain a fork.

If mapbox_maps_flutter ever ships official web support, this package will become a one-line shim — or you can switch off it entirely without changing your call sites (because the public type names match).


License #

MIT. See LICENSE.

1
likes
160
points
134
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter Web bridge for Mapbox GL JS. Pair with mapbox_maps_flutter on mobile via conditional imports to render the same map on every platform.

Repository (GitHub)
View/report issues

Topics

#mapbox #maps #web #js-interop #flutter-web

License

MIT (license)

Dependencies

flutter

More

Packages that depend on mapbox_gl_flutter_web