DEV Community

Cover image for How to add a location search widget to your web app using Amazon Location Service
abraham poorazizi
abraham poorazizi

Posted on • Edited on

How to add a location search widget to your web app using Amazon Location Service

Location information comes in different forms and formats from geographical coordinates (or longitude & latitude) to addresses and to place names. A common use case, when building geospatial apps, is to allow users to search for places, and convert geographic coordinates into addresses and vice versa.

Amazon Location Service lets you add location search functionality to your web and mobile applications. It supports:

  • Converting text such as an address or a place name (or point of interest) into geographic coordinates, also known as geocoding.
  • Turning geographic coordinates into an address or a place name (or point of interest), also known as reverse-geocoding.
  • Responsive feedback to end-users as they are typing an address or a place name (or point of interest), also known as autocomplete or auto-suggest.

In this post, you will learn how you can add a location search widget to your web app using Amazon Location Service’s Places API. We will build the app using AWS Amplify and Vue — We will create, deploy, and manage AWS resources using Amplify CLI and we will build the app components using Amplify JavaScript and MapLibre GL JS. The app will have a basemap with navigation controls and a location search widget with geocoding, reverse-geocoding, and autocomplete support.

1. Install and configure AWS Amplify

Before you start

  • Create an AWS account, if you don’t have one already.
  • Install Node.js (version 12.x or greater) and npm (version 6.x or greater), if they are not already on your machine.

Now, install Amplify CLI.

npm install -g @aws-amplify/cli
Enter fullscreen mode Exit fullscreen mode

Next, configure AWS Amplify. This will create a new IAM user with administrative access to your account to provision AWS resources for you.

amplify configure
Enter fullscreen mode Exit fullscreen mode
Follow these steps to set up access to your AWS account:

Sign in to your AWS administrator account:
https://console.aws.amazon.com/
Press Enter to continue
Enter fullscreen mode Exit fullscreen mode

Continue the process on the AWS Console. Create a user with AdministratorAccess-Amplify to your account to provision AWS resources for you.

Add an IAM user for Amplify - Step 1
Add an IAM user for Amplify - Step 2
Add an IAM user for Amplify - Step 3

Once you create the user, Amplify CLI will ask you to provide the accessKeyId and the secretAccessKey to connect Amplify CLI with your newly created IAM user.

Enter the access key of the newly created user:
? accessKeyId: ••••••••••••••••
? secretAccessKey:  ••••••••••••••••
This would update/create the AWS Profile in your local machine
? Profile Name: default
Enter fullscreen mode Exit fullscreen mode

2. Create a new project

Create a new Vue project using Vite.

npm create vite@latest
Enter fullscreen mode Exit fullscreen mode

Choose a name for your project and pick vue as the framework and variant.

✔ Project name: location-search-widget
✔ Select a framework: › vue
✔ Select a variant: › vue
Enter fullscreen mode Exit fullscreen mode

Next, go into your project’s root directory and install the dependencies.

cd location-search-widget
npm install
Enter fullscreen mode Exit fullscreen mode

Then, initialize AWS Amplify within your project’s root directory.

amplify init
Enter fullscreen mode Exit fullscreen mode

Choose a name for your Amplify project, set your desired configurations, and select your authentication profile. Amplify CLI will then initialize your project.

? Enter a name for the project locationsearchwidget
The following configuration will be applied:

Project information
| Name: locationsearchwidget
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: vue
| Source Directory Path: src
| Distribution Directory Path: dist
| Build Command: npm run-script build
| Start Command: npm run-script serve

? Initialize the project with the above configuration? Yes
Using default provider  awscloudformation
? Select the authentication method you want to use: AWS profile

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html

? Please choose the profile you want to use default
Enter fullscreen mode Exit fullscreen mode

Next, install the AWS Amplify library for JavaScript.

npm install aws-amplify
Enter fullscreen mode Exit fullscreen mode

Then, add the following code to src/main.js to configure Amplify within your Vue app.

...

import { Amplify } from "aws-amplify";
import awsconfig from "./aws-exports";

Amplify.configure(awsconfig);

...
Enter fullscreen mode Exit fullscreen mode

Next, replace the content of App.vue with the following code.

<template>
</template>

<script setup>
</script>

<style>
</style>
Enter fullscreen mode Exit fullscreen mode

Finally, add the following configuration to vite.config.

export default defineConfig({
  ...

  define: {
    global: {}
  }
});
Enter fullscreen mode Exit fullscreen mode

3. Add auth configuration

