> ## Documentation Index
> Fetch the complete documentation index at: https://www.beeq.design/llms.txt
> Use this file to discover all available pages before exploring further.

# Vue.js

> Use BEEQ in Vue through the Vue wrapper for cleaner component imports, event bindings, and `v-model` support.

BEEQ works best in Vue through `@beeq/vue`, the official Vue wrapper around BEEQ web components.

Vue already handles custom elements well, and the BEEQ wrapper makes the developer experience even smoother by adding typed component imports and `v-model` support for compatible form controls.

<Columns cols={3}>
  <Card title="Vue-friendly imports">
    Import BEEQ components as PascalCase Vue components instead of relying only on raw custom elements.
  </Card>

  <Card title="Custom elements support">
    Tell Vue to treat all `bq-` tags as custom elements so your templates stay clean and warning-free.
  </Card>

  <Card title="`v-model` support">
    Use compatible BEEQ form controls with `v-model` for a more natural Vue authoring experience.
  </Card>
</Columns>

<Check>
  Vue has strong built-in support for custom elements — you can use raw `bq-*` elements in templates without any wrapper. `@beeq/vue` adds PascalCase component imports, TypeScript types, and native `v-model` support for compatible form controls.
</Check>

## Get started

You can add BEEQ to an existing Vue project in a few steps:

