

# Create a web app to use Amazon Location Service
<a name="qs-web"></a>

 In this section, you will create a static webpage with a map and the ability to search at a location. First you will create your Amazon Location resources and create an API key for your application.

**Topics**
+ [Create Amazon Location resources for your app](qs-create-resources-web.md)
+ [Set up authentication for your Amazon Location application](qs-setup-authentication-web.md)
+ [Create the HTML for your Amazon Location application](qs-create-html.md)
+ [Add an Amazon Location interactive map to your application](qs-add-map.md)
+ [Add Amazon Location search to your application](qs-add-search.md)
+ [Review the final Amazon Location application](qs-final-review.md)

# Create Amazon Location resources for your app
<a name="qs-create-resources-web"></a>

If you do not already have them, you must create the Amazon Location resources that your application will use. Here, you create a map resource to display maps in your application, and a place index to search for locations on the map.

**To add location resources to your application**

1. Choose the map style that you want to use.

   1. In the Amazon Location console, on the [Maps](https://console.aws.amazon.com/location/maps/home) page, choose **Create map** to preview map styles.

   1. Add a **Name** and **Description** for the new map resource. Make a note of the name that you use for the map resource. You will need it when creating your script file later in the tutorial.

   1. Choose a map.
**Note**  
Choosing a map style also chooses which map data provider that you will use. If your application is tracking or routing assets that you use in your business, such as delivery vehicles or employees, you may only use HERE as your geolocation provider. For more information, see section 82 of the [AWS service terms](https://aws.amazon.com/service-terms). 

   1. Agree to the **Amazon Location Terms and Conditions**, then choose **Create map**. You can interact with the map that you've chosen: zoom in, zoom out, or pan in any direction.

   1. Make a note of the Amazon Resource Name (ARN) that is shown for your new map resource. You'll use it to create the correct authentication later in this tutorial.

1. Choose the place index that you want to use.

   1. In the Amazon Location console on the [https://console.aws.amazon.com/location/places/home](https://console.aws.amazon.com/location/places/home) page, choose **Create place index**.

   1. Add a **Name** and **Description** for the new place index resource. Make a note of the name that you use for the place index resource. You will need it when creating your script file later in the tutorial.

   1. Choose a data provider.
**Note**  
In most cases, choose the data provider that matches the map provider that you already chose. This helps to ensure that the searches will match the maps.  
If your application is tracking or routing assets that you use in your business, such as delivery vehicles or employees, you may only use HERE as your geolocation provider. For more information, see section 82 of the [AWS service terms](https://aws.amazon.com/service-terms). 

   1. Choose the **Data storage option**. For this tutorial, the results are not stored, so you can choose ** No, single use only**.

   1. Agree to the **Amazon Location Terms and Conditions**, then choose **Create place index**.

   1. Make a note of the ARN that is shown for your new place index resource. You'll use it to create the correct authentication in the next section of this tutorial.

# Set up authentication for your Amazon Location application
<a name="qs-setup-authentication-web"></a>

The application that you create in this tutorial has anonymous usage, meaning that your users are not required to sign into AWS to use the application. However, by default, the Amazon Location Service APIs require authentication to use. You can use either Amazon Cognito or API keys to provide authentication and authorization for anonymous users. In this tutorial, you will create API keys for use in the sample application.

**Note**  
For more information about using API keys or Amazon Cognito with Amazon Location Service, see [Grant access to Amazon Location Service](how-to-access.md).



**To set up authentication for your application**

1. Go to the [Amazon Location console](https://console.aws.amazon.com/location), and choose **API keys** from the left menu.

1. Choose **Create API key**.
**Important**  
The API key that you create must be in the same AWS account and AWS Region as the Amazon Location Service resources that you created in the previous section.

1. One the **Create API key** page, fill in the following information.
   + **Name** – A name for your API key, such as `MyWebAppKey`.
   + **Resources** – Choose the Amazon Location Map and Place index resources that you created in the previous section. You can add more than one resource by choosing **Add resource**. This will allow the API key to be used with those resources.
   + **Actions** – Specify the actions you want to authorize with this API key. You must select at least **geo:GetMap\$1** and **geo:SearchPlaceIndexfForPosition** so that the tutorial will work as expected.
   + You can optionally add a **Description**, **Expiration time**, or **Tags** to your API key. You can also add a referrer (such as `*.example.com`), to limit the key to only being used from a particular domain. This will mean that the tutorial will only work from that domain.
**Note**  
It is recommended that you protect your API key usage by setting either an expiration time or a referrer, if not both.

1. Choose **Create API key** to create the API key.

1. Choose **Show API key**, and copy the key value for use later in the tutorial. It will be in the form `v1.public.a1b2c3d4...`.
**Important**  
You will need this key when writing the code for your application later in this tutorial.

# Create the HTML for your Amazon Location application
<a name="qs-create-html"></a>

In this tutorial, you will create a static HTML page that embeds a map, and allows the user to find what's at a location on the map. The app will consist of three files: an HTML file and CSS file for the webpage, and a JavaScript (.js) file for the code that creates the map and responds to the user's interactions and map events.

First, let's create the HTML and CSS framework that will be used for the application. This will be a simple page with a `<div>` element to hold the map container and a <pre> element to show the JSON responses to your queries.

**To create the HTML for your quick start application**

1. Create a new file called `quickstart.html`.

1. Edit the file in the text editor or environment of your choice. Add the following HTML to the file.

   ```
   <!DOCTYPE html>
   <html>
     <head>
       <meta charset="utf-8">
       <title>Quick start tutorial</title>
   
       <!-- Styles -->
       <link href="main.css" rel="stylesheet" />
     </head>
     
     <body>
       <header>
         <h1>Quick start tutorial</h1>
       </header>
       <main>
         <div id="map"></div>
         <aside>
           <h2>JSON Response</h2>
           <pre id="response"></pre>
         </aside>
       </main>
       <footer>This is a simple Amazon Location Service app. Pan and zoom. Click to see details about entities close to a point.</footer>
       
     </body>
   </html>
   ```

   This HTML has a pointer to the CSS file that you will create in the next step, some placeholder elements for the application, and some explanatory text.

   There are two placeholder elements that you will use later in this tutorial. The first is the `<div id="map>` element, which will hold the map control. The second is the `<pre id="response">` element, which will show the results of searching on the map.

1. Save your file.

Now add the CSS for the webpage. This will set the style of the text and placeholder elements for the application.

**To create the CSS for your quick start application**

1. Create a new file called `main.css`, in the same folder as the quickstart.html file created in the previous procedure.

1. Edit the file in whatever editor that you want to use. Add the following text to the file.

   ```
   * {
     box-sizing: border-box;
     font-family: Arial, Helvetica, sans-serif;
   }
   
   body {
     margin: 0;
   }
   
   header {
     background: #000000;
     padding: 0.5rem;
   }
   
   h1 {
     margin: 0;
     text-align: center;
     font-size: 1.5rem;
     color: #ffffff;
   }
   
   main {
     display: flex;
     min-height: calc(100vh - 94px);
   }
   
   #map {
     flex: 1;
   }
   
   aside {
     overflow-y: auto;
     flex: 0 0 30%;
     max-height: calc(100vh - 94px);
     box-shadow: 0 1px 1px 0 #001c244d, 1px 1px 1px 0 #001c2426, -1px 1px 1px 0 #001c2426;
     background: #f9f9f9;
     padding: 1rem;
   }
   
   h2 {
     margin: 0;
   }
   
   pre {
     white-space: pre-wrap;
     font-family: monospace;
     color: #16191f;
   }
   
   footer {
     background: #000000;
     padding: 1rem;
     color: #ffffff;
   }
   ```

   This sets the map to fill the space not used by anything else, sets the area for our responses to take up 30% of the width of the app, and sets color and styles for the title and explanatory text.

1. Save the file.

1. You can now view the `quickstart.html` file in a browser to see the layout of the application.  
![\[alt text not found\]](http://docs.aws.amazon.com/location/previous/developerguide/images/quickstart-blank.png)

Next, you will add the map control to the application.

# Add an Amazon Location interactive map to your application
<a name="qs-add-map"></a>

Now that you have a framework and a div placeholder, you can add the map control to your application. This tutorial uses [MapLibre GL JS](https://maplibre.org/maplibre-gl-js-docs/api/) as a map control, getting data from Amazon Location Service. You will also use the [JavaScript Authentication helper](loc-sdk-auth.md) to facilitate signing of calls to the Amazon Location APIs with your API key.

**To add an interactive map to your application**

1. Open the `quickstart.html` file that you created in the previous section.

1. Add references to the needed libraries, and the script file that you will create. The changes you need to make are shown in **green**.

   ```
   <!DOCTYPE html>
   <html>
     <head>
       <meta charset="utf-8">
       <title>Quick start tutorial</title>
   
       <!-- Styles -->
       <link href="https://unpkg.com/maplibre-gl@3.x/dist/maplibre-gl.css" rel="stylesheet" />
       <link href="main.css" rel="stylesheet" />
     </head>
     
     <body>
       ...
       <footer>This is a simple Amazon Location Service app. Pan and zoom. Click to see details about entities close to a point.</footer>
       
       <!-- JavaScript dependencies -->
       <script src="https://unpkg.com/maplibre-gl@3.x/dist/maplibre-gl.js"></script>
       <script src="https://unpkg.com/@aws/amazon-location-client@1.x/dist/amazonLocationClient.js"></script>
       <script src="https://unpkg.com/@aws/amazon-location-utilities-auth-helper@1.x/dist/amazonLocationAuthHelper.js"></script>
       
       <!-- JavaScript for the app -->
       <script src="main.js"></script>
     </body>
   </html>
   ```

   This adds the following dependencies to your app:
   + **MapLibre GL JS**. This library and stylesheet include a map control that displays map tiles and includes interactivity, such as pan and zoom. The control also allows extensions, such as drawing your own features on the map.
   + **Amazon Location client**. This provides interfaces for the Amazon Location functionality needed to get map data, and to search for places on the map. The Amazon Location client is based on the AWS SDK for JavaScript v3.
   + **Amazon Location Authentication Helper**. This provides helpful functions for authenticating Amazon Location Service with API keys or Amazon Cognito.

   This step also adds a reference to `main.js`, which you will create next.

1. Save the `quickstart.html` file.

1. Create a new file called `main.js` in the same folder as your HTML and CSS files, and open it for editing.

1. Add the following script to your file. The text in *red* should be replaced with the API key value, map resource name, and place resource name that you created earlier, as well as the region identifier for your region (such as `us-east-1`).

   ```
   // Amazon Location Service resource names:
   const mapName = "explore.map";
   const placesName = "explore.place";
   const region = "your_region";
   const apiKey = "v1.public.a1b2c3d4...
   
   // Initialize a map
   async function initializeMap() {
     const mlglMap = new maplibregl.Map({
       container: "map", // HTML element ID of map element
       center: [-77.03674, 38.891602], // Initial map centerpoint
       zoom: 16, // Initial map zoom
       style: `https://maps.geo.${region}.amazonaws.com/maps/v0/maps/${mapName}/style-descriptor?key=${apiKey}`, // Defines the appearance of the map and authenticates using an API key
     });
   
     // Add navigation control to the top left of the map
     mlglMap.addControl(new maplibregl.NavigationControl(), "top-left");
     
     return mlglMap;
   }
   
   async function main() {
     // Initialize map and Amazon Location SDK client:
     const map = await initializeMap();
   }
   
   main();
   ```

   This code sets up Amazon Location resources, then configures and initializes a MapLibre GL JS map control and places it in your `<div>` element with the id `map`.

   The `initializeMap()` function is important to understand. It creates a new MapLibre map control (called `mlglMap` locally, but called `map` in the rest of the code) that is used to render the map in your application.

   ```
     // Initialize the map
     const mlglMap = new maplibregl.Map({
       container: "map", // HTML element ID of map element
       center: [-77.03674, 38.891602], // Initial map centerpoint
       zoom: 16, // Initial map zoom
       style: `https://maps.geo.${region}.amazonaws.com/maps/v0/maps/${mapName}/style-descriptor?key=${apiKey}`, // Defines the appearance of the map and authenticates using an API key
     });
   ```

   When you create a new MapLibre map control, the parameters that you pass indicate the initial state of the map control. Here, we set the following parameters.
   + HTML container, which uses the map div element in our HTML.
   + The initial center of the map to a point in Washington, DC.
   + The zoom level to 16 (zoomed into a neighborhood or block level).
   + The style to use for the map, which gives MapLibre a URL to use to get the map tiles and other information to render the map. Notice that this URL includes your API key for authentication.

1. Save your JavaScript file, and open it with a browser. You now have a map on your page, where you can use pan and zoom actions. 
**Note**  
You can use this app to see how the MapLibre map control behaves. You can try using Ctrl or Shift while using a dragging operation, to see other ways to interact with the map. All of this functionality is customizable.  
![\[alt text not found\]](http://docs.aws.amazon.com/location/previous/developerguide/images/quickstart-map.png)

Your app is nearly complete. In the next section, you will handle choosing a location on the map, and show the address of the location chosen. You will also show the resulting JSON on the page, to see the full results.

# Add Amazon Location search to your application
<a name="qs-add-search"></a>

The last step for your application is to add searching on the map. In this case, you will add a reverse geocoding search, where you find the items at a location.

**Note**  
Amazon Location Service also provides the ability to search by name or address to find the locations of places on the map.

**To add search functionality to your application**

1. Open the `main.js` file that you created in the previous section.

1. Modify the `main` function, as shown. The changes you need to make are shown in **green**.

   ```
   async function main() {
     // Create an authentication helper instance using an API key
     const authHelper = await amazonLocationAuthHelper.withAPIKey(apiKey);
   
   
     // Initialize map and Amazon Location SDK client:
     const map = await initializeMap();
   
     const client = new amazonLocationClient.LocationClient({
       region,
       ...authHelper.getLocationClientConfig(), // Provides configuration required to make requests to Amazon Location
     });
   
   
     // On mouse click, display marker and get results:
     map.on("click", async function (e) {
       // Set up parameters for search call
       let params = {
         IndexName: placesName,
         Position: [e.lngLat.lng, e.lngLat.lat],
         Language: "en",
         MaxResults: "5",
       };
   
       // Set up command to search for results around clicked point
       const searchCommand = new amazonLocationClient.SearchPlaceIndexForPositionCommand(params);
   
       try {
         // Make request to search for results around clicked point
         const data = await client.send(searchCommand);
   
         // Write JSON response data to HTML
         document.querySelector("#response").textContent = JSON.stringify(data, undefined, 2);
   
         // Display place label in an alert box
         alert(data.Results[0].Place.Label);
       } catch (error) {
         // Write JSON response error to HTML
         document.querySelector("#response").textContent = JSON.stringify(error, undefined, 2);
   
         // Display error in an alert box
         alert("There was an error searching.");
       }
     });
   }
   ```

   This code starts by setting up the Amazon Location authentication helper to use your API key.

   ```
   const authHelper = await amazonLocationAuthHelper.withAPIKey(apiKey);
   ```

   Then it uses that authentication helper, and the region you are using to create a new Amazon Location client.

   ```
   const client = new amazonLocationClient.LocationClient({
       region,
       ...authHelper.getLocationClientConfig(),
     });
   ```

   Next, the code responds to the user choosing a spot on the map control. It does this by catching a MapLibre provided event for `click`.

   ```
   map.on("click", async function(e) {
       ...
     });
   ```

   The MapLibre `click` event provides parameters that include the latitude and longitude that the user chose (`e.lngLat`). Within the `click` event, the code creates the `searchPlaceIndexForPositionCommand` to find the entities at the given latitude and longitude.

   ```
       // Set up parameters for search call
       let params = {
         IndexName: placesName,
         Position: [e.lngLat.lng, e.lngLat.lat],
         Language: "en",
         MaxResults: "5"
       };
   
       // Set up command to search for results around clicked point
       const searchCommand = new amazonLocationClient.SearchPlaceIndexForPositionCommand(params);
   
       try {
         // Make request to search for results around clicked point
         const data = await client.send(searchCommand);
         ...
       });
   ```

   Here, the `IndexName` is the name of the Place Index resource that you created earlier, the `Position` is the latitude and longitude to search for, `Language` is the preferred language for results, and `MaxResults` tells Amazon Location to return only a maximum of five results.

   The remaining code checks for an error, and then displays the results of the search in the `<pre>` element called `response`, and shows the top result in an alert box.

1. (Optional) If you save and open the `quickstart.html` file in a browser now, choosing a location on the map will show you the name or address of the place that you chose.

1. The final step in the application is to use the MapLibre functionality to add a marker on the spot that the user selected. Modify the `main` function as follows. The changes you need to make are shown in **green**.

   ```
   async function main() {
     // Create an authentication helper instance using an API key
     const authHelper = await amazonLocationAuthHelper.withAPIKey(apiKey);
   
     // Initialize map and Amazon Location SDK client
     const map = await initializeMap();
     const client = new amazonLocationClient.LocationClient({
       region,
       ...authHelper.getLocationClientConfig(), // Provides configuration required to make requests to Amazon Location
     });
   
     // Variable to hold marker that will be rendered on click
     let marker;
   
     // On mouse click, display marker and get results:
     map.on("click", async function (e) {
       // Remove any existing marker
       if (marker) {
         marker.remove();
       }
   
       // Render a marker on clicked point
       marker = new maplibregl.Marker().setLngLat([e.lngLat.lng, e.lngLat.lat]).addTo(map);
   
       // Set up parameters for search call
       let params = {
         IndexName: placesName,
         Position: [e.lngLat.lng, e.lngLat.lat],
         Language: "en",
         MaxResults: "5",
       };
   
       // Set up command to search for results around clicked point
       const searchCommand = new amazonLocationClient.SearchPlaceIndexForPositionCommand(params);
   
   ...
   ```

   This code declares a `marker` variable, that is populated each time the user selects a location, showing where they selected. The marker is automatically rendered by the map control, once it's added to the map with `.addTo(map);`. The code also checks for a previous marker, and removes it, so that there is only 1 marker on the screen at a time.

1. Save the `main.js` file, and open the `quickstart.html` file in a browser. You can pan and zoom on the map, as before, but now if you choose a location, you will see details about the location that you chose.  
![\[alt text not found\]](http://docs.aws.amazon.com/location/previous/developerguide/images/quickstart-search.png)

Your quick start application is complete. This tutorial has shown you how to create a static HTML application that:
+ Creates a map that users can interact with.
+ Handles a map event (`click`).
+ Calls an Amazon Location Service API, specifically to search the map at a location, using `searchPlaceIndexForPosition`.
+ Uses the MapLibre map control to add a marker.

# Review the final Amazon Location application
<a name="qs-final-review"></a>

The final source code for this application is included in this section. You can also find the final project [on GitHub](https://github.com/aws-geospatial/amazon-location-samples-js/tree/main/quick-start-using-api-keys).

You can also find a version of the application that uses Amazon Cognito instead of API keys [on GitHub](https://github.com/aws-geospatial/amazon-location-samples-js/tree/main/quick-start-using-cognito).

------
#### [ Overview ]

Select each tab to view the final source code of the files in this quick start tutorial.

The files are:
+ **quickstart.html** — the framework for your application, including the HTML element holders for the map and search results.
+ **main.css** — the stylesheet for the application.
+ **main.js** — the script for your application that authenticates the user, creates the map, and searches on a `click` event. 

------
#### [ quickstart.html ]

The HTML framework for the quick start application.

```
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Quick start tutorial</title>

    <!-- Styles -->
    <link href="https://unpkg.com/maplibre-gl@3.x/dist/maplibre-gl.css" rel="stylesheet" />
    <link href="main.css" rel="stylesheet" />
  </head>
  
  <body>
    ...
    <footer>This is a simple Amazon Location Service app. Pan and zoom. Click to see details about entities close to a point.</footer>
    
    <!-- JavaScript dependencies -->
    <script src="https://unpkg.com/maplibre-gl@3.x/dist/maplibre-gl.js"></script>
    <script src="https://unpkg.com/@aws/amazon-location-client@1.x/dist/amazonLocationClient.js"></script>
    <script src="https://unpkg.com/@aws/amazon-location-utilities-auth-helper@1.x/dist/amazonLocationAuthHelper.js"></script>
    
    <!-- JavaScript for the app -->
    <script src="main.js"></script>
  </body>
</html>
```

------
#### [ main.css ]

The stylesheet for the quick start application.

```
* {
  box-sizing: border-box;
  font-family: Arial, Helvetica, sans-serif;
}

body {
  margin: 0;
}

header {
  background: #000000;
  padding: 0.5rem;
}

h1 {
  margin: 0;
  text-align: center;
  font-size: 1.5rem;
  color: #ffffff;
}

main {
  display: flex;
  min-height: calc(100vh - 94px);
}

#map {
  flex: 1;
}

aside {
  overflow-y: auto;
  flex: 0 0 30%;
  max-height: calc(100vh - 94px);
  box-shadow: 0 1px 1px 0 #001c244d, 1px 1px 1px 0 #001c2426, -1px 1px 1px 0 #001c2426;
  background: #f9f9f9;
  padding: 1rem;
}

h2 {
  margin: 0;
}

pre {
  white-space: pre-wrap;
  font-family: monospace;
  color: #16191f;
}

footer {
  background: #000000;
  padding: 1rem;
  color: #ffffff;
}
```

------
#### [ main.js ]

The code for the quick start application. The text in *red* should be replaced with the appropriate Amazon Location object names.

```
// Amazon Location Service resource names:
const mapName = "explore.map";
const placesName = "explore.place";
const region = "your_region";
const apiKey = "v1.public.a1b2c3d4...

// Initialize a map
async function initializeMap() {
  // Initialize the map
  const mlglMap = new maplibregl.Map({
    container: "map", // HTML element ID of map element
    center: [-77.03674, 38.891602], // Initial map centerpoint
    zoom: 16, // Initial map zoom
    style: `https://maps.geo.${region}.amazonaws.com/maps/v0/maps/${mapName}/style-descriptor?key=${apiKey}`, // Defines the appearance of the map and authenticates using an API key
  });

  // Add navigation control to the top left of the map
  mlglMap.addControl(new maplibregl.NavigationControl(), "top-left");

  return mlglMap;
}

async function main() {
  // Create an authentication helper instance using an API key
  const authHelper = await amazonLocationAuthHelper.withAPIKey(apiKey);

  // Initialize map and Amazon Location SDK client
  const map = await initializeMap();
  const client = new amazonLocationClient.LocationClient({
    region,
    ...authHelper.getLocationClientConfig(), // Provides configuration required to make requests to Amazon Location
  });

  // Variable to hold marker that will be rendered on click
  let marker;

  // On mouse click, display marker and get results:
  map.on("click", async function (e) {
    // Remove any existing marker
    if (marker) {
      marker.remove();
    }

    // Render a marker on clicked point
    marker = new maplibregl.Marker().setLngLat([e.lngLat.lng, e.lngLat.lat]).addTo(map);

    // Set up parameters for search call
    let params = {
      IndexName: placesName,
      Position: [e.lngLat.lng, e.lngLat.lat],
      Language: "en",
      MaxResults: "5",
    };

    // Set up command to search for results around clicked point
    const searchCommand = new amazonLocationClient.SearchPlaceIndexForPositionCommand(params);

    try {
      // Make request to search for results around clicked point
      const data = await client.send(searchCommand);

      // Write JSON response data to HTML
      document.querySelector("#response").textContent = JSON.stringify(data, undefined, 2);

      // Display place label in an alert box
      alert(data.Results[0].Place.Label);
    } catch (error) {
      // Write JSON response error to HTML
      document.querySelector("#response").textContent = JSON.stringify(error, undefined, 2);

      // Display error in an alert box
      alert("There was an error searching.");
    }
  });
}

main();
```

------

## What's next
<a name="qs-whats-next"></a>

You have completed the quick start tutorial, and should have an idea of how Amazon Location Service is used to build applications. To get more out of Amazon Location, you can check out the following resources:
+ Dive deeper into the [concepts of Amazon Location Service](how-it-works.md)
+ Get more information about [how to use Amazon Location features and functionality](using-amazon-location.md)
+ See how to expand on this sample and build more complex applications by looking at [code examples using Amazon Location](samples.md)