UI Kit Place Search Nearby

This example renders the Place Search element in response to a nearby search with a user-selected place type, and displays a Place Details Compact Element for the selected place. Read the documentation .

TypeScript

 // Query selectors for various elements in the HTML file. 
 const 
  
 map 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-map' 
 ) 
  
 as 
  
 google 
 . 
 maps 
 . 
 MapElement 
 ; 
 const 
  
 placeSearch 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-place-search' 
 ) 
  
 as 
  
 any 
 ; 
 const 
  
 placeSearchQuery 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
  
 'gmp-place-nearby-search-request' 
 ) 
  
 as 
  
 any 
 ; 
 const 
  
 placeDetails 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-place-details-compact' 
 ) 
  
 as 
  
 any 
 ; 
 const 
  
 placeRequest 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
  
 'gmp-place-details-place-request' 
 ) 
  
 as 
  
 any 
 ; 
 const 
  
 typeSelect 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 '.type-select' 
 ) 
  
 as 
  
 HTMLSelectElement 
 ; 
 // Global variables for the map, markers, and info window. 
 const 
  
 markers 
 : 
  
 Map<string 
 , 
  
 google 
 . 
 maps 
 . 
 marker 
 . 
 AdvancedMarkerElement 
>  
 = 
  
 new 
  
 Map 
 (); 
 let 
  
 infoWindow 
 : 
  
 google.maps.InfoWindow 
 ; 
 // The init function is called when the page loads. 
 async 
  
 function 
  
 init 
 () 
 : 
  
 Promise<void> 
  
 { 
  
 // Import the necessary libraries from the Google Maps API. 
  
 const 
  
 [{ 
  
 InfoWindow 
  
 }, 
  
 { 
  
 Place 
  
 }] 
  
 = 
  
 await 
  
 Promise 
 . 
 all 
 ([ 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'maps' 
 ) 
  
 as 
  
 Promise<google 
 . 
 maps 
 . 
 MapsLibrary 
> , 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
  
 'places' 
  
 ) 
  
 as 
  
 Promise<google 
 . 
 maps 
 . 
 PlacesLibrary 
> , 
  
 ]); 
  
 // Create a new info window and set its content to the place details element. 
  
 placeDetails 
 . 
 remove 
 (); 
  
 // Hide the place details element because it is not needed until the info window opens 
  
 infoWindow 
  
 = 
  
 new 
  
 InfoWindow 
 ({ 
  
 content 
 : 
  
 placeDetails 
 , 
  
 ariaLabel 
 : 
  
 'Place Details' 
 , 
  
 }); 
  
 // Set the map options. 
  
 map 
 . 
 innerMap 
 . 
 setOptions 
 ({ 
  
 clickableIcons 
 : 
  
 false 
 , 
  
 mapTypeControl 
 : 
  
 false 
 , 
  
 streetViewControl 
 : 
  
 false 
 , 
  
 }); 
  
 // Add event listeners to the type select and place search elements. 
  
 typeSelect 
 . 
 addEventListener 
 ( 
 'change' 
 , 
  
 () 
  
 = 
>  
 searchPlaces 
 ()); 
  
 placeSearch 
 . 
 addEventListener 
 ( 
 'gmp-select' 
 , 
  
 ( 
 event 
 : 
  
 Event 
 ) 
  
 = 
>  
 { 
  
 const 
  
 { 
  
 place 
  
 } 
  
 = 
  
 event 
  
 as 
  
 any 
 ; 
  
 markers 
 . 
 get 
 ( 
 place 
 . 
 id 
 ) 
 ? 
 . 
 click 
 (); 
  
 }); 
  
 placeSearch 
 . 
 addEventListener 
 ( 
 'gmp-load' 
 , 
  
 () 
  
 = 
>  
 { 
  
 addMarkers 
 (); 
  
 }); 
  
 searchPlaces 
 (); 
 } 
 // The searchPlaces function is called when the user changes the type select or when the page loads. 
 async 
  
 function 
  
 searchPlaces 
 () 
  
 { 
  
 // Close the info window and clear the markers. 
  
 infoWindow 
 . 
 close 
 (); 
  
 for 
  
 ( 
 const 
  
 marker 
  
 of 
  
 markers 
 . 
 values 
 ()) 
  
 { 
  
 marker 
 . 
 remove 
 (); 
  
 } 
  
 markers 
 . 
 clear 
 (); 
  
 // Set the place search query and add an event listener to the place search element. 
  
 if 
  
 ( 
 typeSelect 
 . 
 value 
 ) 
  
 { 
  
 const 
  
 center 
  
 = 
  
 map 
 . 
 center 
 ! 
 ; 
  
 placeSearchQuery 
 . 
 locationRestriction 
  
 = 
  
 { 
  
 center 
 , 
  
 radius 
 : 
  
 50000 
 , 
  
 // 50km radius 
  
 }; 
  
 placeSearchQuery 
 . 
 includedTypes 
  
 = 
  
 [ 
 typeSelect 
 . 
 value 
 ]; 
  
 } 
 } 
 // The addMarkers function is called when the place search element loads. 
 async 
  
 function 
  
 addMarkers 
 () 
  
 { 
  
 // Import the necessary libraries from the Google Maps API. 
  
 const 
  
 [{ 
  
 AdvancedMarkerElement 
  
 }, 
  
 { 
  
 LatLngBounds 
  
 }] 
  
 = 
  
 await 
  
 Promise 
 . 
 all 
 ([ 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
  
 'marker' 
  
 ) 
  
 as 
  
 Promise<google 
 . 
 maps 
 . 
 MarkerLibrary 
> , 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'core' 
 ) 
  
 as 
  
 Promise<google 
 . 
 maps 
 . 
 CoreLibrary 
> , 
  
 ]); 
  
 const 
  
 bounds 
  
 = 
  
 new 
  
 LatLngBounds 
 (); 
  
 if 
  
 ( 
 placeSearch 
 . 
 places 
 . 
 length 
  
 === 
  
 0 
 ) 
  
 { 
  
 return 
 ; 
  
 } 
  
 for 
  
 ( 
 const 
  
 place 
  
 of 
  
 placeSearch 
 . 
 places 
 ) 
  
 { 
  
 const 
  
 marker 
  
 = 
  
 new 
  
 AdvancedMarkerElement 
 ({ 
  
 map 
 : 
  
 map.innerMap 
 , 
  
 position 
 : 
  
 place.location 
 , 
  
 collisionBehavior 
 : 
  
 google.maps.CollisionBehavior.REQUIRED_AND_HIDES_OPTIONAL 
 , 
  
 }); 
  
 markers 
 . 
 set 
 ( 
 place 
 . 
 id 
 , 
  
 marker 
 ); 
  
 bounds 
 . 
 extend 
 ( 
 place 
 . 
 location 
 ); 
  
 marker 
 . 
 addListener 
 ( 
 'click' 
 , 
  
 () 
  
 = 
>  
 { 
  
 placeRequest 
 . 
 place 
  
 = 
  
 place 
 ; 
  
 infoWindow 
 . 
 open 
 ( 
 map 
 . 
 innerMap 
 , 
  
 marker 
 ); 
  
 }); 
  
 } 
  
 map 
 . 
 innerMap 
 . 
 fitBounds 
 ( 
 bounds 
 ); 
 } 
 init 
 (); 
  

