diff --git a/samples/event-poi/README.md b/samples/event-poi/README.md
new file mode 100644
index 00000000..c50bfcc6
--- /dev/null
+++ b/samples/event-poi/README.md
@@ -0,0 +1,41 @@
+# Google Maps JavaScript Sample
+
+## event-poi
+
+This example demonstrates the use of click event listeners on POIs (points of interest).
+
+## Setup
+
+### Before starting run:
+
+`npm i`
+
+### Run an example on a local web server
+
+`cd samples/event-poi`
+`npm start`
+
+### Build an individual example
+
+`cd samples/event-poi`
+`npm run build`
+
+From 'samples':
+
+`npm run build --workspace=event-poi/`
+
+### Build all of the examples.
+
+From 'samples':
+
+`npm run build-all`
+
+### Run lint to check for problems
+
+`cd samples/event-poi`
+`npx eslint index.ts`
+
+## Feedback
+
+For feedback related to this sample, please open a new issue on
+[GitHub](https://github.com/googlemaps-samples/js-api-samples/issues).
diff --git a/samples/event-poi/index.html b/samples/event-poi/index.html
new file mode 100644
index 00000000..8ba42b87
--- /dev/null
+++ b/samples/event-poi/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+ POI Click Events
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/event-poi/index.ts b/samples/event-poi/index.ts
new file mode 100644
index 00000000..982fa5c7
--- /dev/null
+++ b/samples/event-poi/index.ts
@@ -0,0 +1,93 @@
+/**
+ * @license
+ * Copyright 2026 Google LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// [START maps_event_poi]
+let innerMap;
+
+async function initMap() {
+ // Request the needed libraries.
+ await google.maps.importLibrary('maps');
+
+ const mapElement = document.querySelector(
+ 'gmp-map'
+ ) as google.maps.MapElement;
+
+ innerMap = mapElement.innerMap;
+
+ // Create the initial InfoWindow.
+ let infowindow = new google.maps.InfoWindow({});
+
+ 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) {
+ showInfoWindow(event, infowindow);
+ } else {
+ // Otherwise, close the info window.
+ infowindow.close();
+ }
+ });
+}
+
+// Helper function to show the info window.
+async function showInfoWindow(event: google.maps.IconMouseEvent, infowindow: google.maps.InfoWindow) {
+ // 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 google.maps.Size(0, -30),
+ headerContent: name,
+ content: 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'
+ )) as google.maps.PlacesLibrary;
+
+ // 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;
+}
+
+initMap();
+// [END maps_event_poi]
diff --git a/samples/event-poi/package.json b/samples/event-poi/package.json
new file mode 100644
index 00000000..1f408f09
--- /dev/null
+++ b/samples/event-poi/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "@js-api-samples/event-poi",
+ "version": "1.0.0",
+ "scripts": {
+ "build": "tsc && bash ../jsfiddle.sh event-poi && bash ../app.sh event-poi && bash ../docs.sh event-poi && npm run build:vite --workspace=. && bash ../dist.sh event-poi",
+ "test": "tsc && npm run build:vite --workspace=.",
+ "start": "tsc && vite build --base './' && vite",
+ "build:vite": "vite build --base './'",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+
+ }
+}
diff --git a/samples/event-poi/style.css b/samples/event-poi/style.css
new file mode 100644
index 00000000..287de84b
--- /dev/null
+++ b/samples/event-poi/style.css
@@ -0,0 +1,20 @@
+/**
+ * @license
+ * Copyright 2026 Google LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* [START maps_event_poi] */
+
+/* Optional: Makes the sample page fill the window. */
+html,
+body {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.title {
+ font-weight: bold;
+}
+
+/* [END maps_event_poi] */
diff --git a/samples/event-poi/tsconfig.json b/samples/event-poi/tsconfig.json
new file mode 100644
index 00000000..366aabb0
--- /dev/null
+++ b/samples/event-poi/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "compilerOptions": {
+ "module": "esnext",
+ "target": "esnext",
+ "strict": true,
+ "noImplicitAny": false,
+ "lib": [
+ "es2015",
+ "esnext",
+ "es6",
+ "dom",
+ "dom.iterable"
+ ],
+ "moduleResolution": "Node",
+ "jsx": "preserve"
+ }
+}