BlazorGoogleMaps 4.16.0

BlazorGoogleMaps

🗺️ Blazor interop for Google Maps JavaScript API

NuGet version (BlazorGoogleMaps) .NET 10

A powerful and easy-to-use Blazor library for integrating Google Maps into your Blazor WebAssembly and Blazor Server applications.


📑 Table of Contents


✨ Features

  • 🎯 Full Google Maps API Support - Markers, Polylines, Polygons, Circles, Info Windows, and more
  • 🚀 Blazor WebAssembly & Server - Works seamlessly with both hosting models
  • 🎨 Advanced Markers - Render Blazor components directly on the map
  • 📍 Marker Clustering - Built-in support for marker clustering
  • 🔥 Heat Maps - Visualize data density with heat map layers
  • 🛣️ Directions & Routes - Full support for directions and route rendering
  • 🎭 Map Styling - Customize map appearance with style options
  • 📊 Data Layers - Support for GeoJSON and other data formats
  • Event Handling - Comprehensive event support for interactive maps
  • 🎨 Drawing Tools - Built-in drawing manager for shapes and overlays
  • 🖼️ Static Maps - Render maps as plain images, with no JavaScript involved

📋 Prerequisites

  • .NET 8.0 or higher
  • A valid Google Maps API key (Get one here)

📦 Installation

Install the package via NuGet Package Manager:

dotnet add package BlazorGoogleMaps

Or via NuGet Package Manager Console:

Install-Package BlazorGoogleMaps

🚀 Quick Start

Step 1: Configure Your API Key

Add BlazorGoogleMaps to your Program.cs:

builder.Services.AddBlazorGoogleMaps("YOUR_GOOGLE_API_KEY");

Option 2: Advanced Configuration

builder.Services.AddBlazorGoogleMaps(new GoogleMapsComponents.Maps.MapApiLoadOptions("YOUR_GOOGLE_API_KEY")
{
	Version = "beta",
	Libraries = "places,visualization,drawing,marker"
});

Option 3: Custom Key Service

For more complex scenarios (e.g., loading keys asynchronously from a database):

builder.Services.AddScoped<IBlazorGoogleMapsKeyService, YourCustomKeyService>();

⚠️ Legacy Method (Not Recommended): Adding the script tag directly to your HTML is still supported but not recommended.


Step 2: Add JavaScript References

Add the required JavaScript files to your wwwroot/index.html (Blazor WASM) or _Host.cshtml/_HostLayout.cshtml (Blazor Server):

<script src="_content/BlazorGoogleMaps/js/objectManager.js"></script>

Optional: For marker clustering support, add:

<script src="https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"></script>

💡 Usage Examples

Basic Map

Create a simple map component:

@page "/map"
@using GoogleMapsComponents
@using GoogleMapsComponents.Maps

<h1>Google Map</h1>
<div style="height: 500px;">
	<GoogleMap @ref="@_map1" 
			   Id="map1" 
			   Options="@_mapOptions" 
			   Height="100%" 
			   OnAfterInit="@AfterMapRender">
	</GoogleMap>
</div>

@code {
	private GoogleMap? _map1;
	private MapOptions _mapOptions = default!;

	protected override void OnInitialized()
	{
		_mapOptions = new MapOptions()
		{
			Zoom = 13,
			Center = new LatLngLiteral()
			{
				Lat = 13.505892,
				Lng = 100.8162
			},
			MapTypeId = MapTypeId.Roadmap
		};
	}

	private async Task AfterMapRender()
	{
		// Map is ready - you can perform additional initialization here
		var bounds = await LatLngBounds.CreateAsync(_map1!.JsRuntime);
	}
}

Advanced Map with Blazor Components

Render interactive Blazor components as markers (requires Google Maps v=beta and a MapId):

@page "/advanced-map"
@using GoogleMapsComponents
@using GoogleMapsComponents.Maps

