Skip to content

Latest commit

 

History

History
467 lines (355 loc) · 16 KB

File metadata and controls

467 lines (355 loc) · 16 KB

Experience Builder Widget Development: Complete Process Guide

This guide walks through the full process — from installing Experience Builder to having a working custom widget — using Claude (the app) for design and Claude Code for implementation.


Phase 1: Environment Setup

Step 1: Install Node.js 22

Download and install Node.js 22 LTS from https://nodejs.org/

Verify:

node --version   # Should show v22.x.x
npm --version    # Should show 10.x.x

Step 2: Download Experience Builder Developer Edition 1.19

  1. Go to https://developers.arcgis.com/experience-builder/
  2. Sign in with your ArcGIS Developer or organizational account (needs Creator or Professional user type)
  3. Download the Developer Edition ZIP (version 1.19)

Step 3: Extract and Place ExB

Extract the ZIP to a dedicated development directory. Avoid paths with spaces.

Recommended locations:

Windows:

C:\Dev\ArcGISExperienceBuilder\

Mac/Linux:

~/Dev/ArcGISExperienceBuilder/

After extraction you should see:

ArcGISExperienceBuilder/
├── client/
│   ├── your-extensions/        ← Your custom widgets will go here
│   │   ├── manifest.json       ← Extension repo manifest (already exists)
│   │   └── widgets/            ← Widget folders go here
│   ├── dist/
│   ├── package.json
│   └── tsconfig.json
├── server/
│   ├── package.json
│   └── ...
└── ...

Step 4: Install Dependencies

Open two terminal windows. You'll keep both open throughout development.

Terminal 1 — Server (install first):

cd ArcGISExperienceBuilder/server
npm ci

Terminal 2 — Client (install second):

cd ArcGISExperienceBuilder/client
npm ci

npm ci does a clean install from the lockfile. Takes a few minutes the first time.

Step 5: Start ExB and Verify It Works

Start the server FIRST, then the client. The client connects to the server, so the server needs to be running.

Terminal 1:

cd ArcGISExperienceBuilder/server
npm start

Terminal 2:

cd ArcGISExperienceBuilder/client
npm start

Open the URL shown in Terminal 1 output (check carefully — port varies by version, usually 3000 or 3001). Accept the self-signed certificate warning. Sign in with your ArcGIS organizational account.

You should see the Experience Builder app gallery. Create a quick test app — add a Map widget, point it at a web map, and preview it to confirm the environment works.

Leave both terminals running. You'll restart the client service when adding new widget folders, but the server stays up.

Step 6: Verify the Extension Folder

Confirm client/your-extensions/manifest.json exists and looks like:

{
  "name": "your-extensions",
  "type": "exb-web-extension-repo",
  "description": "Custom widgets",
  "version": "1.0.0"
}

