npm package: @myop/vue
Description: Official Vue bindings for embedding [Myop](https://myop.dev) components in your Vue applications.
Latest version: 0.0.47

# @myop/vue

Official Vue bindings for embedding [Myop](https://myop.dev) components in your Vue applications.

Myop components are framework-agnostic UI components that can be updated in real-time without redeploying your application. Build once, embed anywhere, and iterate instantly. Perfect for teams that need to ship UI changes fast, A/B test components, or empower non-developers to customize the interface. Myop is also the safest way to adopt AI-generated components in your application—whether created by developers or non-developers—with built-in sandboxing and controlled integration.

[![npm version](https://img.shields.io/npm/v/@myop/vue.svg)](https://www.npmjs.com/package/@myop/vue)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![Discord](https://img.shields.io/badge/Discord-Join%20us-5865F2?logo=discord&logoColor=white)](https://myop.dev/discord)

[Website](https://www.myop.dev/) | [Documentation](https://docs.myop.dev/) | [Dashboard](https://dashboard.myop.dev/) | [Discord](https://myop.dev/discord)

## Installation

```bash
npm install @myop/vue
```

```bash
yarn add @myop/vue
```

```bash
pnpm add @myop/vue
```

## Auto-Generated Vue Components

Myop automatically generates a typed Vue component package for every component you create in the [dashboard](https://dashboard.myop.dev/). Install it directly via npm:

```bash
npm install https://cloud.myop.dev/npm/{component-id}/vue
```

Then import and use it like any Vue component. For example, if you created a table component called "users-table" in the dashboard:

```vue
<script setup lang="ts">
import { UsersTable } from "@myop/users-table";

const users = [
  { id: 1, name: "Alice", email: "alice@example.com", role: "Admin" },
  { id: 2, name: "Bob", email: "bob@example.com", role: "User" },
  { id: 3, name: "Charlie", email: "charlie@example.com", role: "User" },
];

function handleRowClicked(payload: { rowData: any }) {
  console.log("Selected user:", payload.rowData);
}

function handleDeleteClicked(payload: { userId: number }) {
  deleteUser(payload.userId);
}

function handleExportRequested(payload: { format: "csv" | "xlsx" }) {
  exportToFormat(payload.format);
}
</script>

<template>
  <UsersTable
    :data="{ rows: users }"
    @row-clicked="handleRowClicked"
    @delete-clicked="handleDeleteClicked"
    @export-requested="handleExportRequested"
  />
</template>
```

**Why this is powerful:**

- **Fully typed** — The generated package includes complete TypeScript types for your component's data interface and all CTA event payloads
- **Auto loaded** — Components are fetched and rendered automatically, no manual setup required
- **Not in your code** — The actual component implementation lives on Myop and is loaded at runtime. Update your component in the dashboard and it's instantly live—no rebuild, no redeploy
- **Zero bundle impact** — The entire `@myop/vue` package costs only ~6KB gzipped—and that's the total cost whether you use 1, 2, or 1,000 components. Auto-generated component packages are just thin typed wrappers. The actual component implementations are loaded at runtime, meaning your Myop components can be as complex, feature-rich, and heavy as you need without adding a single byte to your application bundle. Consider typical bundle costs: a chart library (~60KB), a map component (~200KB), a data grid (~150KB), a rich text editor (~100KB), or a chat widget with emoji picker (~80KB). With Myop, all of these cost ~0KB to your bundle—they load on-demand when needed

**Environment options:**

Set the default environment for all components using `setEnvironment`:

```ts
import { setEnvironment } from "@myop/vue";

// Set default environment for all component loads
setEnvironment("staging");
```

You can also override the environment directly on a specific component:

```vue
<template>
  <UsersTable
    :data="{ rows: users }"
    :preview="true"
    environment="staging"
  />
</template>
```

Environments are fully configurable in the [dashboard](https://dashboard.myop.dev/), allowing you to test changes in staging before publishing to production.

For more details on auto-generated packages, see the [Auto-Generated Packages documentation](https://docs.myop.dev/docs/learnMyop/AutoGeneratedPackages).

## Requirements

- Vue 3.0+

## Quick Start

```vue
<script setup lang="ts">
import { MyopComponent } from "@myop/vue";

function handleAction(action: string, payload: any) {
  console.log("Action:", action, "Payload:", payload);
}
</script>

<template>
  <MyopComponent
    componentId="your-component-id"
    :style="{ width: '600px', height: '400px' }"
    @action="handleAction"
  />
</template>
```

## Components

### `MyopComponent`

The main component for embedding Myop components.

```vue
<script setup lang="ts">
import { MyopComponent } from "@myop/vue";

const items = [{ id: 1, name: "Item 1" }, { id: 2, name: "Item 2" }];

function handleRowClicked(payload: any) {
  console.log("Row clicked:", payload);
}

function handleLoad(component: any) {
  console.log("Loaded!", component);
}

function handleError(error: string) {
  console.error("Error:", error);
}
</script>

<template>
  <MyopComponent
    componentId="abc123"
    :data="{ items }"
    @row-clicked="handleRowClicked"
    @load="handleLoad"
    @error="handleError"
  />
</template>
```

#### Props

| Prop | Type | Description |
|------|------|-------------|
| `componentId` | `string` | The ID of the Myop component to load |
| `data` | `object` | Data to pass to the component via `myop_init_interface` |
| `style` | `object` | CSS styles for the container |
| `#loader` | `slot` | Loading indicator slot (default: no loader). Use `<MyopLoader />` for default Myop loader |
| `#fallback` | `slot` | Error fallback slot (default: `<MyopFallback />`). Override with custom component |
| `fadeDuration` | `number` | Loader fade-out duration in ms (default: `200`) |
| `environment` | `string` | Load from a specific environment (e.g., `"staging"`, `"prod"`) |
| `preview` | `boolean` | Load the unpublished preview version of the component |

#### Events

| Event | Payload | Description |
|-------|---------|-------------|
| `@action` | `(action, payload)` | Generic handler for all CTA events |
| `@[action-name]` | `payload` | Handler for specific actions (e.g., `@row-clicked`) |
| `@load` | `component` | Called when the component finishes loading |
| `@error` | `error: string` | Called when loading fails |

#### Environments & Preview

Myop supports multiple environments, allowing you to test changes before going live:

```vue
<template>
  <!-- Production (default) -->
  <MyopComponent componentId="abc123" />

  <!-- Load from staging environment -->
  <MyopComponent componentId="abc123" environment="staging" />

  <!-- Load unpublished preview version (for testing before publishing) -->
  <MyopComponent componentId="abc123" :preview="true" />

  <!-- Combine both: preview version in staging -->
  <MyopComponent componentId="abc123" environment="staging" :preview="true" />
</template>
```

Environments are configured in the [dashboard](https://dashboard.myop.dev/). Use `:preview="true"` to test unpublished changes before making them live.

### `MyopContainer` (Legacy)

The legacy container component. Use `MyopComponent` for new projects.

```vue
<script setup lang="ts">
import { MyopContainer } from "@myop/vue";

function handleReady(component: any) {
  console.log("Ready!", component);
}
</script>

<template>
  <MyopContainer
    componentId="abc123"
    :onReady="handleReady"
  />
</template>
```

## Type-Safe Event Handlers

Define your CTA payloads for fully typed event handlers:

```vue
<script setup lang="ts">
import { MyopComponent } from "@myop/vue";

// Define your component's data and CTA payload types
interface MyData {
  items: { id: string; name: string }[];
}

interface RowClickedPayload {
  rowIndex: number;
  rowData: any;
}

interface ItemSelectedPayload {
  itemId: string;
}

interface ExportRequestedPayload {
  format: "csv" | "json";
}

function handleRowClicked(payload: RowClickedPayload) {
  console.log("Row clicked:", payload.rowIndex);
}

function handleItemSelected(payload: ItemSelectedPayload) {
  console.log("Item selected:", payload.itemId);
}

function handleAction(action: string, payload: any) {
  console.log(action, payload);
}
</script>

<template>
  <MyopComponent
    componentId="dashboard-component"
    :data="{ items: [...] }"
    @row-clicked="handleRowClicked"
    @item-selected="handleItemSelected"
    @action="handleAction"
  />
</template>
```

## Configuration

### Preloading Components

Preload components for faster rendering:

```ts
import { preloadComponents, isPreloaded } from "@myop/vue";

// Preload multiple components
await preloadComponents(["component-1", "component-2"]);

// Check if a component is preloaded
if (isPreloaded("component-1")) {
  console.log("Component is cached and ready");
}
```

### Custom Repository URL

```ts
import { setCloudRepositoryUrl } from "@myop/vue";

// Point to a custom Myop server
setCloudRepositoryUrl("https://your-custom-server.com");
```

### Environment Configuration

```ts
import { setEnvironment } from "@myop/vue";

// Set default environment for all component loads
setEnvironment("staging");
```

### Local Development

```ts
import { enableLocalDev } from "@myop/vue";

// Connect to local Myop development server (localhost:9292)
enableLocalDev();
```

### Advanced: Custom Repository

```ts
import { setCloudRepository, getCloudRepository } from "@myop/vue";
import { CloudRepository } from "@myop/sdk/helpers";

// Set a custom CloudRepository instance
const customRepo = new CloudRepository("https://custom-url.com");
setCloudRepository(customRepo);

// Get the current repository
const repo = getCloudRepository();
```

## Loading & Error States

By default, no loader is shown while the component loads. The Myop-branded fallback is displayed automatically on error.

### Using the Default Myop Loader

```vue
<script setup lang="ts">
import { MyopComponent, MyopLoader } from "@myop/vue";
</script>

<template>
  <MyopComponent componentId="my-component" :fadeDuration="300">
    <template #loader>
      <MyopLoader />
    </template>
  </MyopComponent>
</template>
```

### Custom Loading State

```vue
<template>
  <MyopComponent componentId="my-component" :fadeDuration="300">
    <template #loader>
      <div class="custom-loader">
        <Spinner />
        <p>Loading component...</p>
      </div>
    </template>
  </MyopComponent>
</template>
```

### Custom Error Fallback

```vue
<script setup lang="ts">
import { MyopComponent, MyopFallback } from "@myop/vue";
</script>

<template>
  <MyopComponent componentId="my-component">
    <!-- Custom fallback -->
    <template #fallback>
      <div class="error-state">
        <p>Failed to load component</p>
        <button @click="() => window.location.reload()">Retry</button>
      </div>
    </template>
  </MyopComponent>

  <!-- Or use default Myop fallback explicitly -->
  <MyopComponent componentId="other-component">
    <template #fallback>
      <MyopFallback />
    </template>
  </MyopComponent>
</template>
```

## API Reference

### Exports

| Export | Description |
|--------|-------------|
| `MyopComponent` | Main component for embedding Myop components |
| `MyopLoader` | Default Myop-branded loading indicator (opt-in) |
| `MyopFallback` | Default Myop-branded error fallback |
| `preloadComponents` | Preload components for faster rendering |
| `isPreloaded` | Check if a component is cached |
| `enableLocalDev` | Enable local development mode |
| `setCloudRepositoryUrl` | Set custom server URL |
| `setCloudRepository` | Set custom CloudRepository instance |
| `getCloudRepository` | Get current CloudRepository instance |
| `setEnvironment` | Set default environment |

## License

MIT