Skip to content

Embed in a Vue app

When your host page is already a Vue 3 + Pinia app, you have two choices:

  1. Import enableAutopilotBar from autopilot-client/bar — the simplest path. Vue and Pinia are bundled into the bar's IIFE, but you do not interact with them directly; you treat it the same as the standalone embed.
  2. Use individual components from autopilot-client/vue — more work, but tree-shakable, and the components share your app's Vue/Pinia instance.

This page covers option 1. For option 2 see Vue components.

Setup

ts
// src/main.ts
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import { AutopilotClient, setAutopilotClient } from '@llmor/autopilot-core';
import { enableAutopilotBar } from '@llmor/autopilot-bar';
import App from './App.vue';

const client = new AutopilotClient();
setAutopilotClient(client);

const app = createApp(App);
app.use(createPinia());
app.mount('#app');

client
  .connect({ conversationUrl: import.meta.env.VITE_CONVERSATION_URL })
  .then(() => enableAutopilotBar(client))
  .catch((err) => console.error('autopilot failed', err));

The bar mounts itself after the connection is ready. You can mount it earlier — it tolerates a disconnected client — but waiting avoids a flash of "disconnected" state on first paint.

Note on Pinia instances

The bar's IIFE bundle includes its own copy of Vue and Pinia. Despite this, both apps share the autopilot store because Pinia stores are identified by their defineStore ID — and there is only one definition, statically.

In practice: anything you useAutopilotStore() from in your components reads the same state the bar mutates. You do not need to forward props or share a Pinia instance manually.

Cleaning up on unmount

If your Vue app gets torn down (for example, micro-frontend lifecycles), destroy the bar too:

ts
let bar: { destroy(): void } | null = null;

client.connect({ conversationUrl }).then(() => {
  bar = enableAutopilotBar(client);
});

app.unmount = () => {
  bar?.destroy();
  client.disconnect();
  // …
};

Per-component function registration

You can register autopilot functions from inside Vue components as usual — the bar picks them up immediately because both ends use the same singleton client.

vue
<script setup lang="ts">
import { onScopeDispose } from 'vue';
import { useAutopilotClient } from '@llmor/autopilot-core';

const client = useAutopilotClient();

client.registerFunction({
  name: 'open_user_profile',
  parameters: {
    type: 'object',
    properties: { id: { type: 'string' } },
    required: ['id'],
  },
  handler: ({ id }: { id: string }) => {
    router.push({ name: 'user', params: { id } });
  },
});

onScopeDispose(() => client.unregisterFunction('open_user_profile'));
</script>