From dropping your first map onto the canvas to building production map-centric dashboards that drive every widget in your app. The Map widget is the beating heart of Experience Builder.
Everything you need to get a map into your app, configure its tools, and understand how the Map widget connects to every other widget in Experience Builder.
The Map widget is the centerpiece of most Experience Builder apps. It displays your Web Map (or Web Scene), lets users pan, zoom, click, and select features, and -- most importantly -- it drives other widgets. When a user clicks a feature on the map, that selection can update a List, populate a Text widget, filter a Chart, and trigger message actions across the entire app.
Without a Map widget, your EB app is a static page. With one, it becomes an interactive application.
The Map widget is like the steering wheel in a car. Other widgets -- Lists, Charts, Text, Buttons -- are the dashboard gauges. They all respond to what the driver (your user) does with the steering wheel. Turn the wheel (pan the map, select features), and everything else updates.
Shows your Web Map with all its layers, symbology, popups, and basemap exactly as configured in Map Viewer.
Pan, zoom, click, select, search, measure. Every interaction can trigger actions in other widgets.
The Map widget is the primary data source for most widget-to-widget connections. It is the hub of your app.
The single most important rule of the Map widget: build your Web Map in Map Viewer first, then connect it in EB. Do not try to configure layers, symbology, or popups inside Experience Builder. EB reads from your Web Map. If you want to change how data looks, change the Web Map.
Trying to build the map inside EB. They add layers, change symbology, configure popups, all inside the Map widget settings. Then they wonder why nothing sticks after publish, or why the map looks different in the builder vs. the published app. The Web Map is your single source of truth. Configure it in Map Viewer. EB just displays it.
Open Map Viewer, make a change to your Web Map (move a label, change a color), save it. Go back to EB, and the Map widget automatically reflects the change. This is the workflow -- Map Viewer is your design tool, EB is your app builder.
Every Map widget has a configurable toolbar that appears in the corner of the map. These are the built-in tools your users get. You choose which to show and which to hide. The key is knowing which tools are actually useful and which just add clutter.
| Tool | What it does | Recommendation |
|---|---|---|
| Zoom In/Out | + and - buttons for zooming | Keep ON. Users expect it. Some users don't know about scroll-to-zoom. |
| Home | Returns to the initial extent | Keep ON. This is the "reset" button. Essential. |
| Compass | Shows north, rotates the map | Usually OFF. Most 2D apps don't need map rotation, and the compass confuses people. |
| My Location | Zooms to user's GPS location | ON for field apps. OFF for desktop dashboards. |
| Search | Address/place search on the map | ON if users need to find locations. Consider the standalone Search widget instead for more control. |
| Measurement | Distance and area measurement | ON for planning and assessment apps. OFF for simple dashboards. |
| Basemap Gallery | Lets users switch basemaps | Usually OFF. Most apps have one correct basemap. Letting users switch creates confusion. |
| Fullscreen | Expands the map to fill the browser | ON for embedded apps. Nice to have for any map-heavy app. |
| Select | Rectangle, lasso, circle, point selection tools | ON if your app has any widget-to-widget connections. This is how users select features. |
| Layer List | Shows layer visibility toggles | Consider using the standalone Layer List widget instead -- more space, more options. |
| Legend | Shows symbology key | Consider the standalone Legend widget. The toolbar version is tiny and hard to read. |
The toolbar position (top-left, top-right, bottom-left, bottom-right) is set in the Style panel, not the Content panel. Many people search the Content panel for 10 minutes trying to find it. It is under Style > Map tools > Position.
Users often need to toggle layers on and off or see what the colors on the map mean. You have two approaches: built-in tools (inside the Map toolbar) or standalone widgets (separate widgets connected to the Map). The standalone widgets are almost always better.
Tiny panel inside the map. Limited space. Disappears when you click elsewhere. Fine for 2-3 layers.
Full-size panel in your layout. Always visible. Supports grouping, opacity sliders, reordering. Use this.
Connecting a standalone Layer List to your Map:
If your Web Map has group layers, the Layer List shows the groups with expand/collapse arrows. This is usually what you want. But if you have deeply nested groups, the Layer List becomes hard to navigate. Keep your Web Map layer structure flat and simple -- 1 level of grouping max.
When your app loads, the map zooms to a specific place. That is the initial extent. You can also create bookmarks -- saved views that users can jump to. Both are more useful than people realize.
Setting the initial extent in EB:
Creating and using bookmarks:
Bookmarks can be created in Map Viewer (saved with the Web Map) or in the Bookmark widget in EB. Map Viewer bookmarks are the better approach because they persist with the Web Map and work everywhere.
Bookmarks are like TV channel presets. Instead of manually tuning to a frequency (panning and zooming), you press a button and jump straight to the view you want. Create bookmarks for every geographic view your users commonly need.
Create 3 bookmarks in Map Viewer: one for the full extent, one for a zoomed-in area, and one for a specific feature. Add a Bookmark widget in EB and watch how it creates navigation buttons automatically. This is the simplest way to add geographic navigation to your app.
Selection is the foundation of interactivity in EB. When a user selects features on the map, that selection flows to every connected widget. A List shows only the selected items. A Text widget updates to reflect the selection. A Chart recalculates. Without selection, your app is just a viewer. With selection, it becomes an analytical tool.
| Selection mode | How it works | Best for |
|---|---|---|
| Point select | Click a single feature | Inspecting one feature at a time. The default behavior. |
| Rectangle | Drag a box to select everything inside | Selecting a geographic area. Most common multi-select method. |
| Lasso | Freehand draw a selection boundary | Irregular areas, like selecting features along a river or coastline. |
| Circle | Draw a radius from a center point | "Everything within X miles of this point" analysis. |
| Line | Draw a line, selects intersecting features | Selecting features along a route or corridor. |
A regular click on the map opens the popup. It does NOT create a selection that other widgets see. The Select tool (rectangle, lasso, etc.) creates selections. This confuses everyone. If your List isn't updating when users click features, they need to use the Select tool, not just click. Alternatively, configure a message action (Intermediate lesson) to make clicks behave like selections.
Search is how users find specific features or addresses on the map. You can use the built-in search tool on the Map toolbar, or the standalone Search widget. The standalone version gives you far more control over search sources, appearance, and behavior.
Small search bar in the map toolbar. Searches the ArcGIS World Geocoding Service by default. Quick but limited.
Full search widget in your layout. Configure multiple search sources, search by attribute, control zoom behavior. Use this.
Configuring the standalone Search widget:
The #1 reason search "doesn't work" is that the search field is not indexed on the feature layer. For hosted feature layers in AGOL, go to the layer's Settings tab and enable Optimize Layer. For search to work well on large datasets, the search fields need to be indexed. Also make sure you selected the right fields in the Search widget configuration -- it's easy to accidentally pick the wrong field.
You now know: how to add a Map widget, connect a Web Map, configure tools, work with Layer List and Legend, use bookmarks, understand selection, and set up search. You have a functional, interactive map app. The Intermediate section will teach you how to make it powerful.
Multiple maps, filter-map connections, popup mastery, click-to-detail patterns, 3D scenes, and the gotchas that will save you hours of debugging.
Sometimes one map is not enough. You might want to show two time periods side by side, or display different themes (demographics vs. infrastructure) simultaneously. EB supports multiple Map widgets in the same app, each with its own Web Map.
Two maps showing different data for the same area. Before/after, or two different themes.
Pan one map, the other follows. Zoom one, both zoom. Perfectly synchronized views.
One small map showing the full extent, one large map showing the zoomed-in area.
Setting up synced maps:
If Map A syncs to Map B, and Map B syncs to Map A, you might expect an infinite loop. EB is smart enough to prevent this in most cases, but you may see slight jitter when panning quickly. If you experience this, try making only one map the "driver" (Map A -> Map B, but not B -> A). Users pan Map A, and Map B follows.
This is where EB starts to feel like a real application. The pattern is: Map displays data, Filter narrows it, List shows details. All three widgets share the same data source, and they stay in sync automatically.
The data connection model:
In EB, widgets do not connect directly to each other (in most cases). They connect to a shared data source. When the Map widget is connected to a Web Map, EB creates data sources for each layer. Other widgets connect to these same data sources. When a Filter widget filters the data source, every widget connected to that source updates.
STATUS = 'Open', or POPULATION > 50000The most common mistake when connecting widgets is picking the wrong data source. Each layer in the Web Map creates a separate data source with an auto-generated ID like dataSource_1-abc123-layer-0. If the Map, Filter, and List are not connected to the exact same data source, they won't communicate. Check the data source ID in each widget's settings -- they must match.
This is the lesson that will save you the most time. Popups belong in the Web Map, not in EB. Yes, EB has popup settings. Yes, you can override them. No, you should not. Here is why.
EB's popup override is limited, inconsistent between the builder preview and published app, and gets wiped if you reconnect the Web Map. Every popup configuration you do in EB is fragile. Do it in Map Viewer once, save the Web Map, and EB will display it perfectly.
What to configure in Map Viewer's popup settings:
| Setting | Where | Notes |
|---|---|---|
| Title | Popup config > Title | Use field values: {NAME} or Arcade: {expression/expr0} |
| Field list | Popup config > Fields list | Choose which fields to show, rename them, set formatting (dates, numbers) |
| Arcade expressions | Popup config > Arcade | Calculated values in popups: classifications, math, conditional text |
| Charts | Popup config > Media | Pie charts and bar charts from field values. Great for multi-category data. |
| Images | Popup config > Media | Image from URL field. Supports Arcade for dynamic URLs. |
| Custom HTML | Popup config > Custom attribute display | Full HTML/CSS for complex layouts. The most powerful option. |
| Related records | Popup config > Related records | Show child records from related tables. Automatic if relationships exist. |
// Arcade expression in a popup: shelter capacity status var current = $feature.CURRENT_POP var capacity = $feature.CAPACITY var pct = Round((current / capacity) * 100, 0) var status = "Available" if (pct > 90) { status = "Near Capacity" } if (pct >= 100) { status = "FULL" } return pct + "% full (" + status + ")"
Popups are fine for quick info, but for a real application, you want a detail panel -- a sidebar or bottom panel that shows full information about the clicked feature. This is the most professional-looking pattern in EB apps and it replaces the floating popup entirely.
Building a click-to-detail panel:
A popup is like a Post-it note -- quick info, limited space, disappears easily. A detail panel is like opening the full file folder -- room for charts, images, related records, action buttons. For public-facing apps, use popups. For operational dashboards, use detail panels.
The Map widget can display Web Scenes (3D) in addition to Web Maps (2D). When you connect a Web Scene, the widget becomes a 3D viewer with tilt, rotation, and elevation. This is powerful for specific use cases, but 3D comes with tradeoffs.
Building inspections (see rooftops). Terrain analysis (flood modeling). Elevation profiles. Urban planning (shadow analysis). Site inspections where height matters.
General dashboards. Thematic maps (choropleth). Tabular data display. Anything where users just need to see "where things are" on a flat map. Most apps.
If you're debating between 2D and 3D, use 2D. Only go 3D when height or elevation is genuinely part of the analysis. A 3D map that's just "flat data floating above a terrain surface" adds complexity without value.
This lesson is the one you'll come back to. These are the issues that waste hours and aren't documented well. Every one of these has bitten experienced EB developers.
| Problem | Cause | Fix |
|---|---|---|
| Map shows old data after editing the Web Map | Browser cache or CDN cache serving the old version | Hard refresh (Ctrl+Shift+R). If still stale, re-select the Web Map in the Map widget settings (disconnect then reconnect). In stubborn cases, open the published URL in an incognito window. |
| Initial extent doesn't save after publish | EB sometimes ignores the custom extent setting | Set the initial extent in the Web Map (save the map at the view you want), not in EB. The Web Map extent is more reliable than the EB override. |
| Layers disappear in published app | Layers are shared to a different group than the app, or the layer's sharing level is more restrictive than the app's | Check that every layer in the Web Map is shared at the same level (Public/Org/Group) as the app. The Map widget silently hides layers the viewer can't access. |
| Search doesn't find features | Search field isn't indexed, or wrong field selected | Go to the feature layer Settings in AGOL. Enable "Optimize Layer Drawing and Querying." Verify the correct field is selected in the Search widget config. |
| Selection doesn't trigger other widgets | Click opens popup, not a selection. Or widgets on different data sources. | Use the Select tool (rectangle/lasso), not single-click. Verify all widgets share the same data source ID. Or configure a Record Selection Changes message action. |
| Map is blank / grey in builder | Web Map was deleted, moved, or you lost access | Check the Web Map still exists in your AGOL content. Re-share if needed. If deleted, you need to reconnect a new Web Map. |
| Labels show in Map Viewer but not in EB | EB respects visibility ranges. Labels may be set to show at a zoom level different from the initial extent. | Check the label visibility range in Map Viewer. Set it to match the zoom level your EB app will use. Or zoom in/out in the published app to verify. |
| Map tools work in builder but not in published app | The tool was enabled in the builder but the published app uses different settings | Save the EB app, then re-publish. Check that you're not looking at a cached older version of the published app. Clear browser cache. |
You now know how to use multiple maps, connect maps to filters and lists, configure popups properly (in Map Viewer), build click-to-detail panels, handle 3D, and debug the most common issues. Your EB apps are now genuinely interactive. The Advanced section will make them production-grade.
URL parameters, performance optimization, multi-source data, disaster response map patterns, and the map-centric app architecture that powers real operational tools.
URL parameters let you deep link to a specific map state: a particular extent, selected features, or filtered view. This is how you share "look at this specific area" links or embed map views in emails and reports.
EB supports several URL parameters out of the box. You append them to your app URL with ? for the first and & for additional parameters.
| Parameter | What it does | Example |
|---|---|---|
center | Centers the map at longitude,latitude | ?center=-77.03,38.89 |
level | Sets the zoom level (0-23) | ?center=-77.03,38.89&level=12 |
extent | Sets a bounding box (xmin,ymin,xmax,ymax) | ?extent=-78,38,-76,39 |
viewpoint | Alias for center and level combined | ?viewpoint=-77.03,38.89,12 |
// Center on Washington DC at zoom level 12 https://experience.arcgis.com/experience/abc123?center=-77.03,38.89&level=12 // Show a specific extent (bounding box) https://experience.arcgis.com/experience/abc123?extent=-78.5,38.0,-76.5,39.5 // Open a specific page in a multi-page app https://experience.arcgis.com/experience/abc123?page=page-2 // Combine parameters https://experience.arcgis.com/experience/abc123?center=-77.03,38.89&level=14&page=detail
document.querySelector('.esri-view').view.extentURL parameters override both the EB custom extent and the Web Map saved extent. If someone bookmarks a URL with extent parameters, they will always see that extent, even if you update the Web Map. This is usually what you want, but be aware of it when debugging "the map always opens to the wrong place" reports.
?filter-status=Open&filter-region=SoutheastA slow map kills your app. Users will wait maybe 3 seconds for a map to load. After that, they leave. Performance optimization is not optional for production apps -- it is a requirement. Here is what actually moves the needle.
The single biggest performance factor is your layer type. Tile layers and Vector Tile layers are orders of magnitude faster than Feature layers for display.
Feature layers download every feature to the browser as GeoJSON. 100K features = 100K geometries + attributes sent over the wire. Use them only when you need interactivity.
| Layer type | Speed | Interactivity | Use when |
|---|---|---|---|
| Vector Tile Layer | Fastest | None (display only) | Basemaps, boundaries, reference layers. Anything users only look at. |
| Tile Layer (raster) | Very fast | None (display only) | Imagery, pre-rendered thematic maps. Static reference. |
| Map Image Layer | Fast | Identify (popup) | Large datasets that need popups but not selection or editing. Server does the rendering. |
| Feature Layer | Slower | Full (select, edit, filter) | Interactive layers: selection, filtering, editing, Arcade, List connections. The workhorse. |
| OGC WMS/WFS | Variable | Limited | External data sources. Performance depends on the external server. |
Concrete optimization strategies:
STATE = 'NC'. This filters server-side before data reaches the browser.For point layers with many features, clustering in Map Viewer dramatically improves performance and readability. Instead of rendering 10,000 individual points, the map shows cluster bubbles with counts. Users zoom in to see individual features. Enable it in Map Viewer under Layer Properties > Clustering. It works in EB out of the box -- no extra configuration needed.
Production maps often combine data from multiple sources: your org's hosted layers, Living Atlas layers, external WMS/WFS services, CSV files, and GeoJSON. Understanding how to combine them -- and the authentication implications -- is essential for real-world apps.
| Data source | How to add | Authentication | Notes |
|---|---|---|---|
| AGOL Hosted Layers | Add to Web Map from your content | Org login or public sharing | Fastest, most reliable. Your primary data source. |
| ArcGIS Living Atlas | Add to Web Map from Living Atlas | Most are public, some need AGOL subscription | Demographics, boundaries, imagery, environmental data. Extremely useful reference layers. |
| ArcGIS Enterprise Layers | Add to Web Map via URL or search | Enterprise login (may require portal trust) | On-premises data. Can be slower than AGOL hosted. Watch for firewall issues. |
| WMS / WFS (OGC) | Add to Web Map via URL | Usually public or API key | External services (NOAA weather, USGS). Performance varies. No editing. |
| CSV / GeoJSON | Upload to AGOL first, add as hosted layer | Inherits AGOL sharing settings | Great for one-time data. Remember to update the hosted layer when data changes. |
| Image Services | Add to Web Map via URL | Depends on server | Satellite imagery, aerial photos, raster analysis. Can be very large. |
If your Web Map includes a secured layer (requires login), every user of your EB app will be prompted to log in -- even if the app itself is public. This is the #1 source of "my app works for me but not for others" reports. Before publishing, open the app in an incognito window without logging in. If you see a login prompt, you have a sharing issue. Fix it by making the layer public, or share it to a group that includes your app's intended audience.
// Useful Living Atlas layers to add to your Web Map: USA Counties // County boundaries with FIPS codes USA States // State boundaries USA Census Tracts // Tract-level demographics USA Social Vulnerability Index // CDC SVI data World Imagery // Satellite basemap USA Flood Hazard Areas // FEMA flood zones USA Weather Watches and Warnings // Live NWS alerts USA Wildfires // Active fire perimeters USA Red Cross Regions // ARC organizational boundaries
This lesson brings everything together with production patterns from actual disaster response EB apps. These are the map configurations and widget connections that power real operational tools.
Pattern 1: Shelter Status Map
A map showing shelter locations with color-coded status indicators. Green = Open, Yellow = Near Capacity, Red = Closed. Click a shelter to see capacity details in a side panel.
// Shelter capacity popup expression var current = $feature.CURRENT_POP var capacity = $feature.CAPACITY if (IsEmpty(capacity) || capacity == 0) { return "Capacity not set" } var pct = Round((current / capacity) * 100, 0) var remaining = capacity - current var indicator = IIf(pct > 90, "CRITICAL", IIf(pct > 75, "Filling up", "Available")) return pct + "% occupied (" + current + "/" + capacity + ") - " + indicator + "\n" + remaining + " spots remaining"
Pattern 2: Damage Assessment Map
Damage assessment data with classification-based symbology and a dashboard-style summary. Rectangle selection for area-based analysis.
Pattern 3: Evacuation Zone Map
Polygon zones with interactive zone lookup. Users search an address or click the map to find which zone they're in.
The most powerful EB architecture puts the Map widget at the center of everything. Every other widget responds to what's visible on the map. When the user pans, zooms, or selects, the entire app updates. This is the map-centric app architecture, and it is the professional standard for operational GIS dashboards.
In a map-centric app, the map is the DJ at a party. The DJ controls the music, and everyone on the dance floor (List, Chart, Text, Filter) responds to what the DJ plays. Change the song (pan the map), and the entire room shifts. This is different from the "widget-centric" approach where a Filter or List drives the map. In the map-centric approach, the map drives everything else.
The three map triggers that drive other widgets:
User pans or zooms. All connected widgets recalculate based on what's visible. "Show me stats for what I can see."
User selects features with the Select tool. All connected widgets update to show only selected features.
A Filter widget filters the shared data source. The map and all other widgets show only matching features.
Building a map-centric dashboard:
$dataSources["..."].layer and queryParams to show aggregate stats that respect the spatial filter. "X features in view. Total population: Y."// This Arcade expression respects spatial filtering // When the user pans/zooms, the stats update automatically function getFilteredFeatureSet(ds) { var result = ds.layer var qp = ds.queryParams if (!IsEmpty(qp.where)) { result = Filter(result, qp.where) } if (!IsEmpty(qp.geometry)) { result = Intersects(result, qp.geometry) } return result } var ds = $dataSources["YOUR_DS_ID"] var filtered = getFilteredFeatureSet(ds) var selected = ds.selectedFeatures var target = IIf(Count(selected) > 0, selected, filtered) var count = Count(target) var label = IIf(Count(selected) > 0, "Selected", "In view") return '<p style="font-size:28px;font-weight:bold;margin:0;">' + Text(count, '#,###') + '</p><p style="font-size:12px;color:#888;margin:2px 0 0;">' + label + ' features</p>'
Map shows all shelters for a hurricane event. The Filter widget is set to "Open shelters." The user pans to the affected county. The List updates to show only open shelters in view. The Arcade Text widgets show: "12 shelters in view | 847 residents | 68% capacity." The user draws a rectangle around a cluster. Now the stats update to "3 selected | 215 residents | 82% capacity." They click one shelter. The detail panel opens with name, address, capacity chart, contact info, and a link to Google Maps for driving directions. All of this is the Map widget driving the entire experience.
You've gone from "what is the Map widget" to URL parameters, performance optimization, multi-source data management, disaster response map patterns, and the map-centric app architecture that powers real operational tools. These 18 lessons cover everything you need to build production-grade map applications in Experience Builder. The Map widget is the foundation -- master it, and every other widget falls into place.