<h1>Advanced Map with Blazor Markers</h1>
<AdvancedGoogleMap @ref="@_map1" Id="map1" Options="@_mapOptions">
	@foreach (var marker in Markers)
	{
		<MarkerComponent 
			@key="marker.Id" 
			Lat="@marker.Lat" 
			Lng="@marker.Lng" 
			Clickable="@marker.Clickable" 
			Draggable="@marker.Draggable" 
			OnClick="@(() => marker.Active = !marker.Active)"
			OnMove="@(pos => marker.UpdatePosition(pos))">
			<div class="custom-marker">
				<h4>@marker.Title</h4>
				<p>Custom Blazor Content</p>
			</div>
		</MarkerComponent>
	}
</AdvancedGoogleMap>

@code {
	private AdvancedGoogleMap? _map1;
	private List<MarkerData> Markers = 
	[
		new MarkerData { Id = 1, Lat = 13.505892, Lng = 100.8162, Title = "Location 1" }
	];

	private MapOptions _mapOptions = new()
	{
		Zoom = 13,
		Center = new LatLngLiteral()
		{
			Lat = 13.505892,
			Lng = 100.8162
		},
		MapId = "DEMO_MAP_ID", // Required for advanced markers
		MapTypeId = MapTypeId.Roadmap
	};

	public class MarkerData
	{
		public int Id { get; set; }
		public string Title { get; set; } = string.Empty;
		public double Lat { get; set; }
		public double Lng { get; set; }
		public bool Clickable { get; set; } = true;
		public bool Draggable { get; set; }
		public bool Active { get; set; }

		public void UpdatePosition(LatLngLiteral position)
		{
			Lat = position.Lat;
			Lng = position.Lng;
		}
	}
}

Static Maps

The Maps Static API returns a map as an ordinary image. No JavaScript is loaded and no interop object is created, which makes it a good fit for thumbnails, previews, e-mails, print views and pages that must stay lightweight. The trade-off is that the result is a picture: it cannot be panned or zoomed.

@page "/static-map"
@using GoogleMapsComponents.Maps
@using GoogleMapsComponents.Maps.StaticMaps

<StaticMap Options="@_options" Alt="Map of Bangkok" class="border" />

@code {
	private StaticMapOptions _options = new()
	{
		Center = new LatLngLiteral(13.505892, 100.8162),
		Zoom = 13,
		Width = 600,
		Height = 400,
		MapType = MapTypeId.Roadmap
	};
}

Markers, paths and polygons are added through the options. Locations accept either coordinates or a geocodable address, and locations that share a style belong in a single StaticMapMarker so that the URL stays short:

var options = new StaticMapOptions
{
	Width = 600,
	Height = 400,
	Markers =
	[
		new StaticMapMarker(new LatLngLiteral(13.7563, 100.5018), new LatLngLiteral(13.7367, 100.5232))
		{
			Color = StaticMapColors.Blue,
			Size = StaticMapMarkerSize.Mid
		},
		new StaticMapMarker("Don Mueang International Airport, Bangkok") { Label = 'A' }
	],
	Paths =
	[
		// Encode = true compresses the points, which matters because a request URL is limited to 16384 characters.
		new StaticMapPath(routePoints) { Encode = true, Color = "#0000FF", Weight = 4 },

		// A path with a FillColor becomes a polygon; the API closes it for you.
		new StaticMapPath(areaPoints) { Color = "0x00000000", FillColor = "0xFF000033" }
	],
	// Built with the same GoogleMapStyleBuilder as an interactive map.
	Styles = new GoogleMapStyleBuilder()
		.AddColor(MapStyleFeatures.Water, MapStyleElements.Geometry, "#1d2c4d")
		.AddVisibility(MapStyleFeatures.Poi, MapStyleElements.Labels, false)
		.Build()
};

To build a URL outside of a component — to embed a map in an e-mail, a PDF or a report — inject StaticMapService, which is registered by AddBlazorGoogleMaps and uses the same API key as the rest of the library:

@inject StaticMapService StaticMaps

var url = await StaticMaps.GetUrlAsync(options);

EncodedPolyline accepts an already encoded polyline, so the OverviewPolyline of a route returned by the Directions API can be drawn on a static map directly. PolylineEncoder encodes and decodes those values.

