Skip to main content

Overview

Demo mode lets developers and users explore the full Pastures UI without a running Engine backend. When enabled, all API calls return synthetic data with a simulated network delay.

Data Flow

isGlobalDemoMode()
  ├── true  → load DEMO_* constants (with simulated delay)
  └── false → isEngineConfigured()?
                ├── true  → engineFetch() → safeJson()
                └── false → show "Configure Engine" prompt

Two Demo Data Patterns

Pattern 1: engineFetch-based pages

Pages that call engineFetch() get demo data automatically via getDemoResponse() in lib/demoResponses.ts. Add a new case for your API path:
// lib/demoResponses.ts
export function getDemoResponse(path: string): any {
  switch (path) {
    // ... existing cases
    case '/api/my-feature':
      return {
        items: [
          { id: 'demo-1', name: 'Demo item', status: 'healthy' },
          { id: 'demo-2', name: 'Another item', status: 'warning' },
        ],
      };
  }
}

Pattern 2: Inline fetch pages

Pages that use fetch directly (instead of engineFetch) define DEMO_* constants and check demo mode in onMounted:
const DEMO_METRICS = {
  cpu: 42.5,
  memory: 68.1,
  pods: 127,
};

onMounted(async () => {
  if (isGlobalDemoMode()) {
    await new Promise((r) => setTimeout(r, 400));
    metrics.value = DEMO_METRICS;
    loading.value = false;
    return;
  }

  // real API call
  const res = await fetch(`${engineUrl}/api/metrics`, { headers });
  metrics.value = await res.json();
  loading.value = false;
});

Best Practices

Never silently fall back to demo data when the Engine is configured and expected to respond. If an API call fails in non-demo mode, surface the error to the user rather than quietly substituting synthetic data.

Realistic data

  • Use plausible values: realistic cluster names (prod-us-east-1), version strings (v1.28.4+rke2r1), timestamps, and counts.
  • Include a mix of healthy and unhealthy states so the UI exercises all code paths.
  • Match the exact response shape the Engine returns — demo data doubles as a contract test.

Simulated delay

Always add a short delay (300–500 ms) before resolving demo data. This exercises loading states and prevents UI flicker bugs from hiding behind instant responses.
await new Promise((r) => setTimeout(r, 400));

Naming conventions

  • Prefix constants with DEMO_ (e.g., DEMO_ADVISORIES, DEMO_CLUSTERS).
  • Keep constants at the top of the <script setup> block or in lib/demoResponses.ts.

Testing both paths

When developing a feature, toggle demo mode on and off in Settings to verify:
  1. The UI renders correctly with demo data.
  2. The UI renders correctly with live Engine data (or shows an appropriate error).
  3. Loading states display during the simulated delay.