# Quickstart — Vue

Integrate `@ios-web-bluetooth/core` with a Vue 3 Composition API component.

## Prerequisites

- The WebBLE Safari Web Extension enabled on your origin. See the [base quickstart](quickstart.md).
- Vue 3 (Composition API). Works with Vite, Nuxt, Quasar.

## 1. Install

```bash
npm install @ios-web-bluetooth/core
```

## 2. Mount the polyfill at app entry

```ts
// main.ts
import '@ios-web-bluetooth/core/auto';
import { createApp } from 'vue';
import App from './App.vue';

createApp(App).mount('#app');
```

Importing once installs `navigator.bluetooth` and `window.webbleIOS` before any component code runs.

## 3. Read a heart-rate monitor

```vue
<!-- HeartRate.vue -->
<script setup lang="ts">
import { ref } from 'vue';

const bpm = ref<number | null>(null);
const err = ref<string | null>(null);

async function connect() {
  try {
    const device = await navigator.bluetooth.requestDevice({
      filters: [{ services: ['heart_rate'] }]
    });
    const server = await device.gatt!.connect();
    const service = await server.getPrimaryService('heart_rate');
    const char = await service.getCharacteristic('heart_rate_measurement');
    await char.startNotifications();
    char.addEventListener('characteristicvaluechanged', (ev) => {
      const v = (ev.target as BluetoothRemoteGATTCharacteristic).value!;
      bpm.value = v.getUint8(0) & 0x01 ? v.getUint16(1, true) : v.getUint8(1);
    });
  } catch (e: any) {
    err.value = e.message;
  }
}
</script>

<template>
  <button @click="connect">Connect</button>
  <p v-if="err">Error: {{ err }}</p>
  <p v-else>{{ bpm ?? '—' }} bpm</p>
</template>
```

## 4. Nuxt note

In Nuxt, mount the polyfill from a client-only plugin:

```ts
// plugins/webble.client.ts
import '@ios-web-bluetooth/core/auto';
export default defineNuxtPlugin(() => {});
```

The `.client.ts` suffix prevents SSR from evaluating the polyfill, which touches `window` at import time.

## Next

- [API reference](api-reference.md)
- [Recipes](recipes.md)
- [Premium APIs](premium.md)