Requests may optionally be signed. Signing needs the URL signing secret, which must never be shipped to a browser, so StaticMapUrlSigner.Sign and StaticMapService.GetSignedUrlAsync belong in server-side code only.


🎮 Live Demos

Explore interactive examples and learn more features:

The server-side demos include the most up-to-date examples covering:

  • Markers and Info Windows
  • Polylines, Polygons, and Circles
  • Heat Maps and Data Layers
  • Drawing Manager
  • Routes and Directions
  • Event Handling
  • Map Styling
  • And much more!

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.


📄 License

This project is licensed under the MIT License.


🙏 Acknowledgments

  • Built with ❤️ for the Blazor community
  • Powered by the Google Maps JavaScript API

Happy Mapping! 🗺️

No packages depend on BlazorGoogleMaps.

Version Downloads Last updated
4.16.0 1 08/16/2026
4.15.2 0 06/13/2026
4.15.1 3 03/01/2026
4.15.0 4 02/19/2026
4.14.1 5 01/15/2026
4.14.0 6 11/30/2025
4.13.8 10 11/24/2025
4.13.7 7 11/23/2025
4.13.6 12 08/14/2025
4.13.5 14 08/01/2025
4.13.4 17 08/01/2025
4.13.3 12 08/01/2025
4.13.2 13 07/29/2025
4.13.1 17 08/01/2025
4.13.0 16 06/30/2025
4.12.2 13 06/29/2025
4.12.1 21 06/28/2025
4.12.0 16 06/28/2025
4.11.3 20 06/28/2025
4.11.2 14 06/29/2025
4.11.1 16 06/29/2025
4.11.0 19 06/28/2025
4.10.1 15 06/29/2025
4.10.0 13 06/29/2025
4.9.5 17 06/28/2025
4.9.4 14 06/28/2025
4.9.3 12 03/07/2025
4.9.2 18 03/07/2025
4.9.1 15 03/07/2025
4.9.0 17 03/07/2025
4.8.0 19 03/07/2025
4.7.15 13 03/07/2025
4.7.14 14 03/07/2025
4.7.13 14 03/07/2025
4.7.12 18 03/07/2025
4.7.11 14 03/07/2025
4.7.10 14 03/07/2025
4.7.9 18 03/07/2025
4.7.8 18 03/07/2025
4.7.7 18 03/07/2025
4.7.6 16 03/07/2025
4.7.5 15 03/07/2025
4.7.4 13 03/07/2025
4.7.3 14 03/07/2025
4.7.2 19 03/07/2025
4.7.1 16 03/07/2025
4.7.0 15 03/07/2025
4.6.2 18 03/07/2025
4.6.1 16 03/07/2025
4.6.0 17 03/07/2025
4.5.0 15 03/07/2025
4.4.2 16 03/07/2025
4.4.1 17 03/07/2025
4.4.0 14 03/07/2025
4.3.0 15 03/07/2025
4.2.0 14 03/07/2025
4.1.2 17 03/07/2025
4.1.1 17 03/07/2025
4.1.0 14 03/07/2025
4.0.3 17 03/07/2025
4.0.2 16 03/07/2025
4.0.1 16 03/07/2025
4.0.0 16 03/07/2025
3.3.2 12 03/07/2025
3.3.1 20 03/07/2025
3.2.5 18 03/07/2025
3.2.4 15 03/07/2025
3.2.3 14 03/07/2025
3.2.2 19 03/07/2025
3.2.1 16 03/07/2025
3.2.0 14 03/07/2025
3.1.4 17 03/07/2025
3.1.3 14 03/07/2025
3.1.2 18 03/07/2025
3.1.1 15 03/07/2025
3.1.0 18 03/07/2025
3.0.8 16 03/07/2025
3.0.7 16 03/07/2025
3.0.6 15 03/07/2025
3.0.5 17 03/07/2025
3.0.4 17 03/07/2025
3.0.3 23 03/07/2025
3.0.2 19 03/07/2025
3.0.1 13 03/07/2025
3.0.0 17 03/07/2025
2.5.7 19 03/07/2025
2.5.6 16 03/07/2025
2.5.5 13 03/07/2025
2.5.4 16 03/07/2025
2.5.3 16 03/07/2025
2.5.2 20 06/25/2023
2.5.1 13 03/07/2025
2.4.4 16 03/07/2025
2.4.3 11 03/07/2025
2.4.2 17 03/07/2025
2.4.1 12 03/07/2025
2.3.1 21 03/07/2025
2.2.6 13 03/07/2025
2.2.5 14 03/07/2025
2.2.4 19 03/07/2025
2.2.3 17 03/07/2025
2.2.2 14 03/07/2025
2.2.1 16 03/07/2025
2.2.0 15 03/07/2025
2.1.1 18 03/07/2025
2.1.0 16 03/07/2025
2.0.6 18 03/07/2025
2.0.5 15 03/07/2025
2.0.4 15 03/07/2025
2.0.3 13 03/07/2025
2.0.2 19 03/07/2025
2.0.1 18 03/07/2025
2.0.0 21 03/07/2025
1.5.5 25 03/07/2025
1.5.4 16 03/07/2025
1.5.3 12 10/30/2023
1.5.2 11 03/07/2025
1.5.1 16 03/07/2025
1.4.2 15 03/07/2025
1.4.1 17 03/07/2025
1.4.0 16 03/07/2025
1.3.0 17 03/07/2025
1.2.1 18 03/07/2025
1.1.8 19 10/19/2023
1.1.7 16 03/07/2025
1.1.6 17 03/07/2025
1.1.5 15 03/07/2025
1.1.4 13 03/07/2025
1.1.3 15 10/21/2023
1.1.2 16 03/07/2025
1.1.1 16 03/07/2025
1.0.17 14 03/07/2025
1.0.16 15 03/07/2025
1.0.15 22 03/07/2025
1.0.14 16 03/07/2025
1.0.13 17 03/07/2025
1.0.12 20 03/07/2025
1.0.11 24 03/07/2025
1.0.10 17 03/07/2025
1.0.9 17 03/07/2025
1.0.8 19 03/07/2025
1.0.7 17 03/07/2025
1.0.6 19 03/07/2025
1.0.5 16 03/07/2025
1.0.4 13 03/07/2025
1.0.3 16 03/07/2025
1.0.2 18 03/07/2025
1.0.1 17 03/07/2025
1.0.0 15 03/07/2025
0.9.3 13 03/07/2025
0.9.2 20 03/07/2025
0.9.1 15 03/07/2025
0.9.0 17 10/28/2023
0.8.1 13 03/07/2025
0.8.0 16 03/07/2025
0.7.1 16 03/07/2025
0.6.14 9 03/07/2025
0.6.13 15 03/07/2025
0.6.12 14 03/07/2025
0.6.11 16 11/10/2023
0.6.10 17 03/07/2025
0.6.9 16 03/07/2025
0.6.8 13 03/07/2025
0.6.7 12 03/07/2025
0.6.6 16 11/03/2023
0.6.5 14 03/07/2025
0.6.4 16 03/07/2025
0.6.3 15 03/07/2025
0.6.2 14 03/07/2025
0.6.1 17 03/07/2025
0.6.0 14 03/07/2025
0.5.9 17 03/07/2025
0.5.8 18 03/07/2025
0.5.7 17 03/07/2025
0.5.6 17 03/07/2025
0.5.5 15 03/07/2025
0.5.4 16 03/07/2025
0.5.3 16 03/07/2025
0.5.2 14 03/07/2025
0.5.1-alpha 13 03/07/2025
0.4.8-alpha 20 03/07/2025
0.4.7-alpha 16 03/07/2025
0.4.6-alpha 16 03/07/2025
0.4.5-alpha 15 03/07/2025
0.4.0-alpha 16 03/07/2025
0.3.0 15 10/26/2023
0.1.0 20 03/07/2025