Widget Development Setup¶
This guide explains the workflow for developing and testing CSS/UI changes in the Rose widget. For comprehensive technical knowledge about the widget architecture, see Widget Technical Knowledge.
Overview¶
When making frontend changes to the widget, use this multi-step approach:
- Preprod UI (port 3001) - Fast iteration for CSS/UI changes with hot reloading
- Widget Demo (port 8083) - Production-like testing with Shadow DOM behavior
- Chrome Plugin (optional) - Test website-dependent behavior on real client sites locally
- Client Production (optional) - Real production testing on specific client sites
This workflow ensures rapid development while validating changes work correctly in production conditions.
Step 1: Preprod UI Testing (Fast Iteration)¶
Use the preprod-ui for rapid CSS and UI iteration. It provides hot reloading and can connect to any backend environment.
Starting the Server¶
Or from the frontend root:
Benefits¶
| Feature | Description |
|---|---|
| Hot Reloading | See changes instantly without page refresh |
| Direct Package Access | Uses @frontend/shared directly (no bundle step) |
| Environment Flexibility | Connect to test, staging, or production APIs |
| No Local Backend | Works with any deployed backend environment |
Use Cases¶
- CSS tweaks and styling adjustments
- Component layout changes
- Theme modifications
- Responsive design testing
- Rapid UI prototyping
Connecting to Different Environments¶
The preprod-ui allows you to select which backend environment to use. No local backend is required - you can test against:
- Test environment - Safe for experimentation
- Staging environment - Pre-production validation
- Production environment - Real data testing (use carefully)
Step 2: Widget Demo Testing (Production Conditions)¶
After validating changes in preprod-ui, test with the widget demo page. This simulates real-world widget embedding conditions.
Critical: Shadow DOM Differences
The production widget runs inside a Shadow DOM, which isolates its CSS from the host page. Common issues:
- CSS Variables: Tailwind 4 uses CSS variables (
var(--text-sm)) that can inherit from host page - rem/em units: Calculated from host page's root font-size, not widget's
- Font inheritance: Host page fonts don't penetrate shadow boundary
- Global styles: Don't penetrate the shadow boundary
The widget includes explicit overrides in shadow-dom-protection.css to handle these, but new CSS features should always be tested in the Widget Demo.
Always test CSS changes in the widget demo - what works in preprod-ui may break in production.
Starting the Server¶
URL: http://localhost:8083/demo.html
What This Tests¶
| Aspect | Description |
|---|---|
| Shadow DOM | CSS isolation behavior (critical for styling) |
| Full UMD Bundle | Tests the production build output |
| Loader Behavior | Validates the widget loader script |
| Widget Initialization | Tests real initialization sequence |
| Domain Handling | Uses localhost.demo which maps to abtasty.com |
Environment Configuration¶
The widget demo uses the test environment API endpoint configured in .env.test. This is hardcoded behavior:
- Domain:
localhost.demo→ Forces domain toabtasty.com - API: Uses test environment endpoint
- Bundle: Serves the compiled UMD bundle
Demo Behavior Differences¶
| Environment | forceDisplay |
Traffic Control | Hidden Zone |
|---|---|---|---|
Local demos (just dev) |
false |
Can be tested | Can be tested |
CDN demo pages (just deploy-demo) |
true |
Bypassed | Bypassed |
Local demos load configuration from .env.test and generate demo pages via scripts/build-demo.cjs. Since forceDisplay is false, you can test traffic control and hidden zone features.
CDN demo pages are deployed with forceDisplay: true, meaning the widget always displays regardless of traffic control settings. This is useful for client demonstrations.
Chrome Plugin Testing (Website-Dependent Behavior)¶
When you need to test behavior that depends on the actual client website, use the Chrome plugin to inject the widget locally. This is useful when testing features that interact with:
- Specific page navigation or URL detection
- Form filling and submission tracking
- Page-specific content or layout interactions
- Cross-page user journeys
- Copilot mode on CTA/form pages
- Page display rules (per-page widget visibility)
How It Works¶
- Build or run the Chrome plugin locally with your changes
- Load the unpacked extension in Chrome
- Navigate to any client website (e.g., abtasty.com)
- The widget injects locally - no deployment needed, no changes to the client's site
Option A: Development Mode (Hot Reload)¶
For active development with hot-reloading:
This starts a WXT dev server that reloads the extension on code changes. It uses local Supabase (.env.local) automatically.
Then load the unpacked extension from frontend/chrome-plugin/.output/chrome-mv3/ in Chrome (chrome://extensions → "Load unpacked").
Option B: Static Build¶
For testing a production-like build on real client sites:
cd frontend/chrome-plugin
just build test # Uses test backend API
just build production # Uses production backend API
just build staging # Uses staging backend API
Then load the unpacked extension from frontend/chrome-plugin/.output/chrome-mv3/ in Chrome (chrome://extensions → "Load unpacked").
Local Supabase Auto-Detection
If a local Supabase is running at 127.0.0.1:54321, just build automatically uses it regardless of the environment you specify. This means just build test gives you the test backend API with your local Supabase data (page display rules, site configs, etc.). No extra parameter needed.
Loading the Extension in Chrome¶
- Open
chrome://extensions - Enable Developer mode (top-right toggle)
- Click Load unpacked
- Select the
frontend/chrome-plugin/.output/chrome-mv3/directory - After rebuilding, click the refresh icon on the extension card to reload
Testing Page Display Rules¶
Page display rules (per-page widget visibility) are stored in Supabase. To test them locally:
- Start local Supabase:
cd supabase && just start - Configure rules in local Supabase (via backoffice or direct DB edit)
- Build or run:
just build testorjust dev— both use local Supabase automatically - Navigate to the configured URL and verify the widget hides/shows correctly
Testing Form Assistant¶
Form assistant (copilot mode) requires both conditions to be true:
- The unified
form_assistantfeature is enabled for the domain - The current page is a form tracking page (CTA destination, additional form tracking page, or thank-you page)
To test form assistant locally:
- Ensure the feature flag is enabled in the database
- Navigate to a configured CTA destination page (e.g., a signup or demo booking page)
- The widget should appear as a "Need help?" button in the bottom-right corner
- Clicking it should expand to a right-side panel with a welcome message and follow-up questions
See Widget Display Logic - Form Assistant for the complete decision flow.
Source Overrides (Testing Local Changes on Live Sites)¶
Chrome DevTools source overrides let you replace the production widget bundle on any live client website with a local debug build. This is useful for reproducing and debugging issues in the exact context of a client's site — with their page layout, scripts, and configuration — without deploying anything.
Prerequisites¶
- Google Chrome (or any Chromium-based browser)
- A local debug build of the widget
1. Build the widget in debug mode¶
This produces frontend/widget/dist/inboundx-widget.js with debug logging enabled.
2. Enable source overrides in DevTools¶
- Open Chrome DevTools (
Cmd+Option+I/Ctrl+Shift+I) - Go to Sources > Overrides tab (in the left sidebar)
- Click Select folder for overrides and choose (or create) a local folder
- When prompted, click Allow to grant Chrome write access to that folder
3. Override the widget bundle¶
- Go to the Network tab
- Reload the page if needed so requests appear
- Find the
inboundx-widget.jsrequest (filter by "inboundx" to find it quickly) - Right-click the request and select Override content
- DevTools opens the file in the Sources editor
4. Replace with your local build¶
- Open the built file at
frontend/widget/dist/inboundx-widget.js - Select all its content and copy it
- In DevTools, select all content in the override file and paste your build
- Press
Cmd+S/Ctrl+Sto save
5. Hard-refresh the page¶
Press Cmd+Shift+R / Ctrl+Shift+R to reload without cache. The page now loads your local widget build instead of the production bundle. Debug logs appear in the console.
The override persists across reloads
Chrome remembers overrides until you disable them. To stop overriding, uncheck the Enable Local Overrides checkbox in the Sources > Overrides tab.
Remember to disable overrides
Overrides affect all pages served from the same origin. Disable them when you're done testing to avoid confusion.
Step 3: Client Production Testing (Optional)¶
Very optionaly. For final validation, you can deploy to specific client sites in production. Not all clients use the same widget bundle, allowing safe in-production testing.
Available Test Sites¶
| Client | Domain | Notes |
|---|---|---|
| Rose | userose.ai | Our own website - safest for testing |
| AB Tasty | abtasty.com | Uses its own widget deployment |
When to Use¶
- Final validation before rolling out to all clients
- Testing client-specific configurations
- Verifying behavior with real production traffic
- A/B testing widget changes
Deployment¶
Deploy a new widget version to a specific client before rolling out globally. This allows:
- Real user interaction testing
- Production API integration validation
- Performance monitoring under real conditions
Use with caution
Production testing affects real users. Always test thoroughly in preprod-ui and widget demo first.
Ports Reference¶
| Service | Port | URL | Purpose |
|---|---|---|---|
| Widget Demo | 8083 | http://localhost:8083/demo.html | Production-like testing |
| Preprod UI | 3001 | http://localhost:3001 | Fast UI iteration |
Typical Development Flow¶
- Start preprod-ui - Begin with fast iteration
- Make changes - Edit shared components or styles
- Verify in preprod-ui - Check changes with hot reload
- Test in widget demo - Validate production bundle behavior
- Source overrides (optional) - Test your build on a live client site via DevTools overrides
- Deploy to test client (optional) - For high-risk changes, deploy to userose.ai first
- Commit & deploy - Roll out to all clients