This example demonstrates the use of click event listeners on POIs (points of
interest). It listens for the [`click`](https://developers.google.com/maps/documentation/javascript/reference/event.md.txt#MapsEventListener)
event on the basemap, and shows an info window if a place ID is present in the
event. The click event listener uses `event.stop()` to prevent the default POI
info window from showing.

Read the [documentation](https://developers.google.com/maps/documentation/javascript/events.md.txt).
<iframe src="https://maps-docs-team.web.app/samples/event-poi/dist/" allow="fullscreen; "></iframe>

### TypeScript

```typescript
let innerMap: google.maps.Map;

async function init() {
    //  Request the needed libraries.
    void google.maps.importLibrary('core'); // preload
    const { InfoWindow } = await google.maps.importLibrary('maps');

    // Retrieve the map element.
    const mapElement = document.querySelector('gmp-map')!;

    // Get the inner map from the map element.
    innerMap = mapElement.innerMap;

    // Create the initial info window.
    const infoWindow = new InfoWindow();

    // Add a listener for click events on the map.
    innerMap.addListener(
        'click',
        (event: google.maps.MapMouseEvent | google.maps.IconMouseEvent) => {
            // Prevent the default POI info window from showing.
            event.stop();

            // If the event has a placeId, show the info window.
            if (isIconMouseEvent(event) && event.placeId) {
                void showInfoWindow(event, infoWindow);
            } else {
                // Close the info window if there is no placeId.
                infoWindow.close();
            }
        }
    );
}

// Helper function to show the info window.
async function showInfoWindow(
    event: google.maps.IconMouseEvent,
    infoWindow: google.maps.InfoWindow
) {
    if (!event.placeId) return;

    const { Size } = await google.maps.importLibrary('core');

    // Retrieve the place details for the selected POI.
    const place = await getPlaceDetails(event.placeId);

    // Assemble the info window content.
    const content = document.createElement('div');
    const address = document.createElement('div');
    const placeId = document.createElement('div');
    address.textContent = place.formattedAddress || '';
    placeId.textContent = place.id || '';
    content.append(address, placeId);

    // Create an element to use the place name as header content.
    const name = document.createElement('div');
    name.style.fontWeight = 'bold';
    name.style.fontSize = 'medium';
    name.textContent = place.displayName || '';

    // Update info window options.
    infoWindow.setOptions({
        position: event.latLng,
        pixelOffset: new Size(0, -30),
        headerContent: name,
        content,
    });

    innerMap.panTo(event.latLng!);
    infoWindow.open(innerMap);
}

// Helper function to get place details.
async function getPlaceDetails(placeId: string) {
    // Import the Places library.
    const { Place } = await google.maps.importLibrary('places');

    // Create a Place instance with the place id and fetch the details.
    const place = new Place({ id: placeId });
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });

    // Return the place details.
    return place;
}

// Helper type guard to determine if the event is an IconMouseEvent.
function isIconMouseEvent(
    e: google.maps.MapMouseEvent | google.maps.IconMouseEvent
): e is google.maps.IconMouseEvent {
    return 'placeId' in e;
}

void init();
```

### JavaScript

```javascript
let innerMap;

async function init() {
    //  Request the needed libraries.
    void google.maps.importLibrary('core'); // preload
    const { InfoWindow } = await google.maps.importLibrary('maps');

    // Retrieve the map element.
    const mapElement = document.querySelector('gmp-map');

    // Get the inner map from the map element.
    innerMap = mapElement.innerMap;

    // Create the initial info window.
    const infoWindow = new InfoWindow();

    // Add a listener for click events on the map.
    innerMap.addListener('click', (event) => {
        // Prevent the default POI info window from showing.
        event.stop();

        // If the event has a placeId, show the info window.
        if (isIconMouseEvent(event) && event.placeId) {
            void showInfoWindow(event, infoWindow);
        } else {
            // Close the info window if there is no placeId.
            infoWindow.close();
        }
    });
}

// Helper function to show the info window.
async function showInfoWindow(event, infoWindow) {
    if (!event.placeId) return;

    const { Size } = await google.maps.importLibrary('core');

    // Retrieve the place details for the selected POI.
    const place = await getPlaceDetails(event.placeId);

    // Assemble the info window content.
    const content = document.createElement('div');
    const address = document.createElement('div');
    const placeId = document.createElement('div');
    address.textContent = place.formattedAddress || '';
    placeId.textContent = place.id || '';
    content.append(address, placeId);

    // Create an element to use the place name as header content.
    const name = document.createElement('div');
    name.style.fontWeight = 'bold';
    name.style.fontSize = 'medium';
    name.textContent = place.displayName || '';

    // Update info window options.
    infoWindow.setOptions({
        position: event.latLng,
        pixelOffset: new Size(0, -30),
        headerContent: name,
        content,
    });

    innerMap.panTo(event.latLng);
    infoWindow.open(innerMap);
}

// Helper function to get place details.
async function getPlaceDetails(placeId) {
    // Import the Places library.
    const { Place } = await google.maps.importLibrary('places');

    // Create a Place instance with the place id and fetch the details.
    const place = new Place({ id: placeId });
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });

    // Return the place details.
    return place;
}

// Helper type guard to determine if the event is an IconMouseEvent.
function isIconMouseEvent(e) {
    return 'placeId' in e;
}

void init();
```

### CSS

```css
/* Optional: Makes the sample page fill the window. */
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

.title {
    font-weight: bold;
}
```

### HTML

```html
<html>
    <head>
        <title>POI Click Events</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <script>
            // prettier-ignore
            (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: "GOOGLE_MAPS_API_KEY"
            });
        </script>
    </head>
    <body>
        <gmp-map center="-33.871, 151.197" zoom="18"> </gmp-map>
    </body>
</html>
```

### Try Sample

[JSFiddle.net](https://jsfiddle.net/gh/get/library/pure/googlemaps-samples/js-api-samples/tree/main/dist/samples/event-poi/jsfiddle)

### Clone Sample


Git and Node.js are required to run this sample locally. Follow these [instructions](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
to install Node.js and NPM. You will also need a [Google Maps API key](https://developers.google.com/maps/documentation/javascript/get-api-key.md.txt).


The following commands clone the repository, install dependencies, and copy the environment file.

```javascript
  git clone https://github.com/googlemaps-samples/js-api-samples.git
  cd js-api-samples
  npm i
  cp .env.template .env
```


Once you copy the environment file, make sure to open the `.env` file and replace `<Insert your own development API key here>` with your actual API key before starting the sample.

```javascript
  cd samples/event-poi
  npm start
```