--- url: https://chartbuddy.io/embed/docs/guides/vue.md --- > Docs index: [llms.txt](https://chartbuddy.io/embed/docs/llms.txt) # Vue ```bash npm install @chartbuddy.io/embed vue ``` `vue` is an optional peer dependency — install it only if you use these bindings. Vue 3. ```vue ``` The chart fills its container, so **give the container a height**. A container with no height renders nothing visible. ## Without a bundler (CDN / single HTML file) The bindings import `vue` as a bare specifier, so a plain HTML page needs an **import map**. Use the browser ESM build of Vue, and render without SFCs: ```html
``` The import map must map **both** `vue` and `@chartbuddy.io/embed/vue`, and the subpath needs the explicit `.mjs` file — bare-specifier subpath resolution does not work in browsers. For a standalone artifact with no framework at all, the [custom element](https://chartbuddy.io/embed/docs/guides/angular.md#other-frameworks) needs no import map. ## Why use the wrapper `new Insight()` owns a DOM node and lives across renders. The wrapper handles the lifecycle so you don't: * **Data changes patch instead of remount.** A new `chartData` calls `update()` on the live instance. Rebuilding the chart on every change makes an embedded editor feel broken. * **Only construction options remount.** Changing `editable` or `instanceId` rebuilds the chart; everything else is applied in place. * **Reactive proxies never reach the engine.** The wrapper passes `toRaw()` config, so Vue's proxy wrapper doesn't leak into chart internals. * **Unmount destroys.** Listeners and the instance are cleaned up on `onBeforeUnmount`. ## Editable charts with two-way data ```vue ``` `change` fires after live edits in edit mode, after programmatic updates, and on Done. Feeding it straight back into `chartData` is safe — the wrapper compares by identity and the object it hands you is the one it already applied. ## Assign, don't mutate `chartData` is compared **by identity**, not deeply. Mutating a nested property in place will not be detected: ```js // Not picked up — same object identity chartData.value.title.text = 'FY26'; // Picked up chartData.value = { ...chartData.value, title: { text: 'FY26' } }; ``` ## Events | Event | Payload | |---|---| | `ready` | The `Insight` instance | | `change` | `ChartData \| null` | | `mode` | `'view' \| 'edit'` | | `error` | `Error` — a `ChartDataValidationError` for invalid config | ## `useInsight` for imperative access When you need the instance itself — PNG export, edit mode, revision tracking — use the composable and place the container yourself. ```vue ``` `chartData` accepts a plain object, a `ref`, or a getter. `insight` is a `shallowRef` holding `null` until the mount resolves — guard imperative calls on `ready`. ## What remounts, what patches | Prop change | Effect | |---|---| | `chartData` | `update()` on the live instance | | `instanceId`, `editable`, `assetBase`, `hostOverrides` | Full remount (destroy + construct) | | Anything else in the parent | Nothing | Toggling `editable` remounting is deliberate: view mode and the full editor are different mounts. If you toggle it often, prefer one mount plus `insight.enterEditMode()` / `exitEditMode()`. ## Handling invalid data Chart data is validated at the API boundary, so bad data fails at mount. The wrapper surfaces it rather than throwing through your render: ```vue ``` See [Validation](https://chartbuddy.io/embed/docs/quality-assurance/validation.md). ## Dashboards One `` per chart, each with a stable `instance-id`. Duplicate ids on a page throw, so derive them from your data rather than the loop index if the list can reorder. ```vue ``` The engine loads once per page, not once per chart — but read [Installation](https://chartbuddy.io/embed/docs/getting-started/installation.md#bundle-size-and-many-charts) before putting a lot of charts on one screen. ## Nuxt / SSR The bindings are browser-only: the chart engine needs a real DOM. The mount happens in `onMounted`, so nothing runs during SSR, but wrap usage in `` so Nuxt does not try to render it on the server: ```vue ``` There is no headless/Node render path today, so charts cannot be pre-rendered to PNG on a server.