<Steps>
  <Step title="Check your project setup" titleSize="h3">
    Make sure your project already has:

    * Vue `3`
    * Node.js `18+`
    * a Vue application created with Vite or another modern build setup

    If you are starting a new Vue project, Vite is usually the simplest setup path.
  </Step>

  <Step title="Install the packages" titleSize="h3">
    Install both the core package and the Vue wrapper:

    ```bash theme={"theme":{"light":"one-light","dark":"night-owl"}}
    npm install @beeq/core @beeq/vue
    ```

    What each package gives you:

    * `@beeq/core` includes the web components, styles, icons, and shared types
    * `@beeq/vue` provides Vue-friendly component wrappers
  </Step>

  <Step title="Tell Vue to treat BEEQ as custom elements" titleSize="h3">
    Vue should compile `bq-` tags as custom elements instead of trying to resolve them as local Vue components.

    Configure `@vitejs/plugin-vue`:

    ```ts vite.config.ts theme={"theme":{"light":"one-light","dark":"night-owl"}}
    import vue from "@vitejs/plugin-vue";
    import { defineConfig } from "vite";

    export default defineConfig({
      plugins: [
        vue({
          template: {
            compilerOptions: {
              isCustomElement: (tag) => tag.includes("bq-"),
            },
          },
        }),
      ],
    });
    ```

    If you are using Vue without a build step, configure the compiler directly:

    ```ts theme={"theme":{"light":"one-light","dark":"night-owl"}}
    app.config.compilerOptions.isCustomElement = (tag) => tag.includes("bq-");
    ```
  </Step>

  <Step title="Add the global styles" titleSize="h3">
    Import the BEEQ stylesheet once in your application's main stylesheet:

    ```css src/style.css theme={"theme":{"light":"one-light","dark":"night-owl"}}
    @import "@beeq/core/dist/beeq/beeq.css";
    ```
  </Step>

  <Step title="Configure icons" titleSize="h3">
    Many BEEQ components rely on SVG icons. Your application needs to serve the SVG files and tell BEEQ where to find them.

    <Warning>
      Be aware that **there are over 9k SVG files**, which can slow down your development or bundling time if you copy all of them.
    </Warning>

    The fastest way to tell BEEQ where to find the icons is to add a `<script>` tag with the `data-beeq` attribute  in your `index.html` entry point:

    ```html src/index.html highlight={6-8} theme={"theme":{"light":"one-light","dark":"night-owl"}}
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <link rel="icon" type="image/svg+xml" href="/vite.svg" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <script
          data-beeq="https://cdn.jsdelivr.net/npm/@beeq/core/dist/beeq/svg/"
        ></script>
        <title>Vite + BEEQ</title>
      </head>
      <body>
        <div id="app"></div>
        <script type="module" src="/src/main.ts"></script>
      </body>
    </html>
    ```

    <Tip>
      The URL must point to the directory that contains BEEQ SVG files (file names such as `user.svg`, `envelope.svg`). You can use a CDN URL, a path your app serves locally, or even a different icon library — just make sure the icon `name` values you use in templates match the file names at that path.
    </Tip>

    If you are using Vite, install the static copy plugin:

    ```bash theme={"theme":{"light":"one-light","dark":"night-owl"}}
    npm install -D vite-plugin-static-copy
    ```

    Then copy the SVG files and set the base path during app startup:

    <CodeGroup>
      ```ts vite.config.ts highlight={2,14-21} expandable theme={"theme":{"light":"one-light","dark":"night-owl"}}
      import vue from "@vitejs/plugin-vue";
      import { viteStaticCopy } from "vite-plugin-static-copy";
      import { defineConfig } from "vite";

      export default defineConfig({
        plugins: [
          vue({
            template: {
              compilerOptions: {
                isCustomElement: (tag) => tag.includes("bq-"),
              },
            },
          }),
          viteStaticCopy({
            targets: [
              {
                src: "./node_modules/@beeq/core/dist/beeq/svg/*",
                dest: "icons/svg",
              },
            ],
          }),
        ],
      });
      ```

      ```ts src/main.ts highlight={2,6} expandable theme={"theme":{"light":"one-light","dark":"night-owl"}}
      import { createApp } from "vue";
      import { setBasePath } from "@beeq/core";
      import App from "./App.vue";
      import "./style.css";

      setBasePath("/icons/svg");

      createApp(App).mount("#app");
      ```
    </CodeGroup>

    <Tip>
      You can create a Vite plugin that copies only the icons you need to speed up development and reduce your bundle size.
      See the React setup [here](/guides/frameworks/react#copy-only-the-icons-you-need) for inspiration.
    </Tip>
  </Step>

  <Step title="Render your first component" titleSize="h3">
    Once styles and icons are configured, import and use BEEQ components in your Vue app:

    ```vue theme={"theme":{"light":"one-light","dark":"night-owl"}}
    <script setup lang="ts">
    import { BqButton, BqIcon } from "@beeq/vue";
    </script>

    <template>
      <BqButton>
        Save changes
        <BqIcon name="floppy-disk" slot="suffix" />
      </BqButton>
    </template>
    ```
  </Step>
</Steps>

## Vue usage patterns with BEEQ

### Import components from `@beeq/vue`

Use the Vue wrapper when you want a more natural Vue authoring experience:

```vue theme={"theme":{"light":"one-light","dark":"night-owl"}}
<script setup lang="ts">
import { BqButton, BqCard, BqInput } from "@beeq/vue";
</script>
```

### Use Vue event bindings with `@bq...`

BEEQ custom events work with standard Vue event binding syntax:

```vue theme={"theme":{"light":"one-light","dark":"night-owl"}}
<template>
  <BqButton @bqClick="save">Save changes</BqButton>
</template>
```

### Use `v-model` on supported form controls

The Vue wrapper supports `v-model` on compatible BEEQ controls. For input components, also handle the `@bqClear` event to keep your reactive ref in sync when the user clicks the clear button:

```vue theme={"theme":{"light":"one-light","dark":"night-owl"}}
<script setup lang="ts">
import { ref } from "vue";
import { BqInput } from "@beeq/vue";

const name = ref("John Doe");
</script>

<template>
  <BqInput
    v-model="name"
    name="name"
    placeholder="How should we call you?"
    @bqClear="name = ''"
  />
</template>
```

<Tip>
  Without `@bqClear`, clicking the clear button resets the component's internal value but does not update your reactive ref. Always pair `v-model` with `@bqClear` on clearable inputs.
</Tip>

The following BEEQ components support `v-model`:

| Component                                                                       | Bound prop |
| ------------------------------------------------------------------------------- | ---------- |
| `BqCheckbox`, `BqSwitch`                                                        | `checked`  |
| `BqDatePicker`, `BqInput`, `BqRadioGroup`, `BqSelect`, `BqSlider`, `BqTextarea` | `value`    |

All of them fire `bqChange` as the trigger event.

### Slots still use the `slot` attribute

Slotted content works the same way as in the web component API:

```vue theme={"theme":{"light":"one-light","dark":"night-owl"}}
<script setup lang="ts">
import { BqIcon, BqInput } from "@beeq/vue";
</script>

<template>
  <BqInput placeholder="Email address">
    <BqIcon name="envelope" slot="prefix" />
  </BqInput>
</template>
```

## Complete example

This example combines component imports, `v-model`, icons, and event bindings in a Vue app.

```vue theme={"theme":{"light":"one-light","dark":"night-owl"}}
<script setup lang="ts">
import { ref } from "vue";
import { BqButton, BqCard, BqIcon, BqInput } from "@beeq/vue";

const count = ref(0);
const name = ref("");

const increment = () => {
  count.value += 1;
};
</script>

<template>
  <BqCard>
    <h1>Hello, {{ name || "stranger" }}!</h1>

    <BqInput v-model="name" placeholder="How should we call you?" @bqClear="name = ''">
      <BqIcon name="user" slot="prefix" />
    </BqInput>

    <BqButton @bqClick="increment">
      Give a thumbs up
      <BqIcon name="thumbs-up" slot="suffix" />
    </BqButton>

    <p>Total of thumbs: {{ count }}</p>
  </BqCard>
</template>
```

## Server-side rendering (Nuxt and SSR frameworks)

If you are using Nuxt or another Vue SSR framework, wrap `setBasePath()` in a client-only plugin to ensure it only runs in the browser:

```ts plugins/beeq.client.ts theme={"theme":{"light":"one-light","dark":"night-owl"}}
import { setBasePath } from "@beeq/core";

export default defineNuxtPlugin(() => {
  setBasePath("/icons/svg");
});
```

The `.client.ts` suffix tells Nuxt to load this plugin only on the client side. If you are using a different SSR framework, wrap the call inside `onMounted()` instead.

## VS Code autocomplete

BEEQ ships HTML custom data for Visual Studio Code, which improves completion and inline hints for the underlying custom elements.

Create `.vscode/settings.json` in your project root and add:

```json theme={"theme":{"light":"one-light","dark":"night-owl"}}
{
  "html.customData": ["./node_modules/@beeq/core/dist/beeq.html-custom-data.json"]
}
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Vue is warning about unknown elements">
    Make sure your Vue compiler config includes `isCustomElement: (tag) => tag.includes("bq-")`.
  </Accordion>

  <Accordion title="Icons are not rendering">
    Check both of these:

    * the SVG files are being served by your app
    * `setBasePath()` points to the same public URL where those files are available
  </Accordion>

  <Accordion title="`v-model` is not updating">
    Confirm that you are using the Vue wrapper from `@beeq/vue` and that the component supports `v-model` (see the table in the `v-model` usage pattern section above). Also make sure you have added `@bqClear` to handle the clear button.
  </Accordion>

  <Accordion title="Styles are missing">
    Make sure `@beeq/core/dist/beeq/beeq.css` is imported once in the stylesheet your Vue app actually loads.
  </Accordion>

  <Accordion title="Can I use raw bq-* elements without the Vue wrapper?">
    Yes. Once you have `isCustomElement: (tag) => tag.includes("bq-")` set in your Vite or compiler config, you can use `<bq-button @bqClick="save">` directly in templates. The Vue wrapper gives you cleaner PascalCase imports and native `v-model` support, but raw custom elements work too.
  </Accordion>
</AccordionGroup>

## Next steps

<Columns cols={3}>
  <Card title="Explore components" href="/components" icon="boxes-stacked" iconType="duotone">
    Start with a component page to see props, events, slots, and framework examples.
  </Card>

  <Card title="Customize the theme" href="/theming/themes-and-modes" icon="palette" iconType="duotone">
    Review theming options if your product needs brand customization.
  </Card>

  <Card title="Open Storybook" href="https://storybook.beeq.design" icon="book" iconType="duotone">
    Explore component states and interactions in the live component library.
  </Card>
</Columns>
