npm package: @strata-ds/web
Description: Strata Design System Web Components
Latest version: 1.0.0

# @strata-ds/web

> 🌐 **Framework-agnostic web components** for [Strata](https://strata.charisol.io) — connect any frontend to your design system with zero lock-in.

`@strata-ds/web` is a Stencil-powered component library that delivers Strata design tokens and components to **vanilla JS, React, Vue, Angular, Svelte**, and any framework that supports web standards. It ensures design-to-code fidelity across your entire frontend ecosystem.

> Design once in Strata. Ship everywhere.

---

## Table of Contents

- [Why @strata-ds/web?](#why-strataweb)
- [Who Is This For?](#who-is-this-for)
- [Core Features](#core-features)
- [5-Minute Integration Checklist](#-5-minute-integration-checklist)
- [Quick Start](#quick-start--5-minutes)
  - [Step 1: Install](#step-1-install)
  - [Step 2: Get Your Credentials](#step-2-get-your-credentials)
  - [Step 3: Load the Components](#step-3-load-the-components)
- [API Reference](#api-reference)
  - [strata-provider](#strata-provider)
  - [strata-dynamic](#strata-dynamic)
  - [strata-debug](#strata-debug)
- [Debugging & Troubleshooting](#debugging--troubleshooting)
- [Architecture Overview](#architecture-overview)
- [Authentication](#authentication)
- [Advanced Usage](#advanced-usage)
- [License](#license)
- [Resources](#resources)

---

## Why @strata-ds/web?

### The Problem

Modern teams use **multiple frameworks** (React for marketing site, Vue for admin panel, vanilla JS for docs). Without a **framework-agnostic design system**, you face:

- Duplicate style implementations across frameworks
- Inconsistent brand experience (React button ≠ Vue button)
- Manual token updates in 5+ repositories
- Designer → developer handoff breaks down per framework

### The Solution

`@strata-ds/web` uses **Web Components** (browser-native, framework-agnostic) to deliver:

- ✅ **One source of truth** — Tokens and components sync from Strata
- ✅ **Works everywhere** — Vanilla JS, React, Vue, Angular, Svelte, etc.
- ✅ **Real-time updates** — Design changes propagate without redeploying
- ✅ **Zero lock-in** — Web standards, not proprietary APIs

---

## Who Is This For?

| Persona | Value |
|---------|-------|
| **Solopreneurs** | "I'm using vanilla JS — I don't need React bloat. I just want brand-consistent components." |
| **Frontend Engineers** | "I maintain 3 apps in different frameworks. One design system = one source of truth." |
| **Entrepreneurs** | "My team ships faster because components stay in sync across React, Vue, and marketing pages." |
| **Designers** | "What I create in Strata works everywhere — no framework-specific tweaks." |

---

## Core Features

- 🌐 **Framework-agnostic** — Works in vanilla JS, React, Vue, Angular, Svelte
- 🔁 **Live sync** with Strata backend
- 🧠 **Token-driven styling** — Design tokens as CSS custom properties
- 🧩 **Dynamic component loading** — Fetch components from Strata on-demand
- 🛠 **React wrappers included** — Import from `@strata-ds/web/react`
- 📴 **Offline-first fallback** — Cached data when network fails
- 🧪 **Debug tools** — `<strata-debug>` component for inspection

---

## 📋 5-Minute Integration Checklist

**Before you start:**
- [ ] Created a project at [strata.charisol.io](https://strata.charisol.io)
- [ ] Imported your design tokens (Style Dictionary JSON or Figma)
- [ ] Published your project (dashboard shows "✅ Published")

**Integration:**
- [ ] Installed `@strata-ds/web` via npm/yarn
- [ ] Copied `projectId` from dashboard URL or project settings
- [ ] Copied `projectToken` from **Publish & Sync** tab (starts with `pt_live_`)
- [ ] Added `<strata-provider>` wrapper using CDN snapshot sync (recommended)
- [ ] Loaded the Stencil script in your HTML/framework entry point
- [ ] Rendered your first component with `<strata-dynamic>`

**Verification:**
- [ ] Opened DevTools → Console and saw `Connected to design system`
- [ ] Console shows `Design system synced: { components: {...}, variables: {...} }`
- [ ] Component renders on screen with correct styles
- [ ] Added `<strata-debug></strata-debug>` and verified connection status

**Stuck?** → Jump to [Debugging & Troubleshooting](#debugging--troubleshooting).

---

## Quick Start (< 5 Minutes)

> 🚀 **New to Strata?** Get your first component rendering in 3 steps.

### Step 1: Install

```bash
npm install @strata-ds/web
# or
yarn add @strata-ds/web
```

---

### Step 2: Get Your Credentials

Go to [strata.charisol.io](https://strata.charisol.io) → **Your Project** → **Publish & Sync** tab:
- Copy your **Project ID** (e.g., `abc123def456`)
- Copy your **Project Token** (starts with `pt_live_`)

---

### Step 3: Load the Components

#### **Vanilla JS / HTML**

```html
<!DOCTYPE html>
<html>
  <head>
    <script type="module" src="https://cdn.jsdelivr.net/npm/@strata-ds/web/dist/strata-web/strata-web.esm.js"></script>
  </head>
  <body>
    <strata-provider
      url="http://localhost:4000"
      enable-realtime="true"
      poll-interval="6000"
      project-id="YOUR_PROJECT_ID"
      project-token="pt_live_your_token_here"
      sync-enabled="true"
    >
      <!-- Dynamic component -->
      <strata-dynamic
        component="Button"
        props='{"children": "Click me!", "variant": "primary"}'
      ></strata-dynamic>
    </strata-provider>
  </body>
</html>
```

> 💡 Replace `YOUR_PROJECT_ID` and `pt_live_your_token_here` with values from **Step 2**.

---

#### **React (Next.js / Create React App)**

```tsx
// app/layout.tsx (Next.js App Router)
"use client";
import { StrataProvider } from "@strata-ds/web/react";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <StrataProvider
          url="http://localhost:4000"
          enableRealtime={true}
          pollInterval={6000}
          projectId="YOUR_PROJECT_ID"
          projectToken="pt_live_your_token_here"
          syncEnabled={true}
        >
          {children}
        </StrataProvider>
      </body>
    </html>
  );
}
```

```tsx
// app/page.tsx
"use client";
import { StrataDynamic } from "@strata-ds/web/react";

export default function Page() {
  return (
    <StrataDynamic
      component="Button"
      props={{ children: "Click me!", variant: "primary" }}
    />
  );
}
```

---

#### **Vue 3**

```vue
<template>
  <strata-provider
    url="http://localhost:4000"
    enable-realtime="true"
    poll-interval="6000"
    project-id="YOUR_PROJECT_ID"
    project-token="pt_live_your_token_here"
    sync-enabled="true"
  >
    <strata-dynamic
      component="Button"
      :props="JSON.stringify({ children: 'Click me!', variant: 'primary' })"
    />
  </strata-provider>
</template>

<script setup>
import { defineCustomElements } from '@strata-ds/web/loader';

defineCustomElements();
</script>
```

---

#### **Angular**

```typescript
// app.module.ts
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { defineCustomElements } from '@strata-ds/web/loader';

defineCustomElements();

@NgModule({
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule {}
```

```html
<!-- app.component.html -->
<strata-provider
  url="http://localhost:4000"
  enable-realtime="true"
  poll-interval="6000"
  project-id="YOUR_PROJECT_ID"
  project-token="pt_live_your_token_here"
  sync-enabled="true"
>
  <strata-dynamic
    component="Button"
    props='{"children": "Click me!", "variant": "primary"}'
  ></strata-dynamic>
</strata-provider>
```

---

#### **Svelte**

```svelte
<!-- App.svelte -->
<script>
  import { onMount } from 'svelte';
  import { defineCustomElements } from '@strata-ds/web/loader';

  onMount(() => {
    defineCustomElements();
  });
</script>

<strata-provider
  url="http://localhost:4000"
  enable-realtime="true"
  poll-interval="6000"
  project-id="YOUR_PROJECT_ID"
  project-token="pt_live_your_token_here"
  sync-enabled="true"
>
  <strata-dynamic
    component="Button"
    props={JSON.stringify({ children: 'Click me!', variant: 'primary' })}
  ></strata-dynamic>
</strata-provider>
```

---

## API Reference

### `<strata-provider>`

Wraps your app and manages the connection to Strata.

| Attribute | Type | Default | Description |
|-----------|------|---------|-------------|
| `url` | `string` | `'http://localhost:4000'` | Base URL for the Strata backend. Use `http://localhost:4000` for local development; set to your deployed Strata backend URL (use `https://` in production to protect tokens) |
| `enable-realtime` | `boolean` | `true` | Enable WebSocket + polling for real-time updates |
| `poll-interval` | `number` | `6000` | Polling interval in milliseconds |
| `project-id` | `string` | `undefined` | Your Strata project ID (from dashboard) |
| `project-token` | `string` | `undefined` | Sync token (starts with `pt_live_`) — required if project is private |
| `sync-enabled` | `boolean` | `true` | Enable/disable syncing |

**Events:**
- `synced` — Fires when design system data syncs successfully
- `error` — Fires when sync fails (check `event.detail.error`)
- `connected` — Fires when WebSocket connects

---

### `<strata-dynamic>`

Renders a component fetched from Strata.

| Attribute | Type | Default | Description |
|-----------|------|---------|-------------|
| `component` | `string` | *required* | Name of the component (e.g., `"Button"`, `"Navbar"`) |
| `props` | `string` (JSON) | `'{}'` | Props to pass to the component (JSON string) |
| `sync-enabled` | `boolean` | `true` | Enable/disable syncing for this component |

**Events:**
- `load` — Fires when the component loads successfully
- `error` — Fires when the component fails to load

**Example:**
```html
<strata-dynamic
  component="Card"
  props='{"title": "Welcome", "variant": "elevated"}'
></strata-dynamic>
```

---

### `<strata-debug>`

Renders a debug panel showing connection status and loaded components.

```html
<strata-debug></strata-debug>
```

Displays:
- ✅ Connection status (Connected / Disconnected / Error)
- ✅ Loaded components
- ✅ Loaded variables
- ✅ Sync mode (WebSocket + Polling)

---

## Debugging & Troubleshooting

### Quick Debug Panel

Add `<strata-debug></strata-debug>` anywhere inside `<strata-provider>` to inspect:
- ✅ Connection status
- ✅ Loaded components
- ✅ Loaded design tokens
- ✅ Sync configuration

```html
<strata-provider url="http://localhost:4000" project-id="abc123">
  <strata-debug></strata-debug>
  <!-- Your app content -->
</strata-provider>
```

---

### Common Issues

| 🚨 Problem | ✅ Solution |
|-----------|-----------|
| **401 Unauthorized** | Your `project-token` is invalid or expired. Go to **Publish & Sync** tab in your Strata project and copy a fresh token. |
| **403 Forbidden** | Your project has CORS restrictions. Add your domain to `allowedOrigins` in your Strata project settings. |
| **Component not rendering** | 1. Check `project-id` matches your dashboard URL<br>2. Verify the component exists in your Strata project<br>3. Open DevTools Console and look for errors |
| **Styles broken / unstyled** | Design tokens are applied as CSS custom properties on `:root`. Check DevTools → Elements → Styles for `--color-*`, `--font-*`, etc. |
| **TypeScript errors (React)** | Install type definitions: `npm install --save-dev @types/react` |
| **Vue warning: unknown element** | Call `defineCustomElements()` from `@strata-ds/web/loader` in your app entry file (see Vue example above) |

---

### Console Log Reference

When debugging, look for these messages in DevTools Console:

- ✅ `Strata Web Components loaded` — Script initialized successfully
- ✅ `Connected to design system` — Provider mounted and connected
- ✅ `Design system synced: { components: {...}, variables: {...} }` — Data loaded
- ❌ `401` / `403` — Token or CORS issue (see table above)
- ❌ `Component "X" doesn't exist` — Component name doesn't match your Strata project

---

### Network Tab Debugging

Open DevTools → **Network** tab and filter by:

- **Polling requests** — Look for requests to your `url` (e.g., `http://localhost:4000/sync`); status should be `200 OK` with JSON responses
- **WebSocket connection** — Look for `101 Switching Protocols`

---

## Architecture Overview

```
Your App
  └── <strata-provider>        ← Manages connection & token sync
        ├── <strata-dynamic>   ← Fetches & renders individual components
        └── <strata-debug>     ← (Optional) Debug panel
```

---

## Authentication

If your project is private, pass a `project-token`:

```html
<strata-provider
  project-id="YOUR_PROJECT_ID"
  project-token="pt_live_your_token_here"
>
```

Every sync request will include `Authorization: Bearer pt_live_...` and `X-Project-Token` headers.

---

## Advanced Usage

### Listening to Events

```javascript
const provider = document.querySelector('strata-provider');

provider.addEventListener('synced', (event) => {
  console.log('Design system loaded:', event.detail);
});

provider.addEventListener('error', (event) => {
  console.error('Sync failed:', event.detail.error);
});
```

**React:**

```tsx
import { StrataProvider } from '@strata-ds/web/react';

<StrataProvider
  projectId="YOUR_PROJECT_ID"
  projectToken="pt_live_your_token_here"
  onSync={(data) => console.log('Synced:', data)}
  onError={(error) => console.error('Error:', error)}
>
  {children}
</StrataProvider>
```

### Dynamic Props

Update `props` dynamically:

```javascript
const dynamic = document.querySelector('strata-dynamic');
dynamic.setAttribute('props', JSON.stringify({ variant: 'secondary', children: 'Updated!' }));
```

> ⚠️ **Note:** `props` must be a **JSON string** when using the web component directly. For React, use the `StrataDynamic` wrapper which accepts objects directly.

---

## License

MIT © [Charisol](https://strata.charisol.io)

---

## Resources

- 🌐 [Strata Dashboard](https://strata.charisol.io)
- 📦 [npm Package](https://www.npmjs.com/package/@strata-ds/web)
- 📚 [Stencil Documentation](https://stenciljs.com/)
- 💬 [Community Discord](https://discord.gg/strata) *(placeholder — update with real link)*