Confirm client/your-extensions/widgets/ directory exists (may be empty — that's fine).

Confirm client/tsconfig.json includes "your-extensions" in its include array. If not, add it.


Phase 2: Set Up Claude Code for ExB Development

Step 7: Place the CLAUDE.md File

Copy the CLAUDE.md file into the ExB project root:

ArcGISExperienceBuilder/
├── CLAUDE.md                          ← Place here (project root)
├── client/
├── server/
└── ...

Claude Code reads this file automatically when you open it in this directory. It contains the import rules, manifest conventions, compatibility matrix, common errors, and development workflow.

Step 8: Place the Developer Guide

Create a docs/ folder in the project root and place CustomWidgetDeveloperGuide.md there:

ArcGISExperienceBuilder/
├── CLAUDE.md
├── docs/
│   └── CustomWidgetDeveloperGuide.md  ← Place here
├── client/
├── server/
└── ...

The CLAUDE.md already references this file and tells Claude Code to read it before starting widget work.

Step 9: Clone the Sample Widgets (Optional but Recommended)

cd ArcGISExperienceBuilder
git clone https://github.com/Esri/arcgis-experience-builder-sdk-resources.git samples

This gives Claude Code ~40 real working examples to reference when writing code.

Step 10: Verify Final Project Structure

ArcGISExperienceBuilder/
├── CLAUDE.md                              # Claude Code reads this automatically
├── docs/
│   └── CustomWidgetDeveloperGuide.md      # Comprehensive patterns & examples
├── samples/                               # (Optional) Esri sample widgets
│   └── widgets/
│       ├── starter-widget/
│       ├── get-map-coordinates-function/
│       └── ...40+ more samples
├── client/
│   ├── your-extensions/
│   │   ├── manifest.json                  # Extension repo manifest
│   │   └── widgets/                       # YOUR widgets go here
│   ├── tsconfig.json
│   └── package.json
├── server/
│   └── ...
└── ...

Your environment is now ready.


Phase 3: Design Your Widget (Claude App)

Step 11: Open a New Conversation in Claude

Copy the starter prompt from starter-prompt-for-claude-app.md into a new Claude conversation. This prompt gives Claude the technical context (ExB 1.19, JSAPI 4.34, React 19, Jimu conventions) and tells it exactly what to produce.

Add your widget description at the bottom. Be specific about:

  • What the widget does from the user's perspective
  • What data it interacts with (maps, layers, services)
  • What the settings panel should let admins configure
  • Any external APIs or services it calls

Example for the smart-filter widget:

I want to build a widget called "smart-filter" that takes plain text input from a user (like "parcels larger than 5 acres near downtown") and converts it to an ArcGIS where clause, then applies that filter to the appropriate layer(s) on the map.

The widget should:

  • Have a text input where the user types a natural language query
  • Parse that text to generate a valid SQL where clause
  • Identify which layer(s) the query applies to based on field names
  • Apply the filter to the correct layer's definitionExpression on the map
  • Show the user what where clause was generated so they can verify/edit it
  • Have a clear/reset button to remove filters
  • Have a settings panel where the admin selects which map widget to connect to and configures which layers/fields are available for filtering

Step 12: Review and Refine the Plan

Claude will produce a design document with architecture, file structure, APIs, an implementation plan, JSAPI deprecation flags, and edge cases.

Review carefully. Key things to check:

  • Does the file structure match ExB conventions?
  • Are the Jimu API choices correct?
  • Are there technical decisions you want to change?
  • Does the implementation plan build progressively (minimal → full)?
  • Any JSAPI classes flagged as uncertain — verify these

Iterate until the plan is solid. Save the final plan text — you'll paste it into Claude Code.


Phase 4: Build the Widget (Claude Code)

Step 13: Open Claude Code in the ExB Directory

cd ArcGISExperienceBuilder
claude

Claude Code automatically reads CLAUDE.md and knows it's in an ExB project.

Step 14: Give Claude Code the Plan and Instructions

Paste something like this, followed by your plan:

I want to build a custom Experience Builder widget. Here's my reviewed design plan.

Before starting:
1. Read CLAUDE.md (you should have already)
2. Read docs/CustomWidgetDeveloperGuide.md for detailed patterns
3. Check the compatibility matrix — we're on ExB 1.19, JSAPI 4.34, React 19
4. Watch for JSAPI deprecations in 4.34

Build this progressively:
- Start with a minimal widget that just renders a text input (verify it loads)
- Then add the core filtering logic
- Then add the settings panel
- Then add polish (error handling, loading states, etc.)

The plan is in PLAN.MD

Review the plan, ask questions and then build your plan.

Step 15: First Build — The Minimal Widget

Claude Code will create the widget files. After it creates the initial set:

  1. Stop the client service (Ctrl+C in Terminal 2)
  2. Restart it (npm start in client/) — necessary because new widget folder was added
  3. Open ExB builder at the URL shown in Terminal 1
  4. Create a new app or open an existing one
  5. Look for your widget in the widget panel — it should appear under custom/organization widgets
  6. Add it to the app and preview

If the widget appears and renders your basic text → you're in great shape. Tell Claude Code to proceed to the next step in the plan.

If it doesn't appear → check these in order:

  • Is the folder name exactly matching name in manifest.json?
  • Is client/tsconfig.json including your-extensions?
  • Did you restart the client service?
  • Check Terminal 2 for TypeScript compilation errors
  • Check browser console (F12) for runtime errors

Step 16: Iterate Progressively

This is the core development loop:

  1. Claude Code adds functionality (hooks, components, logic)
  2. You check the browser — does it still work?
  3. If yes → continue to next feature
  4. If no → check browser console, report the error to Claude Code, it fixes it

You do NOT need to restart the client for code changes within existing files. Webpack hot-reloads those automatically. Just refresh the browser.

You DO need to restart the client if Claude Code:

  • Creates new files or folders
  • Renames files or folders
  • Edits manifest.json
  • Installs npm packages

Step 17: Test the Settings Panel

Once Claude Code has built the settings panel:

  1. In the ExB builder, click on your widget to select it
  2. The settings panel should appear on the right side
  3. Configure it (select a map widget, choose layers, etc.)
  4. Switch to preview mode and verify the widget works with the configuration

If the settings panel doesn't appear:

  • Make sure src/setting/setting.tsx exists
  • Make sure manifest properties is {} (empty) — let ExB auto-detect
  • Restart the client service

Step 18: Polish

Once core functionality works, ask Claude Code for:

  • Error handling for edge cases (no data, network errors, empty results)
  • Loading states and user feedback
  • Graceful handling of unconfigured state
  • Accessibility (ARIA labels, keyboard navigation)
  • Theme-aware styling using Jimu theme variables
  • Any i18n translations needed

Phase 5: Production and Deployment

Step 19: Build for Production

cd ArcGISExperienceBuilder/client
npm run build:prod

Output goes to client/dist-prod/widgets/your-widget-name/.

The production build includes your compiled widget code, bundled external libraries (like d3 if used), CSS, and all assets — but NOT jimu-, react, or esri/ (those are loaded as externals at runtime).

Step 20: Deploy

Option A — Standalone hosting: Deploy the full built ExB app to your web server (includes your widgets).

Option B — ArcGIS Enterprise (11.0+):

Requirements:

  • HTTPS web server accessible by Portal
  • CORS headers allowing your Portal domain
  • JSON MIME type configured
  • Anonymous access enabled for the widget files
  1. Copy dist-prod/widgets/your-widget-name/ to your web server
  2. Configure CORS and MIME types (see IIS example below)
  3. In Portal: My Content → Add Item → Application → Experience Builder Widget
  4. Enter manifest URL: https://your-server.com/widgets/widget-name/manifest.json
  5. Share with your organization
  6. Widget appears in the Custom group in ExB

IIS web.config example (place in widget hosting directory):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin"
             value="https://your-portal.domain.com" />
        <add name="Access-Control-Allow-Methods" value="GET, OPTIONS" />
      </customHeaders>
    </httpProtocol>
    <staticContent>
      <mimeMap fileExtension=".json" mimeType="application/json" />
    </staticContent>
  </system.webServer>
</configuration>

Version compatibility note: If your Enterprise is 11.5 (ExB 1.17), make sure your manifest has "exbVersion": "1.17.0" even if you developed with ExB 1.19.

Option C — Distribution to other developers: Package the widget folder (source) for others to drop into their ExB your-extensions/widgets/ directory.


Quick Reference Card

Commands

Task Command
Start server (first) cd server && npm start
Start client (second) cd client && npm start
Build production cd client && npm run build:prod
Open Claude Code cd ArcGISExperienceBuilder && claude
Install external lib cd client && npm install <package> --save
Clone samples git clone https://github.com/Esri/arcgis-experience-builder-sdk-resources.git samples

When to Restart the Client

RESTART the client service after:

  • Adding or removing a widget folder
  • Renaming any file or folder
  • Editing any manifest.json
  • Installing new npm packages
  • Changing tsconfig.json

NO RESTART needed for:

  • Editing .tsx, .ts, .css files within an existing widget (hot reload handles it)
  • Changing config.json values
  • Editing translation files

Troubleshooting

Problem Likely Cause Fix
Widget not in builder panel Manifest error or client not restarted Check manifest.json syntax, restart client
can't access property "default", t is null Importing React/hooks from 'react' Import from 'jimu-core' instead
Unknown dependency: jimu-core jimu-core listed in manifest dependency array Remove it — only jimu-arcgis belongs there
Module not found: jimu-core/react Importing from jimu-core/react Import from jimu-core only
Settings panel doesn't show Over-specified manifest properties Use "properties": {} (empty)
Map doesn't connect Missing dependency in manifest Add "dependency": ["jimu-arcgis"]
TypeScript compilation errors Extension not in tsconfig Add to client/tsconfig.json include array
__set_webpack_public_path__ is null Trying to build outside ExB Always use ExB Dev Edition build system
Blank widget in preview Uncaught error in render Check browser console (F12) for errors
Widget loads but crashes Null reference on unconfigured state Add null checks for useDataSources, useMapWidgetIds
404 on Enterprise deploy Widget server not accessible Check HTTPS, CORS, JSON MIME type config

Files You Need

File Where to Put It Purpose
CLAUDE.md ExB project root Auto-read by Claude Code. Import rules, manifest conventions, patterns.
CustomWidgetDeveloperGuide.md docs/ folder Comprehensive reference. Full code examples for all widget patterns.
starter-prompt-for-claude-app.md Anywhere (for your use) Template for designing widgets in Claude app before coding.
Esri samples repo samples/ folder (optional) 40+ working widget examples Claude Code can reference.

The Golden Rules

  1. React from jimu-core, never from 'react' — in ALL files, not just widget.tsx
  2. AllWidgetSettingProps from jimu-for-builder, never from jimu-core
  3. Never put jimu-core or jimu-ui in manifest dependency array — only jimu-arcgis
  4. Keep manifest properties empty {} — let ExB auto-detect
  5. Config is immutable — use .set() / .setIn(), never mutate
  6. Start server before client — client connects to server
  7. Restart client after structural changes — new files, renames, manifest edits
  8. Build progressively — minimal widget first, add features one at a time, test each step
  9. Never build outside ExB — its SystemJS/webpack setup can't be replicated
  10. Plan before coding — design in Claude app, implement in Claude Code
  11. One widget at a time — finish and verify before starting the next