We need to configure authentication in our app to specify how we want the frontend app access Amazon Location Service’s APIs. To do that, run the following command.

amplify add auth
Enter fullscreen mode Exit fullscreen mode

We will stick with the defaults but you can choose advanced settings to make changes.

Using service: Cognito, provided by: awscloudformation

 The current configured provider is Amazon Cognito. 

 Do you want to use the default authentication and security configuration? Default configuration
 Warning: you will not be able to edit these selections. 
 How do you want users to be able to sign in? Username
 Do you want to configure advanced settings? No, I am done.
Enter fullscreen mode Exit fullscreen mode

This will create an authentication resource, powered by Amazon Cognito, in your local environment.

4. Add a map

Amplify Geo is a new addition to the Amplify family. It provides APIs and UI components that enable developers to add location functionality such as maps and place search to their web and mobile apps. Amplify Geo APIs are powered by Amazon Location Service and its UI components are built as a plugin for MapLibre.

Now, let’s add a map. First, create a map resource using Amplify CLI.

amplify add geo
Enter fullscreen mode Exit fullscreen mode

Choose a name for your map and pick your preferred auth configuration. We will stick with the defaults but you can choose advanced settings to change your data provider or map style, for example.

? Select which capability you want to add: Map (visualize the geospatial data)
✔ Provide a name for the Map: · locationsearchmap
✔ Who can access this Map? · Authorized and Guest users
Available advanced settings:
- Map style & Map data provider (default: Streets provided by Esri)

✔ Do you want to configure advanced settings? (y/N) · no
Enter fullscreen mode Exit fullscreen mode

This will create a map resource in your local environment. Next, push the changes to AWS.

amplfiy push
Enter fullscreen mode Exit fullscreen mode

It may take a few minutes for the changes to deploy. Once it is done, you will have your authentication and map resources set up and ready to use.

Now, let’s render the map we just created. First, install maplibre-gl-js-amplify, which is a plugin for MapLibre GL JS that makes it easy to integrate with Amplify Geo.

npm install maplibre-gl-js-amplify
Enter fullscreen mode Exit fullscreen mode

Then, open App.vue and add a div container for the map.

<template>
   <div id="map"></div>
</template>
Enter fullscreen mode Exit fullscreen mode

Next, add a new map instance with navigation controls.

<script setup>
import maplibregl from "maplibre-gl";
import { createMap } from "maplibre-gl-js-amplify";

async function initializeMap() {
    const map = await createMap({
        container: "map", 
        center: [-114.067375, 51.046333],
        zoom: 16,
        hash: true
    });

    map.addControl(new maplibregl.NavigationControl(), "bottom-right");
}

initializeMap();
</script>
Enter fullscreen mode Exit fullscreen mode

Finally, add the following CSS to produce a full screen map.

<style>
@import "maplibre-gl/dist/maplibre-gl.css";

body {
  margin: 0;
  padding: 0;
}
#map {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}
</style>
Enter fullscreen mode Exit fullscreen mode

Now, if you run npm run dev in your terminal and go to your browser, you will see an interactive map on the page.

An interactive map

5. Add a location search widget

The next step is to create a location search resource using Amplify CLI.

amplify add geo
Enter fullscreen mode Exit fullscreen mode

Choose a name for your location search index and pick your preferred auth configuration. We will stick with the defaults but you can choose advanced settings to change your data provider, for example.

? Select which capability you want to add: Location search (search by places, addresses, coordinates)
✔ Provide a name for the location search index (place index): · locationsearchwidget
✔ Who can access this search index? · Authorized and Guest users
Available advanced settings:
- Search data provider (default: HERE)
- Search result storage location (default: no result storage)

✔ Do you want to configure advanced settings? (y/N) · no
Enter fullscreen mode Exit fullscreen mode

This will create the backend resources for your project in your local environment. Next, push the changes to AWS.

amplfiy push
Enter fullscreen mode Exit fullscreen mode

It may take a few minutes for the changes to deploy. Once it is done, you will have a location search resource set up and ready to use.

Now, let’s add a location search UI component to our map. First, import createAmplifyGeocoder into App.vue. This will create an instance of maplibre-gl-geocoder with some pre-defined settings.

<script setup>
...

import { createMap, createAmplifyGeocoder } from "maplibre-gl-js-amplify";

...
</script>
Enter fullscreen mode Exit fullscreen mode

Next, add a new map control for the location search component.

<script setup>
...

async function initializeMap() {
   ...

   map.addControl(createAmplifyGeocoder(), "top-left");
}

...
</script>
Enter fullscreen mode Exit fullscreen mode

