← MapboxCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to Mapbox
Snapshot Sep 30, 2026 · 23:11 UTC · version 1.0.0
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "mapbox-flutter-patterns",
"description": "Official integration patterns for the Mapbox Maps Flutter SDK. Covers installation, iOS/Android platform setup, access token configuration, MapWidget initialization, camera control, annotations with tap handling, user location, and loading GeoJSON. Based on official Mapbox documentation.",
"included_files": [
{
"relative_path": ".DS_Store",
"size_in_bytes": 6148
},
{
"relative_path": "AGENTS.md",
"size_in_bytes": 2713
},
{
"relative_path": "evals/evals.json",
"size_in_bytes": 3895
},
{
"relative_path": "references/annotations.md",
"size_in_bytes": 3038
},
{
"relative_path": "references/platform-setup.md",
"size_in_bytes": 5989
}
],
"skill_md_contents": "---\nname: mapbox-flutter-patterns\ndescription: Official integration patterns for the Mapbox Maps Flutter SDK. Covers installation, iOS/Android platform setup, access token configuration, MapWidget initialization, camera control, annotations with tap handling, user location, and loading GeoJSON. Based on official Mapbox documentation.\n---\n\n# Mapbox Flutter Integration Patterns\n\nOfficial patterns for integrating the Mapbox Maps SDK for Flutter (mapbox_maps_flutter) on iOS and Android with Dart.\n\n**Use this skill when:**\n\n- Installing and configuring mapbox_maps_flutter in a Flutter app\n- Setting the Mapbox access token the right way\n- Initializing a `MapWidget` with camera / style options\n- Adding annotations (points, circles, lines, polygons) and handling taps\n- Showing the user location puck\n- Loading GeoJSON from app assets\n- Troubleshooting iOS build failures after adding Mapbox\n\n**Official Resources:**\n\n- [Flutter Maps Guides](https://docs.mapbox.com/flutter/maps/guides/)\n- [API Reference on pub.dev](https://pub.dev/documentation/mapbox_maps_flutter/latest/)\n- [Example App](https://github.com/mapbox/mapbox-maps-flutter/tree/main/example)\n\n> Web and desktop are not supported — the Flutter SDK targets iOS and Android only.\n\n---\n\n## Installation & Setup\n\n### Requirements\n\n- Flutter SDK 3.22.3 / Dart 3.4.4+\n- **iOS: deployment target 14.0 or higher**\n- **Android: minSdk 21 or higher**\n- Free Mapbox account\n\n### Step 1: Add the dependency\n\n```yaml\n# pubspec.yaml\ndependencies:\n mapbox_maps_flutter: ^2.0.0\n```\n\n```bash\nflutter pub get\n```\n\n### Step 2: Bump the iOS deployment target to 14.0 (required)\n\n**This is the single most common cause of iOS build failures after adding Mapbox.** The Flutter SDK requires **iOS 14.0** and will not compile on the Flutter default.\n\n1. Open `ios/Runner.xcworkspace` in Xcode.\n2. Select the **Runner** target → **General** → set **Minimum Deployments → iOS** to `14.0`.\n3. If `ios/Podfile` exists, update the platform line too:\n\n ```ruby\n # ios/Podfile\n platform :ios, '14.0'\n ```\n\nYou do not need to worry about CocoaPods vs Swift Package Manager — `mapbox_maps_flutter` supports both and Flutter picks whichever your app is configured for.\n\n### Step 3: iOS location permission\n\nAdd the purpose string to `ios/Runner/Info.plist`:\n\n```xml\n<key>NSLocationWhenInUseUsageDescription</key>\n<string>Show your location on the map</string>\n```\n\n### Step 4: Android permissions\n\nAdd to `android/app/src/main/AndroidManifest.xml`:\n\n```xml\n<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />\n<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\" />\n```\n\n### Step 5: Configure the access token\n\nThe recommended pattern is to pass the token via `--dart-define` at build/run time and set it on `MapboxOptions` before creating any `MapWidget`.\n\n```bash\nflutter run --dart-define=ACCESS_TOKEN=pk.your_token_here\n```\n\n```dart\n// main.dart\nimport 'package:flutter/material.dart';\nimport 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';\n\nconst accessToken = String.fromEnvironment('ACCESS_TOKEN');\n\nvoid main() {\n MapboxOptions.setAccessToken(accessToken);\n runApp(const MaterialApp(home: MapScreen()));\n}\n```\n\nNever hard-code tokens in source. For CI, pass `--dart-define=ACCESS_TOKEN=$MAPBOX_ACCESS_TOKEN`.\n\n---\n\n## Map Initialization\n\n### Basic map\n\n```dart\nimport 'package:flutter/material.dart';\nimport 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';\n\nclass MapScreen extends StatelessWidget {\n const MapScreen({super.key});\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n body: MapWidget(\n key: const ValueKey('mapWidget'),\n cameraOptions: CameraOptions(\n center: Point(coordinates: Position(-122.4194, 37.7749)),\n zoom: 12,\n ),\n styleUri: MapboxStyles.STANDARD,\n ),\n );\n }\n}\n```\n\n### Grab the `MapboxMap` controller\n\n```dart\nclass MapScreen extends StatefulWidget {\n const MapScreen({super.key});\n\n @override\n State<MapScreen> createState() => _MapScreenState();\n}\n\nclass _MapScreenState extends State<MapScreen> {\n MapboxMap? mapboxMap;\n\n void _onMapCreated(MapboxMap controller) {\n mapboxMap = controller;\n }\n\n @override\n Widget build(BuildContext context) {\n return MapWidget(\n key: const ValueKey('mapWidget'),\n onMapCreated: _onMapCreated,\n cameraOptions: CameraOptions(\n center: Point(coordinates: Position(-122.4194, 37.7749)),\n zoom: 12,\n ),\n );\n }\n}\n```\n\n---\n\n## Add Annotations\n\nUse `mapboxMap.annotations` to create managers for point, circle, polyline, and polygon annotations. Managers are long-lived — create them once and reuse for updates.\n\n### Point annotations with a custom image\n\n```dart\nimport 'package:flutter/services.dart' show rootBundle;\n\nPointAnnotationManager? pointAnnotationManager;\n\nFuture<void> _addMarkers(MapboxMap mapboxMap) async {\n pointAnnotationManager = await mapboxMap.annotations.createPointAnnotationManager();\n\n final bytes = await rootBundle.load('assets/marker.png');\n final imageBytes = bytes.buffer.asUint8List();\n\n final options = <PointAnnotationOptions>[\n PointAnnotationOptions(\n geometry: Point(coordinates: Position(-122.4194, 37.7749)),\n image: imageBytes,\n iconSize: 1.2,\n ),\n PointAnnotationOptions(\n geometry: Point(coordinates: Position(-122.4094, 37.7849)),\n image: imageBytes,\n ),\n ];\n\n await pointAnnotationManager!.createMulti(options);\n}\n```\n\nRemember to register the asset in `pubspec.yaml`:\n\n```yaml\nflutter:\n assets:\n - assets/marker.png\n```\n\n### Tap handling\n\nUse `manager.tapEvents` — this is the current API. `addOnPointAnnotationClickListener` is deprecated.\n\n`tapEvents` returns a `Cancelable` that you store and invoke `.cancel()` on when the listener is no longer needed:\n\n```dart\nfinal Cancelable tapSubscription = pointAnnotationManager!.tapEvents(\n onTap: (annotation) {\n debugPrint('Tapped annotation ${annotation.id}');\n },\n);\n\n@override\nvoid dispose() {\n tapSubscription.cancel();\n super.dispose();\n}\n```\n\nThe same pattern — returning a `Cancelable` — exists on every manager's `longPressEvents` and `dragEvents`, and across the other annotation types (`CircleAnnotationManager.tapEvents`, etc.).\n\n### Load annotations from GeoJSON\n\n```dart\nimport 'dart:convert';\nimport 'package:flutter/services.dart' show rootBundle;\n\nFuture<void> _loadGeoJson(MapboxMap mapboxMap) async {\n final raw = await rootBundle.loadString('assets/coffee_shops.geojson');\n final geo = jsonDecode(raw) as Map<String, dynamic>;\n final features = (geo['features'] as List).cast<Map<String, dynamic>>();\n\n final manager = await mapboxMap.annotations.createPointAnnotationManager();\n final icon = (await rootBundle.load('assets/coffee.png')).buffer.asUint8List();\n\n final options = features.map((feature) {\n final coords = feature['geometry']['coordinates'] as List;\n return PointAnnotationOptions(\n geometry: Point(coordinates: Position(coords[0] as double, coords[1] as double)),\n image: icon,\n );\n }).toList();\n\n await manager.createMulti(options);\n}\n```\n\nFor thousands of features use a style layer (`GeoJsonSource` + `SymbolLayer`) instead of annotations.\n\n---\n\n## Show User Location\n\nPermissions must already be granted (use `permission_handler` or similar) before enabling the puck.\n\n```dart\nawait mapboxMap.location.updateSettings(LocationComponentSettings(\n enabled: true,\n puckBearingEnabled: true,\n locationPuck: LocationPuck(\n locationPuck2D: DefaultLocationPuck2D(),\n ),\n));\n```\n\n---\n\n## Camera Control\n\n```dart\n// Instant jump\nawait mapboxMap.setCamera(CameraOptions(\n center: Point(coordinates: Position(-80.1263, 25.7845)),\n zoom: 14,\n));\n\n// Animated fly-to\nawait mapboxMap.flyTo(\n CameraOptions(\n center: Point(coordinates: Position(-80.1263, 25.7845)),\n zoom: 17,\n bearing: 180,\n pitch: 30,\n ),\n MapAnimationOptions(duration: 2000),\n);\n```\n\n---\n\n## Troubleshooting\n\n### iOS build fails with \"platform is lower than deployment target\"\n\nThe Flutter default iOS deployment target is lower than Mapbox's minimum (iOS 14). Set **Minimum Deployments → iOS** to `14.0` on the Runner target in Xcode. If the project has an `ios/Podfile`, also set `platform :ios, '14.0'` there and re-run `pod install`.\n\n### `setAccessToken` not called\n\nIf you forget to call `MapboxOptions.setAccessToken` before creating a `MapWidget`, the map will load with a blank grid. Always call it in `main()` before `runApp`.\n\n### Annotation tap handler not firing\n\nMake sure you're using `manager.tapEvents(onTap: ...)` — `addOnPointAnnotationClickListener` is deprecated. Also confirm the `MapboxMap` controller is captured via `onMapCreated` before you create the annotation manager.\n\n### Hot reload after permissions change\n\niOS/Android will not re-read manifests or Info.plist on hot reload. Fully restart the app after editing permissions.\n\n---\n\n## Reference Files\n\n- **`references/annotations.md`** — Circle, Polyline, Polygon patterns and GeoJSON source/layer recipes.\n- **`references/platform-setup.md`** — Deeper iOS/Android setup, token strategies, release signing notes.\n\n---\n\n## Additional Resources\n\n- [Flutter Maps Guides](https://docs.mapbox.com/flutter/maps/guides/)\n- [Markers and Annotations guide](https://docs.mapbox.com/flutter/maps/guides/markers-and-annotations/)\n- [User Location guide](https://docs.mapbox.com/flutter/maps/guides/user-location/)\n- [Example App](https://github.com/mapbox/mapbox-maps-flutter/tree/main/example)\n"
}SHA-256: 42cbc4c479294302b8e7b0c222b0948c144b3eba55e30532a26e6fa767d11b57