Power-user patterns that separate functional apps from great ones. URL deep links, data pipelines, Arcade styling, performance, and the new AI Assistant.
Three tips you can apply in under five minutes. No code, no complex configuration — just toggles and settings that immediately improve your apps.
Experience Builder URL parameters are notoriously complex. They require knowledge of internal data source IDs, widget IDs, proper URL encoding, and JSON-like syntax. A typical parameterized URL looks like this:
https://experience.arcgis.com/experience/abc123 ?data_filter=dataSource_1-layer_0:status%3D%27Active%27 #map_1=center:-9175753,3251009,102100&map_1=scale:500000
Nobody wants to hand-write that. Get one character wrong and the whole thing fails silently — the app loads but the parameter is ignored.
The solution: Let the app write the parameters for you. The Share widget captures your current app state as a URL.
Open any EB app in the builder, drop in a Share widget, preview it, zoom to a specific area, turn off a layer, and click Share. Look at the URL it produces. You'll see exact parameter syntax for center, scale, layer visibility, and filters — all properly encoded.
Remove the Share widget before publishing if you don't want end users to see it — it's purely a development tool. Save the generated URLs in a reference doc so you don't have to regenerate them.
You build an EB app with a tabbed Section widget: View 1 is a Map, View 2 is a Chart dashboard, View 3 is a Table, View 4 is a gallery. On page load, EB renders all views simultaneously — even though the user only sees View 1. Everything initializes at once, and the page takes 10-15 seconds to load.
One toggle fixes this: Select your Section widget → Settings → find "Lazy Loading" → turn it ON.
| Behavior | Without Lazy Loading | With Lazy Loading |
|---|---|---|
| Page load | All views render at once | Only the visible view renders |
| Tab switch (first visit) | Instant (already loaded) | 1-3 second delay |
| Tab switch (return) | Instant | Instant (stays loaded) |
| Memory usage | High (all views in DOM) | Lower (only visited views) |
Without lazy loading, opening a restaurant means firing up every oven, grill, and deep fryer at 6 AM — even though the first order won't come in until noon. Lazy loading means you turn on equipment when the first order for that station comes in.
Use it when: 3+ views, views contain Maps/Charts/Tables, users typically visit only 1-2 views, mobile performance matters.
Don't use it when: Only 2 simple views, all views will be visited every session, the brief loading delay would be disruptive (e.g., a real-time monitoring dashboard).
You build a desktop app with a sidebar, legend, filter bar, and full-screen map. Switch to mobile preview: everything overlaps or squishes. The instinct: delete the sidebar. But in EB, deleting from one layout deletes from ALL layouts. Now your desktop is broken too.
The Pending List is a holding area. Widgets moved there are fully configured, invisible to users on that device layout, and still exist on other layouts.
| Widget Type | Mobile Strategy |
|---|---|
| Side panels / Sidebars | Hide → replace with bottom sheet or overlay |
| Legends | Hide → use Map's built-in layer list toggle |
| Filter bars (horizontal) | Hide → replace with compact filter button |
| The Map | KEEP → make it 100% width |
| Primary List | KEEP → make it full-width |
| Search bar | KEEP → essential for mobile navigation |
Always switch to Custom layout mode for responsive work. Auto mode makes educated guesses, but they're frequently wrong — it might stack a sidebar below the map instead of hiding it.
These tips require understanding specific syntax or configuration details, but no code. Master these and you'll unlock capabilities most EB users never discover.
You embed a Dashboard inside your EB app. Both are secured. The user signs into the parent EB app, then gets a second sign-in prompt for the embedded Dashboard. Confusing, frustrating, unprofessional.
Fix: Append ?arcgis-auth-origin=https://experience.arcgis.com to the embedded app's URL.
https://experience.arcgis.com/experience/abc123https://yourorg.maps.arcgis.com/apps/dashboards/def456 ?arcgis-auth-origin=https://experience.arcgis.com &arcgis-auth-portal=https://yourorg.maps.arcgis.com &org=yourorgshortname
| App Type | Shared Auth Works? |
|---|---|
| ArcGIS Dashboard | Yes — most common use case |
| Another EB app | Yes — nested EB apps work well |
| Web AppBuilder app | Yes |
| ArcGIS StoryMap | Yes |
| Custom web app (non-ArcGIS) | No — must implement ArcGIS Identity manually |
?org=yourorgshortname — skips the generic login page, goes directly to your org's branded sign-in (important for SAML/SSO/2FA orgs)?arcgis-auth-portal=https://yourorg.maps.arcgis.com — forces auth against a specific portal (useful for orgs with both AGOL and Enterprise)As of the February 2026 ArcGIS Online update, the Arcade expression editor includes an AI-powered assistant (beta). Describe what you want in plain English and it generates the Arcade expression.
{} icon| Task | AI Quality |
|---|---|
| Conditional formatting (IIf, When, Decode) | Excellent |
| Date math (DateDiff, DateAdd, formatting) | Excellent |
| String concatenation and formatting | Good |
| Basic HTML output generation | Good |
| FeatureSet queries (cross-layer lookups) | Fair |
| Complex spatial calculations | Poor — write these manually |
Arcade can return formatted HTML using supported tags: <h1>-<h6>, <p>, <span>, <strong>, <em>, <a>, <img>, <ul>/<ol>/<li>, <br>. Not supported: <div>, <table>, <style>, <script>.
var name = $feature.ChapterName var activeOps = $feature.ActiveOperations var daysAgo = Floor(DateDiff(Now(), $feature.EditDate, "days")) var statusColor = When( activeOps > 5, "red", activeOps > 0, "orange", "green" ) return "<h3>" + name + "</h3>" + "<p style='color:" + statusColor + "; font-weight:bold'>" + activeOps + " operations</p>" + "<p style='color:#666; font-size:12px'>Updated " + daysAgo + " days ago</p>"
Each page supports a maximum of 10 Arcade expressions (dynamic styling + content + data expressions + Arcade filters combined). Budget carefully. If you need more: move widgets to a different page, use Section views (separate expression budget), or pre-calculate values in your Feature Layer.
While Tip 1 auto-generates URLs, this tip teaches you the actual syntax so you can construct deep links programmatically — from external systems, email templates, or code.
| Type | Syntax | Purpose |
|---|---|---|
| Query parameters | ?key=value | Data filters, page navigation, extent, auth |
| Hash parameters | #key=value | Map state: center, zoom, layers, markers |
Center and scale:
// Web Mercator coordinates + scale #map_1=center:-9175753,3251009,102100&map_1=scale:500000 // Lat/lon alternative #map_1=center:-82.64,27.77,4326&map_1=scale:500000
Layer visibility:
#map_1=layer_visibility:{"dataSource_1":{"layer-2":false,"layer-3":true}}Drop markers:
#map_1=marker:-82.64,27.77;4326;St Petersburg;Click here for details
Pre-filter data:
?data_filter=dataSource_1-layer_0:status='Active' AND region='Southeast'
Combined URL — the real power:
https://experience.arcgis.com/experience/abc123 ?data_filter=dataSource_1-layer_0:region='Southeast' &page=page_2 #map_1=center:-9175753,3251009,102100 &map_1=scale:500000 &map_1=layer_visibility:%7B%22dataSource_1%22%3A%7B%22layer-2%22%3Afalse%7D%7D
| Scale | Approximate View |
|---|---|
150,000,000 | World |
20,000,000 | Country |
5,000,000 | Multi-state region |
500,000 | Metro area |
50,000 | City |
10,000 | Neighborhood |
Create a set of links for stakeholders — each link opens the same app pre-filtered and pre-zoomed to their region. Email them the links. One app, personalized views.
These four tips change how you think about building EB apps. They're architectural patterns — data pipelines, independent views, dynamic styling, and cross-page workflows — that power production-grade applications.
This is the most powerful architectural pattern in EB that most users never discover. Certain widgets don't just display data — they produce new data sources at runtime. These output data sources can be consumed by other widgets, creating processing pipelines entirely through configuration.
Unix pipes: cat file | grep "error" | wc -l — each command takes input from the previous one. In EB, each widget takes data from the previous widget's output.
| Widget | What It Produces | Output Contains |
|---|---|---|
| Query | Filtered record set | Records matching criteria |
| Chart | Statistics | Sum, average, count, min, max |
| Near Me | Proximity results | Features within distance + summary |
| Search | Geocoded locations | Address match results |
| Filter | Filtered subset | Features passing criteria |
Pattern 1: Basic Pipeline (Query → List + Chart)
Pattern 2: Two-Level Pipeline (Query → Chart → Text)
Without pipelines, if your filter logic changes, you update it in 3+ separate places (one per widget). With pipelines, you update it in one place — the Query widget — and all downstream widgets reflect the change automatically.
You have a Map and a List both connected to the same Feature Layer. You add a filter to the List for "Active" incidents. The Map also filters to Active — your historical incidents vanish from the map. Everything connected to the same data source shares the same filter state.
This is the #1 frustration for intermediate EB builders.
The solution: Named Data Views. A Data View is a configured lens on a data source with its own filter, sort, and record limit. Multiple widgets each use a different view, operating independently.
+ icon next to it| Action Target | What Happens |
|---|---|
| Filter on the Default View | ALL widgets using that data source are affected |
| Filter on a Named View | ONLY widgets using that specific view are affected |
Use the Default View for global interactions (user clicks map → everything updates). Use Named Views for isolated interactions (filter panel → only the list updates). This is the single most important thing to understand about EB data architecture.
Map symbology changes how features look on the map. Dynamic styling changes how widgets look in the UI. A List item can turn red when overdue. A Text block can change colors based on severity. This is conditional formatting for Experience Builder.
| Widget | What You Can Style | Profile Variable |
|---|---|---|
| List (per item) | Background, border, text of each row | $feature |
| Text | Background, border, font | $dataSource |
| Button | Background, border, text color | $dataSource |
| Card | Background, border | $feature |
{} next to Background or Bordervar status = $feature.Status var bgColor = When( status == "Critical", "rgba(255, 59, 48, 0.15)", status == "Active", "rgba(255, 149, 0, 0.15)", status == "Monitoring", "rgba(255, 204, 0, 0.10)", status == "Resolved", "rgba(52, 199, 89, 0.10)", "rgba(200, 200, 200, 0.05)" ) var borderColor = When( status == "Critical", "#FF3B30", status == "Active", "#FF9500", status == "Monitoring", "#FFCC00", status == "Resolved", "#34C759", "#CCCCCC" ) return { background: { color: bgColor }, border: { type: "solid", color: borderColor, width: "2px" } }
var daysOverdue = DateDiff(Now(), $feature.DueDate, "days") if (daysOverdue > 0) { return { background: { color: "rgba(255, 59, 48, 0.2)" }, border: { type: "solid", color: "#FF3B30", width: "3px" } } } else if (daysOverdue > -3) { return { background: { color: "rgba(255, 204, 0, 0.15)" }, border: { type: "solid", color: "#FFCC00", width: "2px" } } } else { return { background: { color: "rgba(52, 199, 89, 0.05)" }, border: { type: "solid", color: "#34C759", width: "1px" } } }
Dynamic styling expressions count toward the per-page limit of 10 Arcade expressions. Budget them alongside dynamic content, data expressions, and Arcade filters.
Most EB users know about triggers within a single page. But the system is far more powerful:
Multiple actions fire from a single trigger, executing sequentially
Actions can target widgets on other pages
Complex interactive workflows without any code
Multi-Action Chain: User clicks a feature → map pans and zooms → sidebar opens → list filters → feature flashes.
Cross-Page Pattern: Overview page → user clicks a region → app navigates to detail page pre-filtered.
| Tip | What | Complexity |
|---|---|---|
| 1. Share Widget URLs | Auto-generate URL parameters | Low |
| 2. Lazy Loading | Defer rendering of hidden Section views | Low |
| 3. Pending Mode | Hide widgets per device without deleting | Low |
| 4. Shared Auth | Single sign-on for embedded apps | Low |
| 5. AI Assistant | Natural language → Arcade + HTML output | Low-Med |
| 6. Hash Parameters | Manual deep linking syntax | Medium |
| 7. Data Pipelines | Widget-to-widget output chaining | Medium |
| 8. Data Views | Independent widget filtering | Medium |
| 9. Arcade Styling | Data-driven widget colors/borders | Med-High |
| 10. Cross-Page Triggers | Multi-page interactive workflows | Medium |