Skip to content

Frontend Setup

Prerequisites

  • Node.js 18+
  • npm

Installation

cd frontend

# Install dependencies for all packages
just install

Development Servers

Standard Development Flow

  1. Install dependencies: just install (run once or when dependencies change)
  2. Make changes in shared/ package
  3. Test changes using preprod-ui with just run-preprod
  4. Build all projects with just build
  5. Test Chrome extension with just dev-chrome

Development Commands

cd frontend

# Shared package (watch mode)
just dev-shared

# Widget development
just dev-widget

# Pre-production UI
just dev-preprod

# Run shared + preprod together (recommended)
just run-preprod

# Chrome extension
just dev-chrome

Widget Integration

Auto-initialization (Script Tag)

<script src="https://cdn.example.com/inboundx-widget.js"
        data-inboundx-auto-init
        data-api-url="https://api.inboundx.com"
        data-site-name="example.com"></script>

Manual Initialization

InboundXWidget.init({
  apiUrl: 'https://api.inboundx.com',
  siteName: 'example.com',
  domain: 'example.com'
});

Chrome Extension Development

The Chrome extension uses shared components:

import { RoseWidget } from '@inboundx/shared';
import { ChromeStorageAdapter, ChromeNetworkAdapter } from '../adapters/chrome-adapters';

<RoseWidget
  storageAdapter={new ChromeStorageAdapter()}
  networkAdapter={new ChromeNetworkAdapter()}
  // ... other props
/>

API Key Management

The build process requires IX_API_KEY:

  1. Create frontend/.env file:
    IX_API_KEY=ix-your-api-key
    
  2. Build with: just build-chrome

Building

Build All Packages

cd frontend
just build

Individual Builds

just build-shared         # Build shared package only
just build-chrome         # Build Chrome extension

Testing

Run Tests

cd frontend
just test

Type Checking

cd frontend
just type-check

Deployment

Pre-production UI (Firebase)

cd frontend

# Deploy to production
just deploy-preprod

# Deploy to test channel
just preview-preprod

Client Backoffice (Cloudflare Pages)

Deployed via GitHub Actions:

  • main branch → production (app.userose.ai)
  • staging branch → staging (appstaging.userose.ai)
  • develop branch → test (apptest.userose.ai)

Logging Configuration

Log Levels

Environment Default Level
Development All levels (debug)
Production warn and error only
Test Silent

Override Log Level

LOG_LEVEL=silent    # Completely silent
LOG_LEVEL=error     # Only errors
LOG_LEVEL=warn      # Warnings and errors
LOG_LEVEL=info      # Info, warnings, errors
LOG_LEVEL=debug     # All levels

Usage

import { logger } from '@/utils/logger';

logger.debug('Debug information');
logger.info('User action', data);
logger.warn('Deprecated feature used');
logger.error('API failed', error);

Important

Always use logger from @/utils/logger.ts, never console.log.

Analytics Events

All PostHog events use rw_ prefix (Rose Widget):

Event Description
rw_widget_impression Widget displayed to user
rw_message_sent User sent a message
rw_cta_clicked User clicked CTA button
rw_client_form_submitted Form submission detected
rw_demo_cta_rendered Demo CTA displayed
rw_demo_cta_clicked Demo CTA clicked

Event Deduplication

Best Practice

Handle deduplication at the component level, not in analytics functions.

// ✅ Correct: Component handles deduplication
useEffect(() => {
    if (isVersionCompatible && currentSessionId && isInitialized) {
        ChatAnalytics.trackWidgetImpression({ siteName });
    }
}, [isVersionCompatible && currentSessionId && isInitialized]);

Supabase Type Generation

When the Supabase schema changes:

cd frontend
just gen-types

This generates type-safe database types at frontend/shared/src/types/database.ts.

Never Use Manual Type Assertions

// ❌ Bad
return data as unknown as MyType;

// ✅ Good: Use generated types
type MyTableRow = Database['public']['Tables']['my_table']['Row'];

Environment Configuration

Each package has environment-specific configuration:

Package Configuration
preprod-ui Supabase auth, multiple API endpoints
chrome-plugin API key injection during build
widget Data attributes or manual init
shared Adapter-based configuration

Troubleshooting

TypeScript Errors in Shared Package

Ensure shared package is built:

just build-shared

Chrome Extension Not Loading

  1. Check that IX_API_KEY is set in frontend/.env
  2. Rebuild: just build-chrome
  3. Reload extension in Chrome

Widget Not Appearing

  1. Check browser console for errors
  2. Verify data-site-name matches Supabase configuration
  3. Check traffic control settings in PostHog