Sitemap

How to Use Google Maps in Flutter for Both Mobile and Web

4 min readFeb 25, 2026

--

Maps are one of the most common features in modern apps — from delivery trackers and social check-ins to location search and navigation. Flutter supports Google Maps on Android and iOS through official plugins, but supporting web alongside mobile requires a bit more setup. In this article, you’ll learn how to integrate Google Maps into a Flutter app that runs seamlessly on mobile and web.

Why This Is Tricky

Flutter’s mapping ecosystem is split between:

  • google_maps_flutter — official plugin for Android & iOS
  • google_maps_flutter_web — official plugin that enables map support on Flutter web

While the two are designed to work together, there isn’t a single widget that magically renders the right map for every platform without a little configuration. The solution is to conditionally import and use different Google Maps implementations depending on the platform.

What You’ll Build

By the end of this article, you’ll be able to:

Get Ngeno Gilbert’s stories in your inbox

Join Medium for free to get updates from this writer.

✔ Show a Google Map on Android & iOS
✔ Show a Google Map on Flutter web
✔ Use the same widget in your UI for all platforms
✔ Handle conditional imports cleanly and safely
✔ Support markers and camera positioning

Architecture Overview

Here’s how the implementation works:

lib/
├─ widgets/
│ ├─ map_widget.dart
│ ├─ web_map_widget.dart
│ ├─ mobile_map_widget.dart
│ └─ map_widget_stub.dart

We use conditional imports so that Flutter knows at compile time which version to use.

Step 1 — Add Dependencies

First, add the required packages in your pubspec.yaml:

dependencies:
flutter:
sdk: flutter
google_maps_flutter: ^latest
google_maps_flutter_web: ^latest

The google_maps_flutter package works on Android and iOS, and google_maps_flutter_web enables web support.

Step 2 — Create the Main Map Widget

Create a file named map_widget.dart in your widgets/ folder:

import 'package:flutter/material.dart';
import 'map_widget_stub.dart'
if (dart.library.html) 'web_map_widget.dart'
if (dart.library.io) 'mobile_map_widget.dart';
abstract class MapWidget extends StatefulWidget {
factory MapWidget() => getMapWidget();
}

This file uses Dart conditional imports so we provide platform-specific implementations:

  • web_map_widget.dart for web
  • mobile_map_widget.dart for mobile
  • map_widget_stub.dart as a fallback

Flutter chooses which one to compile depending on where your code runs.

Step 3 — Create the Web Map Widget

Create web_map_widget.dart:

import 'dart:html';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:google_maps/google_maps.dart';
import 'map_widget.dart';

MapWidget getMapWidget() => WebMap();
class WebMap extends StatefulWidget implements MapWidget {
@override
State<WebMap> createState() => WebMapState();
}
class WebMapState extends State<WebMap> {
@override
Widget build(BuildContext context) {
final String htmlId = "map";
// Register a DOM element
ui.platformViewRegistry.registerViewFactory(htmlId, (int viewId) {
final mapOptions = MapOptions()
..zoom = 12
..center = LatLng(37.7749, -122.4194);
final elem = DivElement()..id = htmlId;
final map = GMap(elem, mapOptions);
Marker(MarkerOptions()
..position = map.center
..map = map);
return elem;
});
return HtmlElementView(viewType: htmlId);
}
}

Key Notes

  • On web, Google Maps is rendered using the JavaScript Maps SDK, not a native widget.
  • You register an HTML element and embed it into Flutter using HtmlElementView.

Step 4 — Create the Mobile Map Widget

Create mobile_map_widget.dart:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'map_widget.dart';

MapWidget getMapWidget() => MobileMap();
class MobileMap extends StatefulWidget implements MapWidget {
@override
State<MobileMap> createState() => MobileMapState();
}
class MobileMapState extends State<MobileMap> {
final Completer<GoogleMapController> _controller = Completer();
static const CameraPosition _initialPosition = CameraPosition(
target: LatLng(37.7749, -122.4194),
zoom: 12,
);
@override
Widget build(BuildContext context) {
return GoogleMap(
initialCameraPosition: _initialPosition,
onMapCreated: (controller) {
_controller.complete(controller);
},
markers: {
Marker(
markerId: const MarkerId("center"),
position: _initialPosition.target,
)
},
);
}
}

Notes

  • google_maps_flutter gives you the full mobile API — camera control, markers, gestures, and more.
  • Use GoogleMapController for programmatic control.

Step 5 — Add a Fallback Stub

Create a stub (map_widget_stub.dart) for platforms where Google Maps isn’t supported:

import 'map_widget.dart';
MapWidget getMapWidget() => throw UnsupportedError("Platform not supported");

Step 6 — Use the Unified Widget

Once everything is set up, you can use the map anywhere:

Scaffold(
appBar: AppBar(title: Text("Universal Google Map")),
body: Center(
child: SizedBox(
width: double.infinity,
height: 400,
child: MapWidget(),
),
),
)

No platform checks in the UI — just one unified MapWidget().

Don’t Forget: Web API Key

For web, you need to add your Google Maps JavaScript API key to web/index.html:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>

Without this, the map won’t load on web, even if the app compiles correctly.

Tips & Best Practices

Android & iOS

  • Add your Android and iOS API keys in the platform config files (AndroidManifest.xml, AppDelegate.swift, etc.)
  • Set the correct permissions for location usage.

Web

  • Make sure your Maps JavaScript API is enabled in the Google Cloud Console.
  • Enable billing — Maps usage requires an active billing account.

Markers & Features

You can extend both implementations to support:

  • Custom markers
  • Polylines
  • User location tracking
  • Camera animation

Just remember: the API shapes are different on web vs mobile, so handle shared data carefully.

--

--

Ngeno Gilbert
Ngeno Gilbert

Written by Ngeno Gilbert

Implementation Engineer and tech enthusiast who writes about backend systems, cloud infrastructure, and developer growth. Java, Spring Boot, and DevOps tech.