JavaScript

 // Query selectors for various elements in the HTML file. 
 const 
  
 map 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-map' 
 ); 
 const 
  
 placeSearch 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-place-search' 
 ); 
 const 
  
 placeSearchQuery 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-place-nearby-search-request' 
 ); 
 const 
  
 placeDetails 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-place-details-compact' 
 ); 
 const 
  
 placeRequest 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-place-details-place-request' 
 ); 
 const 
  
 typeSelect 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 '.type-select' 
 ); 
 // Global variables for the map, markers, and info window. 
 const 
  
 markers 
  
 = 
  
 new 
  
 Map 
 (); 
 let 
  
 infoWindow 
 ; 
 // The init function is called when the page loads. 
 async 
  
 function 
  
 init 
 () 
  
 { 
  
 // Import the necessary libraries from the Google Maps API. 
  
 const 
  
 [{ 
  
 InfoWindow 
  
 }, 
  
 { 
  
 Place 
  
 }] 
  
 = 
  
 await 
  
 Promise 
 . 
 all 
 ([ 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'maps' 
 ), 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'places' 
 ), 
  
 ]); 
  
 // Create a new info window and set its content to the place details element. 
  
 placeDetails 
 . 
 remove 
 (); 
  
 // Hide the place details element because it is not needed until the info window opens 
  
 infoWindow 
  
 = 
  
 new 
  
 InfoWindow 
 ({ 
  
 content 
 : 
  
 placeDetails 
 , 
  
 ariaLabel 
 : 
  
 'Place Details' 
 , 
  
 }); 
  
 // Set the map options. 
  
 map 
 . 
 innerMap 
 . 
 setOptions 
 ({ 
  
 clickableIcons 
 : 
  
 false 
 , 
  
 mapTypeControl 
 : 
  
 false 
 , 
  
 streetViewControl 
 : 
  
 false 
 , 
  
 }); 
  
 // Add event listeners to the type select and place search elements. 
  
 typeSelect 
 . 
 addEventListener 
 ( 
 'change' 
 , 
  
 () 
  
 = 
>  
 searchPlaces 
 ()); 
  
 placeSearch 
 . 
 addEventListener 
 ( 
 'gmp-select' 
 , 
  
 ( 
 event 
 ) 
  
 = 
>  
 { 
  
 const 
  
 { 
  
 place 
  
 } 
  
 = 
  
 event 
 ; 
  
 markers 
 . 
 get 
 ( 
 place 
 . 
 id 
 ) 
 ? 
 . 
 click 
 (); 
  
 }); 
  
 placeSearch 
 . 
 addEventListener 
 ( 
 'gmp-load' 
 , 
  
 () 
  
 = 
>  
 { 
  
 addMarkers 
 (); 
  
 }); 
  
 searchPlaces 
 (); 
 } 
 // The searchPlaces function is called when the user changes the type select or when the page loads. 
 async 
  
 function 
  
 searchPlaces 
 () 
  
 { 
  
 // Close the info window and clear the markers. 
  
 infoWindow 
 . 
 close 
 (); 
  
 for 
  
 ( 
 const 
  
 marker 
  
 of 
  
 markers 
 . 
 values 
 ()) 
  
 { 
  
 marker 
 . 
 remove 
 (); 
  
 } 
  
 markers 
 . 
 clear 
 (); 
  
 // Set the place search query and add an event listener to the place search element. 
  
 if 
  
 ( 
 typeSelect 
 . 
 value 
 ) 
  
 { 
  
 const 
  
 center 
  
 = 
  
 map 
 . 
 center 
 ; 
  
 placeSearchQuery 
 . 
 locationRestriction 
  
 = 
  
 { 
  
 center 
 , 
  
 radius 
 : 
  
 50000 
 , 
  
 // 50km radius 
  
 }; 
  
 placeSearchQuery 
 . 
 includedTypes 
  
 = 
  
 [ 
 typeSelect 
 . 
 value 
 ]; 
  
 } 
 } 
 // The addMarkers function is called when the place search element loads. 
 async 
  
 function 
  
 addMarkers 
 () 
  
 { 
  
 // Import the necessary libraries from the Google Maps API. 
  
 const 
  
 [{ 
  
 AdvancedMarkerElement 
  
 }, 
  
 { 
  
 LatLngBounds 
  
 }] 
  
 = 
  
 await 
  
 Promise 
 . 
 all 
 ([ 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'marker' 
 ), 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'core' 
 ), 
  
 ]); 
  
 const 
  
 bounds 
  
 = 
  
 new 
  
 LatLngBounds 
 (); 
  
 if 
  
 ( 
 placeSearch 
 . 
 places 
 . 
 length 
  
 === 
  
 0 
 ) 
  
 { 
  
 return 
 ; 
  
 } 
  
 for 
  
 ( 
 const 
  
 place 
  
 of 
  
 placeSearch 
 . 
 places 
 ) 
  
 { 
  
 const 
  
 marker 
  
 = 
  
 new 
  
 AdvancedMarkerElement 
 ({ 
  
 map 
 : 
  
 map 
 . 
 innerMap 
 , 
  
 position 
 : 
  
 place 
 . 
 location 
 , 
  
 collisionBehavior 
 : 
  
 google 
 . 
 maps 
 . 
 CollisionBehavior 
 . 
 REQUIRED_AND_HIDES_OPTIONAL 
 , 
  
 }); 
  
 markers 
 . 
 set 
 ( 
 place 
 . 
 id 
 , 
  
 marker 
 ); 
  
 bounds 
 . 
 extend 
 ( 
 place 
 . 
 location 
 ); 
  
 marker 
 . 
 addListener 
 ( 
 'click' 
 , 
  
 () 
  
 = 
>  
 { 
  
 placeRequest 
 . 
 place 
  
 = 
  
 place 
 ; 
  
 infoWindow 
 . 
 open 
 ( 
 map 
 . 
 innerMap 
 , 
  
 marker 
 ); 
  
 }); 
  
 } 
  
 map 
 . 
 innerMap 
 . 
 fitBounds 
 ( 
 bounds 
 ); 
 } 
 init 
 (); 
  

