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();

const dispose = 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 } });
  },
});

// the disposer only removes this registration — safe if the page is remounted
onScopeDispose(dispose);
</script>