# Debugging Plugins
Learn techniques for debugging your Lottie Creator Plugin.

Here are tips on how to find and fix issues in your plugin.

## Debugging differences in UI and plugin code

Your plugin runs in two separate environments:

1. **UI** (runs in an iframe): Your UI is rendered in an iframe that you can inspect and debug using standard browser developer tools.

2. **Plugin code** (runs in a sandbox): Your plugin logic that interacts with the Lottie Creator API runs in a secure sandbox environment. Because the sandbox is isolated, you cannot use browser developer tools to set breakpoints or inspect variables in plugin code.

## Debugging the UI

Since your plugin's UI runs in an iframe, you can debug it using your browser's developer tools just like any web page.

- Open browser developer tools, typically with `F12` or `Cmd+Option+I` (Mac) / `Ctrl+Shift+I` (Windows).
- On the Console tab, you'll be able to see any logs printed from the UI.
- On the Sources tab, you can set breakpoints by clicking on line numbers, step through code execution, and inspect variables.
- For React components, consider installing the [React Developer Tools](https://react.dev/learn/react-developer-tools) browser extension to inspect component state and props.

## Debugging plugin code

Since you cannot use browser developer tools for plugin code running in the sandbox, rely on `try-catch` blocks and logging instead.

### Using try-catch

Wrap operations that might fail in `try-catch` blocks to capture errors:

```typescript
creator.ui.onMessage(async (msg) => {
  try {
    if (msg.type === "import-animation") {
      await creator.activeScene.import({
        type: "LOTTIE",
        url: lottieUrl,
      });
    }
  } catch (error) {
    console.error("Import failed:", error);
  }
});
```

### Logging

Use `console.log` and other console methods to trace execution and inspect values. Logs from plugin code appear in the browser console. This can also be helpful for inspecting scene values.

```typescript
creator.ui.onMessage((msg) => {
  console.log("Received message:", msg);

  if (msg.type === "create-shape") {
    console.log("Creating shape with:", msg);
  }
});
```

## Common issues

### 1. Mismatched message formats

If your plugin is not responding to a trigger from the UI (or vice versa), it could be that you're listening for the wrong message formats.

For example:

```typescript
// UI sends this:
parent.postMessage({ pluginMessage: { action: "create" } }, "*");

// Plugin checks for something different:
creator.ui.onMessage((msg) => {
  // Never matches — UI sent 'action', not 'type'
  if (msg.type === "create") {
    // ...
  }
});
```

To resolve this, you can log the actual message to see its shape, or even define a shared type for your messages to catch mismatches:

```typescript
// shared/types.ts
export type PluginMessage = { type: "create-shape"; color: string } | { type: "delete-selection" };

// In plugin UI (App.tsx)
import type { PluginMessage } from "../shared/types";

function handleCreateShape() {
  const message: PluginMessage = { type: "create-shape", color: "#ff0000" };
  parent.postMessage({ pluginMessage: message }, "*");
}

// In plugin sandbox (plugin.ts)
import type { PluginMessage } from "../shared/types";

creator.ui.onMessage((msg: PluginMessage) => {
  if (msg.type === "create-shape") {
    console.log(msg.color);
  }

  // ❌ TypeScript will warn you that 'delete-selection' messages don't have 'color'
  if (msg.type === "delete-selection") {
    console.log(msg.color);
  }
});
```

### 2. UI not showing

If your plugin UI is not showing:

- Check that your development server is running
- Verify the **Development URL** you entered in Lottie Creator's Plugins panel matches your development server
- Confirm `creator.ui.show()` is being called
- Confirm that the UI size passed into `creator.ui.show()` (i.e. meets minimum size and doesn't exceed the current viewport)

### 3. Scene operations failing

If scene operations are failing, try logging scene values or wrapping them in `try-catch` blocks:

```typescript
console.log("Active scene properties:", creator.activeScene);

try {
  creator.activeScene.size = [100, 200];
} catch (err) {
  // You might see something like "unsupported value type", as
  // the correct value to pass in is `creator.activeScene.size = { width: 100, height: 200 }`
  console.log("Error setting scene size:", err);
}
```

If you use TypeScript, Lottie Creator provides typescript types for the Creator API, which will help catch errors ahead of time. You can also refer to the [API Reference](../../api-reference) for details.

### 4. Hot reload failing

If changes to your code aren't reflected in Lottie Creator, it might be that your development server or hot reloading has failed. Try restarting your development server.

### 5. Browser storage APIs not available

If you see this error in the console:

> SecurityError: Failed to read the 'sessionStorage' property from 'Window': The document is sandboxed and lacks the 'allow-same-origin' flag.

This occurs because the plugin UI runs in a sandboxed iframe that restricts access to browser storage APIs like `sessionStorage` and `localStorage`.

Use `creator.clientStorage` instead, which is designed to work within the sandbox:

```typescript
// ❌ This will throw a SecurityError
localStorage.setItem("myKey", "value");
sessionStorage.getItem("myKey");

// ✅ Use creator.clientStorage instead
await creator.clientStorage.set("myKey", "value");
const value = await creator.clientStorage.get("myKey");
```

Note:

- `creator.clientStorage` is only accessible from plugin code (not directly from the UI). If you need to store data from the UI, send a message to your plugin code and have it handle the storage.
- If you're not using `sessionStorage` or `localStorage` but still seeing this error, check if any of your external libraries depend on those browser APIs.

For more details on storage options, see [Storing Data](./storing-data).

### 6. Messages not received after showing UI

If your plugin sends a message to the UI right after calling `creator.ui.show()`, the message may be silently dropped. This happens because `creator.ui.show()` starts loading the UI iframe, but the iframe isn't ready to receive messages immediately.

To fix this, use a **"ui-ready" handshake**: have the UI notify the plugin when it has mounted, and only then send data.

**Plugin code (plugin.ts):**

```typescript
creator.ui.onMessage((message) => {
  if (message.type === "ui-ready") {
    // UI is loaded — safe to send data now
    creator.ui.postMessage({ type: "init", data: someData });
    return;
  }

  // ... handle other messages
});

creator.ui.show({ width: 300, height: 400 });
```

**UI code (App.tsx):**

```typescript
useEffect(() => {
  // Notify the plugin that the UI is ready to receive messages
  parent.postMessage({ pluginMessage: { type: "ui-ready" } }, "*");
}, []);
```

This pattern ensures the plugin waits for the UI iframe to fully load before sending any messages.
