Skip to content

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:

  1. Preprod UI (port 3001) - Fast iteration for CSS/UI changes with hot reloading
  2. Widget Demo (port 8083) - Production-like testing with Shadow DOM behavior
  3. Chrome Plugin (optional) - Test website-dependent behavior on real client sites locally
  4. 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

cd frontend/preprod-ui
just dev

Or from the frontend root:

cd frontend
just dev-preprod

URL: http://localhost:3001

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

cd frontend/widget
just dev

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 to abtasty.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

How It Works

  1. Build the Chrome plugin locally with your changes
  2. Load the unpacked extension in Chrome
  3. Navigate to any client website (e.g., abtasty.com)
  4. The widget injects locally - no deployment needed, no changes to the client's site

Building Locally

cd frontend
just build-chrome

Then load the unpacked extension from frontend/chrome-plugin/dist/ in Chrome's extension manager.

Testing Copilot Mode

Copilot mode requires both conditions to be true:

  1. The copilot_mode feature flag is enabled in global_client_config.features
  2. The current page is a form tracking page (CTA destination, additional form tracking page, or thank-you page)

To test copilot mode locally:

  1. Ensure the feature flag is enabled in the database
  2. Navigate to a configured CTA destination page (e.g., a signup or demo booking page)
  3. The widget should appear as a "Need help?" button in the bottom-right corner
  4. Clicking it should expand to a right-side panel with a welcome message and follow-up questions

See Widget Display Logic - Copilot Mode for the complete decision flow.

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

graph LR A[Make CSS/UI changes] --> B[Test in Preprod UI<br/>Port 3001] B --> C{Changes work?} C -->|No| A C -->|Yes| D[Test in Widget Demo<br/>Port 8083] D --> E{Production behavior OK?} E -->|No| A E -->|Yes| F{High-risk change?} F -->|No| G[Commit & Deploy] F -->|Yes| H[Deploy to test client<br/>userose.ai] H --> I{Real production OK?} I -->|No| A I -->|Yes| G
  1. Start preprod-ui - Begin with fast iteration
  2. Make changes - Edit shared components or styles
  3. Verify in preprod-ui - Check changes with hot reload
  4. Test in widget demo - Validate production bundle behavior
  5. Deploy to test client (optional) - For high-risk changes, deploy to userose.ai first
  6. Commit & deploy - Roll out to all clients