CSS

 html 
 , 
 body 
  
 { 
  
 height 
 : 
  
 100 
 % 
 ; 
  
 margin 
 : 
  
 0 
 ; 
 } 
 body 
  
 { 
  
 display 
 : 
  
 flex 
 ; 
  
 flex-direction 
 : 
  
 column 
 ; 
  
 font-family 
 : 
  
 Arial 
 , 
  
 Helvetica 
 , 
  
 sans-serif 
 ; 
 } 
 . 
 container 
  
 { 
  
 display 
 : 
  
 flex 
 ; 
  
 height 
 : 
  
 100 
 vh 
 ; 
  
 width 
 : 
  
 100 
 % 
 ; 
 } 
 gmp-map 
  
 { 
  
 flex-grow 
 : 
  
 1 
 ; 
 } 
 . 
 ui-panel 
  
 { 
  
 width 
 : 
  
 400 
 px 
 ; 
  
 margin-left 
 : 
  
 20 
 px 
 ; 
  
 margin-top 
 : 
  
 10 
 px 
 ; 
  
 overflow-y 
 : 
  
 auto 
 ; 
  
 font-family 
 : 
  
 Arial 
 , 
  
 Helvetica 
 , 
  
 sans-serif 
 ; 
 } 
 . 
 list-container 
  
 { 
  
 display 
 : 
  
 flex 
 ; 
  
 flex-direction 
 : 
  
 column 
 ; 
 } 
 gmp-place-search 
  
 { 
  
 width 
 : 
  
 100 
 % 
 ; 
  
 margin 
 : 
  
 0 
 ; 
  
 border 
 : 
  
 none 
 ; 
  
 color-scheme 
 : 
  
 light 
 ; 
 } 
  

