Front-End Web & Mobile
Add Maps to your App in 3 Steps with AWS Amplify Geo powered by Amazon Location Service
Today’s release of AWS Amplify Geo allows developers to quickly and easily add maps with markers and location search to their JavaScript-based web apps. The location APIs are powered by Amazon Location Service and the UI components are extended from a popular open-source map library, MapLibre.
Benefits
- Add maps and search functionality to a simple HTML page through script tags
- Add maps and search functionality to your JavaScript-based web frameworks through an NPM package
- Comes with all the cost-effective and privacy benefits powered by Amazon Location Service
- Use popular open-source maps UI library, MapLibre, that offers several additional UI customizations through community-sourced plugins
What we’ll build
Use case: As a restaurant owner, I would like to create a website for my restaurant that displays all the branches of my restaurant on map. This offers a better user experience to my customers who want to view the locations of the all my restaurant branches.
To achieve the above use case, we can add a map to a web page either through simple script tags in the HTML webpage or by adding the necessary NPM packages to any JavaScript-based web framework like React.
In this blog post, we will build a React-based web application for a restaurant website that displays all of the restaurant branches on a map.
We will dive into different approaches of adding maps to your website in future blog posts.
What we’ll learn
- How to create a React app with a map display
- How to display markers on the map
- How to customize the text in the popovers on markers
Prerequisites
Note: At the time of this post, Amplify Geo is only available in the following regions – US East (N. Virginia), US East (Ohio), US West (Oregon), Asia Pacific (Singapore), Asia Pacific (Sydney), Asia Pacific (Tokyo), Europe (Frankfurt), Europe (Ireland), and Europe (Stockholm)
- Install Node JS greater than v12.0
- Get the latest Amplify CLI by running
npm install -g @aws-amplify/cli
- If you haven’t yet configured Amplify CLI, please follow the documentation on the Amplify website here.
- At the time of writing, the latest version is v6.1.0.
Setting up a React App
This tutorial focuses on integrating AWS Amplify Geo into a React app – but, similar steps can be used with most modern web frameworks. To start with, we can run the following commands to create a React app for our restaurant home page.
npx create-react-app my-restaurants
cd my-restaurants
Run npm start
from the project directory to test the my-restaurants
project. This will automatically launch the React app in the browser pointing at http://localhost:3000. You will see something similar to the image below:
1. Setting up Amplify Geo
To get started with Amplify Geo, initialize an Amplify project for your new React app.
amplify init
This command will prompt you initialize your Amplify project with preselected defaults. You can choose to edit these defaults. For the purpose of this project, we can stick to the defaults. The defaults are shown below:
Now, add a map resource to display the map tiles on the screen. The following command will walk you through some configurations to set up your map.
amplify add geo
Choose to add a map resource to your project:
If you do not have Amplify Auth category configured, the Amplify CLI will prompt you to configure it now. You can follow along with the default choices for the purpose of this project:
Next, either enter a custom name for your map or stick with the default name and hit enter. This name can’t be changed, but isn’t visible to end-users. And you can always add more map resources, as required.
Next, select Authorized and Guest Users for Who can access this map? because you want anyone browsing the internet to be able to view the branches of the restaurant.
Note: If you select the Authorized users only option (the default), you will not see a map at the end of this tutorial until you make it possible for a user to login. The Amplify Authenticator UI component is a good way to do this for React apps.
The next question, Are you tracking commercial assets for your business in your app?, is primarily for determining the pricing for your map resource. For this project, since we are not tracking any devices, choose the first option No, I do not track devices or I only need to track consumers’ personal devices. You can find additional pricing details at Amazon Location Service Pricing.
For the purpose of this project, stick with the defaults and select No when prompted to configure advanced settings. Advanced settings allow you to further customize the map styles and data providers – you can come back to configure those later, if you choose.
Your map is now set up locally. To deploy this to the cloud, run the following command:
amplify push
Install the necessary client libraries for our application by running the following command:
npm install aws-amplify
Paste the following code to your index.js
file.
import Amplify from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
The aws-exports.js
is automatically generated by the Amplify CLI, and contains all of the details needed for your frontend web app to find all of the AWS services which have been configured for you.
2. Displaying Map on the Restaurant Home Page
First, clean up the web page to show the title of the restaurant and list out the different locations of the restaurant. Replace the contents of React App()
main function in App.js
to the code below.
function App() {
return (
<div className="App">
<h1>My Restaurant</h1>
<ul id="locations">
<li><b>My Restaurant - Upper East Side</b> <br/> 300 E 77th St, New York, NY 10075 </li>
<li><b>My Restaurant - Hell's Kitchen</b> <br/> 725 9th Ave, New York, NY 10019</li>
<li><b>My Restaurant - Lower East Side</b><br/> 102 Norfolk St, New York, NY 10002</li>
</ul>
</div>
);
}
Add the following CSS definitions in App.css to ensure a clean interface centered in the middle of the page.
#locations {
display: inline-block;
display: inline;
}
li {
padding: 5px;
display: inline-block;
margin: 20px;
}
At this point, you have a page that looks like this
Now that all the ground work is completed for the Amplify app and map resources, edit the React app to display a map on the web page and show the desired location markers.
The popular map rendering library, MapLibre, is used to render the map on the web page. We have created an Amplify Geo<>Maplibre package that provides ready to use map UI components that are already connected to the Amplify Geo APIs.
Install the MapLibre dependencies:
npm install -S maplibre-gl@1 maplibre-gl-js-amplify
Now, paste the following code snippet in your App.js file, to import the necessary dependencies
import { createMap } from "maplibre-gl-js-amplify";
import "maplibre-gl/dist/maplibre-gl.css";
import { useEffect } from 'react';
Using the createMap
function from maplibre-gl-js-amplify imported above, add a function to initialize the map. Add the code snippet below to App.js
async function initializeMap() {
const map = await createMap({
container: "map", // An HTML Element or HTML element ID to render the map in https://maplibre.org/maplibre-gl-js-docs/api/map/
center: [-73.98597609730648, 40.751874635721734], // center in New York
zoom: 11,
})
return map;
}
Invoke the initializeMap()
method in App()
function with the React useEffect
hook. The useEffect
hook ensures that the code inside it runs after every render. This ensures the map is not initialized before the map div component is available. Since a div
is needed to display the map in the HTML page, add the following div
element in the App()
function. It should now look like this:
function App() {
useEffect( async () => {
const map = await initializeMap();
}, []);
return (
<div className="App">
<h1>My Restaurant</h1>
<ul id="locations">
<li><b>My Restaurant - Upper East Side</b> <br/> 300 E 77th St, New York, NY 10075 </li>
<li><b>My Restaurant - Hell's Kitchen</b><br/> 725 9th Ave, New York, NY 10019</li>
<li><b>My Restaurant - Lower East Side</b><br/> 102 Norfolk St, New York, NY 10002</li>
</ul>
<div id="map"></div>
</div>
);
}
Lastly, add some CSS to render the map component correctly on the restaurant homepage:
#map { /* The id of the container you passed to createMap */
height: 40vh;
width: 40vw;
margin: auto;
}
You can now view your map on the web page, it should now look like the image below:
3. Adding Branch Locations for Restaurant on the Map
Here, you will be adding 3 different branch locations for the restaurant in New York. To display markers on the map, you will be using the drawPoints
method and the map automatically handles rendering the popups on click and clustering markers when they are nearby to offer a better user experience.
First, import the drawPoints
method in App.js
:
import { drawPoints } from "maplibre-gl-js-amplify";
Now, create a function addRestaurantLocations
using the drawPoints
method to load the markers on the map. The coordinates specified are locations of the restaurant branches. For more configuration options, please refer to the details of the drawPoints
method reference at aws-amplify/maplibre-gl-js-amplify repo.
function addRestaurantLocations(map) {
map.on("load", function () {
drawPoints("mySourceName", // Arbitrary source name
[
{
coordinates: [-73.98709247500821, 40.718839863699905],
title: "My Restaurant - Lower East Side",
address: "102 Norfolk St, New York, NY 10002",
},
{
coordinates: [-73.9893305444102, 40.76329636720047],
title: "My Restaurant - Hell's Kitchen",
address: "725 9th Ave, New York, NY 10019",
},
{
coordinates: [-73.95621342276895, 40.77225519589616],
title: "My Restaurant - Upper East Side",
address: "300 E 77th St, New York, NY 10075",
},
], // An array of coordinate data, an array of Feature data, or an array of [NamedLocations](https://github.com/aws-amplify/maplibre-gl-js-amplify/blob/main/src/types.ts#L8)
map,
{
showCluster: true,
unclusteredOptions: {
showMarkerPopup: true,
},
clusterOptions: {
showCount: true,
},
}
);
});
}
Call the addRestaurantLocations()
within useEffect()
in App()
function as well. Your App()
function will look like this:
function App() {
useEffect( async () => {
const map = await initializeMap();
addRestaurantLocations(map);
}, []);
return (
<div className="App">
<h1>My Restaurant</h1>
<ul id="locations">
<li><b>My Restaurant - Upper East Side</b> <br/> 300 E 77th St, New York, NY 10075 </li>
<li><b>My Restaurant - Hell's Kitchen</b><br/> 725 9th Ave, New York, NY 10019</li>
<li><b>My Restaurant - Lower East Side</b><br/> 102 Norfolk St, New York, NY 10002</li>
</ul>
<div id="map"></div>
</div>
);
}
Finally, cleanup the resources so that memory leaks wont be introduced into the application. To do this, copy the following highlighted code snippet in your useEffect
:
function App() {
useEffect( async () => {
const map = await initializeMap();
addRestaurantLocations(map);
return function cleanup() {
map.remove();
};
}, []);
return (
<div className="App">
<h1>My Restaurant</h1>
<ul id="locations">
<li><b>My Restaurant - Upper East Side</b> <br/> 300 E 77th St, New York, NY 10075 </li>
<li><b>My Restaurant - Hell's Kitchen</b><br/> 725 9th Ave, New York, NY 10019</li>
<li><b>My Restaurant - Lower East Side</b><br/> 102 Norfolk St, New York, NY 10002</li>
</ul>
<div id="map"></div>
</div>
);
}
Voilà! run npm start
and see your restaurant homepage that displays the many branches of the restaurant. You now have a fully functioning map on your restaurant’s homepage that displays its branches with additional information displayed in popovers!
You can follow the Amplify Hosting documentation here to successfully host your restaurant’s homepage!
Clean up
Now that you have finished this walk through, it’s recommended that you delete your Amplify app if you don’t plan to use it any further. This ensures that your resources won’t incur unexpected charges in the event someone gains access to your project’s credentials.
To delete all the local Amplify associated files and the Amplify project in the backend, run the following command:
$ amplify delete
Conclusion
In this blog post, we covered how to
- Configure a map in AWS
- Initialize and display a map to your react application
- Display location markers on a map with customized popover text
Next Steps: For more features and documentation on Amplify Geo, you can visit the Amplify Geo documentation
We are going to be adding more features to this new Amplify category, so stay tuned on our Twitter and Discord communications channels! 🎉