Web Components are a popular W3C standard that encapsulate HTML, CSS, and JS in
custom and reusable HTML elements. These reusable components can range from
atomic pieces of functionality, like displaying the star rating for a place, to
more complex business logic. This guide describes Web Components available in
Maps JavaScript API.
For more information about the standard itself, see
Web Components
.
Audience
This documentation is designed to let you quickly start exploring and developing
applications with Web Components. You should be familiar with HTML
and CSS programming concepts.
Display a Map
The easiest way to start learning about Web Components is to see
an example. The following example displays a map of the San Jose area.
TypeScript
// This example adds a map using web components.
async function initMap(): Promise<void> {
const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;
console.log('Maps JavaScript API loaded.');
}
initMap();
JavaScript
// This example adds a map using web components.
async function initMap() {
const { Map } = await google.maps.importLibrary("maps");
console.log("Maps JavaScript API loaded.");
}
initMap();
CSS
/*
* Always set the map height explicitly to define the size of the div element
* that contains the map.
*/
#map {
height: 100%;
}
/*
* Optional: Makes the sample page fill the window.
*/
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
gmp-map {
height: 400px;
}
HTML
<html>
<head>
<title>Add a Map Web Component</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
</head>
<body>
<gmp-map
center="37.4220656,-122.0840897"
zoom="10"
map-id="DEMO_MAP_ID"
></gmp-map>
<!-- prettier-ignore -->
<script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "beta"});</script>
</body>
</html>
Try Sample
In this example there are a few things to note:
- The
Maps JavaScript API
is called asynchronously. The callback function is used to know when the API has
loaded.
- Presentation of the map is defined with the
<gmp-map>
custom element.
- Map properties are defined by specifying attributes in the
<gmp-map>
custom element.
- Styling can be applied inline to custom elements or declared in a separate CSS file.
Style the basemap
A map ID is an identifier associated with a specific map style or
feature. To take advantage of optional cloud configuration features, replace the
cloud-based maps styling
DEMO_MAP_ID
with your own map ID.
To learn how to create a map ID and configure a custom style,
visit
Cloud-based Maps Styling
.
Add markers to the map
Just as one can nest built-in HTML tags to create complex content hierarchies,
one can also nest
<gmp-advanced-marker>
inside an element to display one or more map markers.
TypeScript
// This example adds a map with markers, using web components.
async function initMap(): Promise<void> {
const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;
const { AdvancedMarkerElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary;
console.log('Maps JavaScript API loaded.');
}
initMap();
JavaScript
// This example adds a map with markers, using web components.
async function initMap() {
const { Map } = await google.maps.importLibrary("maps");
const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
console.log("Maps JavaScript API loaded.");
}
initMap();
CSS
/*
* Always set the map height explicitly to define the size of the div element
* that contains the map.
*/
#map {
height: 100%;
}
/*
* Optional: Makes the sample page fill the window.
*/
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
gmp-map {
height: 400px;
}
HTML
<html>
<head>
<title>Add a Map with Markers using Web Components</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
</head>
<body>
<gmp-map center="43.4142989,-124.2301242" zoom="4" map-id="DEMO_MAP_ID">
<gmp-advanced-marker
position="37.4220656,-122.0840897"
title="Mountain View, CA"
></gmp-advanced-marker>
<gmp-advanced-marker
position="47.648994,-122.3503845"
title="Seattle, WA"
></gmp-advanced-marker>
</gmp-map>
<!-- prettier-ignore -->
<script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "beta"});</script>
</body>
</html>
Try Sample
Here we've added two
<gmp-advanced-marker>
elements inside
the
<gmp-map>
custom element. Text for
title
provides an additional hover text and accessibility label for the specified
element.
JavaScript Events
A major benefit of Web Components is ease of use. With a few lines
of code, one can display a Map with limited knowledge of JavaScript or advanced
programming. Once implemented, the code follows the familiar patterns of other
HTML elements. For example, one can use the native browser eventing system to
react to Map or Advanced Marker actions, such as a marker click.
In your HTML, set the
gmp-clickable
attribute on the
gmp-advanced-marker
element to make a marker clickable. Use
advancedMarker.addEventListener
to
handle click events.
TypeScript
// This example adds a map using web components.
async function initMap(): Promise<void> {
const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;
const { AdvancedMarkerElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary;
console.log('Maps JavaScript API loaded.');
const advancedMarkers = document.querySelectorAll("#marker-click-event-example gmp-advanced-marker");
for (const advancedMarker of advancedMarkers) {
customElements.whenDefined(advancedMarker.localName).then(async () => {
advancedMarker.addEventListener('gmp-click', async () => {
const infoWindow = new google.maps.InfoWindow({
//@ts-ignore
content: advancedMarker.title,
});
infoWindow.open({
//@ts-ignore
anchor: advancedMarker
});
});
});
}
}
initMap();
JavaScript
// This example adds a map using web components.
async function initMap() {
const { Map } = await google.maps.importLibrary("maps");
const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
console.log("Maps JavaScript API loaded.");
const advancedMarkers = document.querySelectorAll(
"#marker-click-event-example gmp-advanced-marker",
);
for (const advancedMarker of advancedMarkers) {
customElements.whenDefined(advancedMarker.localName).then(async () => {
advancedMarker.addEventListener("gmp-click", async () => {
const infoWindow = new google.maps.InfoWindow({
//@ts-ignore
content: advancedMarker.title,
});
infoWindow.open({
//@ts-ignore
anchor: advancedMarker,
});
});
});
}
}
initMap();
CSS
/*
* Always set the map height explicitly to define the size of the div element
* that contains the map.
*/
#map {
height: 100%;
}
/*
* Optional: Makes the sample page fill the window.
*/
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
gmp-map {
height: 400px;
}
HTML
<html>
<head>
<title>Add a Map Web Component with Events</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
</head>
<body>
<gmp-map
id="marker-click-event-example"
center="43.4142989,-124.2301242"
zoom="4"
map-id="DEMO_MAP_ID"
>
<gmp-advanced-marker
position="37.4220656,-122.0840897"
title="Mountain View, CA"
gmp-clickable
></gmp-advanced-marker>
<gmp-advanced-marker
position="47.648994,-122.3503845"
title="Seattle, WA"
gmp-clickable
></gmp-advanced-marker>
</gmp-map>
<!-- prettier-ignore -->
<script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "beta"});</script>
</body>
</html>
Try Sample
In this example,
initMap
represents the required
callback function
once
the Maps JavaScript API loads completely. The code
establishes listeners to each marker and presents an info window when each
marker is clicked.
What's next