HTML

<!doctype html>
<html>
    <head>
        <title>Place Search Nearby with Google Maps</title>
        <meta charset="utf-8" />
        <link rel="stylesheet" type="text/css" href="style.css" />
        <script type="module" src="./index.js" defer></script>
        <!-- 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: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});
    </script>
    </head>
    <body>

        <div class="container">
            <!-- map-id is required to use advanced markers. See https://developers.google.com/maps/documentation/javascript/map-ids/mapid-over. -->
            <gmp-map center="-37.813,144.963" zoom="16" map-id="DEMO_MAP_ID">
            </gmp-map>
            <div class="ui-panel">
                <div class="controls">
                    <label for="type-select">
                        Select a place type:
                        <select id="type-select" class="type-select">
                            <option value="restaurant">Restaurant</option>
                            <option value="cafe" selected>Cafe</option>
                            <option value="electric_vehicle_charging_station">
                                EV charging station
                            </option>
                        </select>
                    </label>
                </div>
                <div class="list-container">
                    <gmp-place-search selectable>
                        <gmp-place-all-content></gmp-place-all-content>
                        <gmp-place-nearby-search-request
                            max-result-count="5"></gmp-place-nearby-search-request>
                    </gmp-place-search>
                </div>
            </div>
        </div>

        <!--
        The gmp-place-details-compact element is styled inline because it is
        conditionally rendered and moved into the info window, which is
        part of the map's shadow DOM.
    -->
        <gmp-place-details-compact
            orientation="horizontal"
            truncation-preferred
            style="
                width: 400px;
                padding: 0;
                margin: 0;
                border: none;
                background-color: transparent;
                color-scheme: light;
            ">
            <gmp-place-details-place-request></gmp-place-details-place-request>
            <gmp-place-content-config>
                <gmp-place-media></gmp-place-media>
                <gmp-place-rating></gmp-place-rating>
                <gmp-place-price></gmp-place-price>
                <gmp-place-accessible-entrance-icon></gmp-place-accessible-entrance-icon>
                <gmp-place-open-now-status></gmp-place-open-now-status>
                <gmp-place-attribution
                    light-scheme-color="gray"
                    dark-scheme-color="white"></gmp-place-attribution>
            </gmp-place-content-config>
        </gmp-place-details-compact>

    </body>
</html>  

Try Sample

Clone Sample

Git and Node.js are required to run this sample locally. Follow these instructions to install Node.js and NPM. The following commands clone, install dependencies and start the sample application.

  
  git 
  
 clone 
  
 https 
 : 
 //github.com/googlemaps-samples/js-api-samples.git 
 
  
  cd 
  
 samples 
 / 
 ui 
 - 
 kit 
 - 
 place 
 - 
 search 
 - 
 nearby 
 
  
  npm 
  
 i 
 
  
  npm 
  
 start 
 
Design a Mobile Site
View Site in Mobile | Classic
Share by: