As I’ve progressed through my coding experiences and career (and, let’s be honest, throughout life), I’m constantly looking for fun ways to connect what I learn with what I know. Most recently, I’ve been creating a video series for web developers looking to add a bit of AI to their mapping applications. I’ve had fun testing out different AI libraries and showing developers just how easy it can be to implement these in their apps.
Today, I’m guiding you through a tutorial that shows how to generate insights about a location with minimal code. We’ll be using the OpenAI API alongside the ArcGIS Maps SDK for JavaScript, with the modern web components approach. This is a simple and declarative way to add powerful mapping features to your web apps. Don’t worry if you’re new to either of these tools — I’ll guide you through each step.
AI + ArcGIS JS SDK Project Setup
To start, we’ll use a simple HTML, CSS, and JS setup. In Visual Studio Code, I’ll create the HTML, CSS, and JS files. In the HTML, I’ll use the ! + Enter shortcut for the basic HTML setup. I’ll also be sure to link my CSS and JS files. Here's what it looks like so far:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="/styles.css" />
<script src="/scripts.js"></script>
</head>
<body>
</body>
</html>
HTML Setup
Since I’m using the ArcGIS Maps SDK for JS components, I’ll need to include a couple of libraries through CDN — Calcite Components and the ArcGIS JS SDK. We’re using CDN for simplicity, but for larger production apps, using npm is recommended.
<link rel="stylesheet" type="text/css" href="https://js.arcgis.com/calcite-components/2.13.2/calcite.css" />
<link rel="stylesheet" href="https://js.arcgis.com/4.31/esri/themes/light/main.css" />
<script type="module" src="https://js.arcgis.com/calcite-components/2.13.2/calcite.esm.js"></script>
<script src="https://js.arcgis.com/4.31/"></script>
<script type="module" src="https://js.arcgis.com/map-components/4.31/arcgis-map-components.esm.js"></script>
Before using the ArcGIS map styles, I’ll set up authentication with my ArcGIS API key. Note: Never expose your API key publicly in the frontend. In a production environment, you should use a backend server to securely handle API requests and manage keys. For now, I’ll include this above all other script tags in my HTML file for simplicity.
<script>
var esriConfig = {
apiKey: "yourKey"
};
</script>
Now, I can use the custom element to represent the map and set the basemap, center (longitude, latitude), and zoom properties to my liking.
<arcgis-map basemap="arcgis/topographic" center="-77.02, 38.89" zoom="13">
<arcgis-zoom position="top-left"></arcgis-zoom>
</arcgis-map>
Here’s what the final HTML file should look like:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenAI + ArcGIS Map</title>
<script>
var esriConfig = {
apiKey: "yourKey"
};
</script>
<link rel="stylesheet" type="text/css" href="https://js.arcgis.com/calcite-components/2.13.2/calcite.css" />
<link rel="stylesheet" href="https://js.arcgis.com/4.31/esri/themes/light/main.css" />
<link rel="stylesheet" href="/styles.css" />
<script type="module" src="https://js.arcgis.com/calcite-components/2.13.2/calcite.esm.js"></script>
<script src="https://js.arcgis.com/4.31/"></script>
<script type="module" src="https://js.arcgis.com/map-components/4.31/arcgis-map-components.esm.js"></script>
</head>
<body>
<arcgis-map basemap="arcgis/topographic" center="-77.02, 38.89" zoom="13">
<arcgis-zoom position="top-left"></arcgis-zoom>
</arcgis-map>
<script src="/scripts.js"></script>
</body>
</html>
CSS Setup
Now, onto the CSS. We’ll start by targeting the html, body, and arcgis-map elements. Since I want my map to take up the entire page, I'll ensure there are no predefined padding or margins and that it takes up 100% of the height and width of the page.
html,
body,
arcgis-map {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
At this point, you’ll be able to see your ArcGIS JS map on the screen. Functionality is limited to zooming and panning, so let’s continue!
JS Setup
Now, onto the fun part — getting our map to interact with OpenAI! First, we need to define our OpenAI API key for authentication. You’ll need to have an account with OpenAI to get one. After that, we’ll grab the map by selecting the custom element from the DOM and assigning it to the arcgisMap variable. This lets us manipulate the map programmatically.
const openaiApiKey = "yourKey";
const arcgisMap = document.querySelector("arcgis-map");
Speaking of interacting with our map, we’ll go ahead and add an event listener to it. We’ll capture the arcgisViewClick event, which is triggered when the user clicks anywhere on the map. This will help us get the clicked location and send it to the OpenAI API.
After the user clicks, we’ll extract the map coordinates (mapPoint) from the event details and store them in the params object. This gives us the location (longitude, latitude) where the user clicked. We'll also use outFields: "*" to request all attributes for the clicked feature (you can refine this based on your needs).
arcgisMap.addEventListener("arcgisViewClick", async event => {
const params = {
location: event.detail.mapPoint,
outFields: "*"
};
//rest of the code from below will go here
});
Now, let’s move on to getting the response from OpenAI. First, we define the prompt that will be sent to the API using the longitude and latitude from params.location. Next, we'll destructure the choices array from the response. This is where OpenAI will store the generated content based on our prompt. We'll then call the OpenAI API with fetch(), sending a POST request to the chat/completions endpoint. The headers include Content-Type: application/json to indicate we're sending and receiving JSON, and Authorization with the Bearer token for authentication.
In the body, we specify the model (I’m choosing the gpt-4o model here). Then, we'll pass the prompt in the messages field with a "user" role, indicating it's user input. After making the request, we use await to get the response and call .json() to parse it.
const prompt = `Give a fact about longitude: ${params.location.longitude}, latitude: ${params.location.latitude}.`;
const { choices } = await (
await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${openaiApiKey}`, // Use the API key
},
body: JSON.stringify({
model: "gpt-4o", // Use the gpt-4o model
messages: [{ role: "user", content: prompt }],
}),
})
).json();
Finally, we use arcgisMap.popup.open() to display a popup at the clicked location. The longitude and latitude are set from params.location, and the title is whatever you choose. The content is set to the AI-generated text from choices[0].message.content, showing the fact on the map.
arcgisMap.openPopup({
longitude: params.location.longitude,
latitude: params.location.latitude,
title: "AI-Generated Fact",
content: choices[0].message.content,
});
Final App in Action
With everything set up, this app now allows users to click anywhere on the map. Based on their click, it sends the coordinates to the OpenAI API. The API generates a relevant fact about that location, which is then displayed in a popup on the map. But don’t stop there — have fun with it! You can easily change the prompt sent to OpenAI. For example, you could ask for a scary fact 😱, a funny one 😂, or even ask it to include emojis! 😉
For your reference, here’s a CodePen with the full code.
Conclusion
By following these steps, we’ve successfully created an AI-powered mapping application. Here’s a quick recap of what we’ve done:
Set up the map using the ArcGIS Maps SDK for JavaScript Web Components via CDN.
Used the OpenAI API to generate dynamic content based on clicked locations.
Displayed that content in a popup on the map.
With this approach, you’ve seen how easy it is to integrate AI and mapping tools into your web applications. The key takeaway is that it really takes minimal setup and code to build powerful applications that combine real-time user interactions with AI insights.
So whether you’re enhancing your mapping projects or exploring new ways to use AI, I hope I’ve inspired you today. I’d love to see any future creations you make, so please share them here or with me on my socials. I’d love to see your work!
This article was written by Courtney Yatteau, a Developer Advocate at Esri. The opinions expressed in this article are solely Courtney’s and do not necessarily represent the views, strategies, or opinions of her employer. If you have any feedback, please feel free to like and/or comment. Additionally, if you have any questions or comments that you’d prefer to send privately, you can contact Courtney through LinkedIn, X, Bluesky, or email. If you’re considering a career switch, looking to get into tech, or curious about what it’s like to work at Esri, then please stay tuned for future posts! You can also check out Esri’s careers page or this video for more information.
Top comments (2)
This innovative merge of AI and mapping is truly captivating! The simplicity of deriving insights from map clicks belies the vast potential it unlocks.🤯 Your share has certainly inspired me to explore this further, thank you...!!!
Thank you!! Please share anything you create. I'd love to see it!