Finally, import a CSS file into your app to style the location search component.

<style>
...

@import "@maplibre/maplibre-gl-geocoder/dist/maplibre-gl-geocoder.css";

...
</style>
Enter fullscreen mode Exit fullscreen mode

Now, if you save your project and go to your browser, you will see a location search widget on the map.

An interactive map with a location search widget

6. Customizations

The Amplify Geo’s location search widget supports customization through a number of options, including:.

  • autocomplete, which provides suggestions as users type in their input.
  • bbox, which limits the results to a bounding box. By default, the location search widget returns results that are near the center of the map. If you add bbox, it will override the default behaviour.
  • countries, which limits the results to specified countries using ISO 3166 three letter country codes, for example CAN for Canada.
  • language, which limits the results to the specified language using a valid BCP 47 language code, for example en for English.
  • limit, which limits the maximum number of results returned in the API response. The default value is 5.

Amplify Geo forms appropriate queries based on your customizations and invokes Amazon Location Service’s Places API to perform location search operations. See all the supported options for customization on GitHub.

For this project, we will use autocomplete, countries, and language.

map.addControl(
    createAmplifyGeocoder({
      autocomplete: true,
      countries: "CAN",
      language: "en",
    }),
    "top-left"
  );
Enter fullscreen mode Exit fullscreen mode

This will enable autocomplete and limit the search results to English and within Canada.

We will also add some UI customizations; we will use a custom icon for markers and add popups to markers. Download the SVG icon and put it in src/assets.

<script setup>
...

import markerIcon from "./assets/MarkerIcon.svg";

...

async function initializeMap() {
   ...

   const icon = new Image(35, 35);
   icon.src = markerIcon;

   map.addControl(
    createAmplifyGeocoder({
      ...

      marker: { element: icon },
      showResultMarkers: { element: icon },
      popup: { offset: 20 }
    }),
    "top-left"
  );
}

...
</script>
Enter fullscreen mode Exit fullscreen mode

Finally, add some CSS to customize the style of the location search widget.

<style>
...

*:focus {
  outline: none !important;
}
.maplibregl-ctrl-top-left .maplibregl-ctrl {
  width: 400px !important;
  border-radius: 10px;
}
.suggestions {
  border-radius: 10px !important;
}
.maplibregl-ctrl-geocoder--input {
  height: 50px;
  padding: 0px 50px;
}
.maplibregl-ctrl-geocoder--icon-search {
  left: 15px;
  width: 25px;
  height: 35px;
}
.maplibregl-ctrl-geocoder--button {
  right: 15px !important;
  top: 15px !important;
}
.maplibregl-ctrl-geocoder--icon-loading {
  width: 25px;
  height: 25px;
  right: 15px !important;
  top: 15px !important;
}
</style>
Enter fullscreen mode Exit fullscreen mode

Now, if you save your project and go to your browser, you will see the final result. You can search for addresses, place names, and geographic coordinates using the location search widget.

An interactive web map with a customized location search widget

Wrap up

In this tutorial, you learned how you can add a location search widget to your web app using Amazon Location Service’s Places API. You can use this project as a starting point for building apps with maps and search functionality and customize it to fit your purpose. Here are a few things you can do:

  • Include a number of different map styles using a layer control — see my previous post for a walkthrough.
  • Use the location search widget options to provide a personalized experience for you users, for example setting the language property based on their IP or exposing geospatial filtering options using the bounding box property.
  • Adjust the position of map controls such as the navigation controls and the location search widget or change their style to match your brand.

If you’d like to delete the AWS resources that you have created for this project, run amplify delete.

The code for this project is on GitHub. I’d love to hear your feedback, so please reach out to me if you have any questions or comments.

Top comments (5)

Collapse
 
samueldesalegn profile image
Samuel Desalegn Tumdedo

Thank you so much. This is so impressive and what I was looking for. Would mind assisting me on this?

Collapse
 
mepa1363 profile image
abraham poorazizi

Sure, how can I help?

Collapse
 
samueldesalegn profile image
Samuel Desalegn Tumdedo

Thank you again, my organization currently uses other LBS and they wanted me research on this, and I found your blog and it was amazing. Now, I wanted to show them exact same thing as your codes but had some difficulties. May we discuss privately, thanks.

Thread Thread
 
mepa1363 profile image
abraham poorazizi

Just sent you an email.

Collapse
 
samueldesalegn profile image
Samuel Desalegn Tumdedo

I am not sure how I can connect to you privately, our organization needs this feature and would you mind texting me on samueldesalegnt@gmail.com.