Skip to main content
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.

Vue-friendly imports

Import BEEQ components as PascalCase Vue components instead of relying only on raw custom elements.

Custom elements support

Tell Vue to treat all bq- tags as custom elements so your templates stay clean and warning-free.

`v-model` support

Use compatible BEEQ form controls with v-model for a more natural Vue authoring experience.
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.

Get started

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

Check your project setup

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.
2

Install the packages

Install both the core package and the Vue wrapper:
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
3

Tell Vue to treat BEEQ as custom elements

Vue should compile bq- tags as custom elements instead of trying to resolve them as local Vue components.Configure @vitejs/plugin-vue:
vite.config.ts
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:
app.config.compilerOptions.isCustomElement = (tag) => tag.includes("bq-");
4

Add the global styles

Import the BEEQ stylesheet once in your application’s main stylesheet:
src/style.css
@import "@beeq/core/dist/beeq/beeq.css";
5

Configure icons

Many BEEQ components rely on SVG icons. Your application needs to serve the SVG files and tell BEEQ where to find them.
Be aware that there are over 9k SVG files, which can slow down your development or bundling time if you copy all of them.
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:
src/index.html
<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>
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.
If you are using Vite, install the static copy plugin:
npm install -D vite-plugin-static-copy
Then copy the SVG files and set the base path during app startup:
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",
        },
      ],
    }),
  ],
});
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 for inspiration.
6

Render your first component

Once styles and icons are configured, import and use BEEQ components in your Vue app:
<script setup lang="ts">
import { BqButton, BqIcon } from "@beeq/vue";
</script>

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

Vue usage patterns with BEEQ

Import components from @beeq/vue

Use the Vue wrapper when you want a more natural Vue authoring experience:
<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:
<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:
<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>
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.
The following BEEQ components support v-model:
ComponentBound prop
BqCheckbox, BqSwitchchecked
BqDatePicker, BqInput, BqRadioGroup, BqSelect, BqSlider, BqTextareavalue
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:
<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.
<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:
plugins/beeq.client.ts
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:
{
  "html.customData": ["./node_modules/@beeq/core/dist/beeq.html-custom-data.json"]
}

Troubleshooting

Make sure your Vue compiler config includes isCustomElement: (tag) => tag.includes("bq-").
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
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.
Make sure @beeq/core/dist/beeq/beeq.css is imported once in the stylesheet your Vue app actually loads.
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.

Next steps

Explore components

Start with a component page to see props, events, slots, and framework examples.

Customize the theme

Review theming options if your product needs brand customization.

Open Storybook

Explore component states and interactions in the live component library.