How to add an AI chatbot to a Vue or Nuxt app

Paste the Feedbot script tag into index.html of your Vue app (or app.head in nuxt.config for Nuxt) and an AI chatbot trained on your content appears on every page. Control it from components with the global Feedbot() function: open the chat, identify the user, reset on logout.

  • Setup: 5 minutes
  • Free plan, no card
  • Updated

Many “vue chatbot” tutorials show how to build a chat app from scratch with the OpenAI API. That’s a good weekend project, but then you also own retrieval over your docs, storage, rate limits and handoff to a human. If you need a working assistant on an existing Vue site, embed one. Below is how with Feedbot (our product).

What you need

  • A Feedbot bot id from Dashboard → Bot → Install (the Free plan works).
  • A Vue 3 app (Vite) or a Nuxt 3/4 app. Vue 2 works the same with the script tag.

Option 1: script tag in index.html

  1. Open index.html at the root of your Vite project.

  2. Paste before </body>:

    <script src="https://w.feedbotai.com/v1/feedbot.js" data-bot-id="YOUR_BOT_ID" async></script>
  3. Run npm run dev. A chat button appears in the corner. Ask it a question to check.

That’s the whole install. It loads about 6 KB gzipped and fetches the chat only when the visitor hovers or clicks, or when the browser is idle.

Option 2: load it from a composable

Use this when the bot id comes from an environment variable or you want to load the chat only after login.

src/composables/useFeedbot.ts
type FeedbotFn = ((...args: unknown[]) => unknown) & { q?: unknown[] };
declare global { interface Window { Feedbot: FeedbotFn } }
export function useFeedbot() {
// Queue stub: calls made before the loader finishes are replayed.
window.Feedbot = window.Feedbot || function (...args: unknown[]) {
(window.Feedbot.q = window.Feedbot.q || []).push(args);
};
function load(botId: string) {
if (document.querySelector("script[data-bot-id]")) return;
const s = document.createElement("script");
s.src = "https://w.feedbotai.com/v1/feedbot.js";
s.async = true;
s.dataset.botId = botId;
document.body.appendChild(s);
}
const call = (...args: unknown[]) => window.Feedbot(...args);
return { load, call };
}
src/App.vue
<script setup lang="ts">
import { onMounted } from "vue";
import { useFeedbot } from "./composables/useFeedbot";
const feedbot = useFeedbot();
onMounted(() => feedbot.load(import.meta.env.VITE_FEEDBOT_BOT_ID));
</script>
<template>
<RouterView />
<button @click="feedbot.call('open')">Chat with us</button>
</template>

The loader ignores a second copy of itself, so remounting App.vue in development is harmless.

Nuxt

Add the script globally in nuxt.config.ts, using the app.head option:

nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
script: [
{ src: "https://w.feedbotai.com/v1/feedbot.js", async: true, "data-bot-id": "YOUR_BOT_ID" },
],
},
},
});

To load it only in one layout or page, use useHead() there instead, with tagPosition: "bodyClose":

layouts/app.vue
<script setup lang="ts">
useHead({
script: [{
src: "https://w.feedbotai.com/v1/feedbot.js",
async: true,
"data-bot-id": "YOUR_BOT_ID",
tagPosition: "bodyClose",
}],
});
</script>

Call window.Feedbot only on the client, for example in onMounted, since it doesn’t exist during server rendering.

Open the chat from a button

Command What it does
Feedbot("open") / Feedbot("close") / Feedbot("toggle") Show or hide the chat
Feedbot("sendMessage", "How do refunds work?") Open the chat and send the text as the visitor
Feedbot("setMetadata", { plan: "pro" }) Attach context to the conversation
Feedbot("on", "message", cb) Listen to ready, open, close, message

The full list is in the JavaScript API docs.

Identify signed-in users

Watch your auth store and call identify with a hash your backend computes:

import { watch } from "vue";
watch(() => auth.user, (user) => {
if (user) {
window.Feedbot("identify", {
userId: user.id,
email: user.email,
name: user.name,
hash: user.feedbotHash, // HMAC-SHA256(identitySecret, user.id), from your API
});
} else {
window.Feedbot("reset"); // logout: forget the visitor on this device
}
}, { immediate: true });

Never compute the hash in the browser: the identity secret must stay on your server. In Nuxt you can compute it in a server route (server/api/). Code for Node, Python and PHP is in Identify users.

Troubleshooting

Symptom Cause Fix
No chat button Bot id is empty Vite only exposes env variables prefixed with VITE_. Restart the dev server after editing .env.
window.Feedbot is not a function Called before the stub exists Add the queue stub (see the composable) before your first call.
window is not defined in Nuxt Called during server rendering Move the call into onMounted or a .client plugin.
Requests rejected Domain not in Allowed domains Add localhost and your domain in Bot → Install → Allowed domains.
Blocked by CSP Strict policy Allow https://w.feedbotai.com in script-src and https://api.feedbotai.com in connect-src.

Train it on your content

On Free, add text and FAQ. From Starter, import your site by URL or sitemap (pages rendered by Vue in the browser are read with a real browser) and upload PDF, DOCX or Markdown. See knowledge base. For questions the bot can’t answer, it hands off to you in Telegram, Slack, Discord or email: handoff docs.

Next steps

Questions

Can't find an answer? Ask the bot in the corner, or write to us.

Is there a Vue component for the Feedbot chatbot?

There's no Vue package. You don't need one: the widget is a plain script that renders in its own Shadow DOM, and you control it with the global Feedbot() function from any component.

Does it work with Vue Router navigation?

Yes. Load the script once, in index.html or App.vue, not in a route component. The widget is attached to the document, so route changes don't reload it or close the conversation.

How do I add the chatbot to Nuxt?

Add the script to app.head.script in nuxt.config.ts with src, async and data-bot-id. Use useHead() in app.vue or a layout if you need it only on some pages.

Will it conflict with my Tailwind or Vuetify styles?

No. The widget renders inside a Shadow DOM, so your global CSS doesn't reach it and its CSS doesn't leak into your app.

Can I build my own Vue chat UI on top of Feedbot?

Not today. Feedbot ships its own chat UI. For a fully custom UI, use inline mode to place the chat inside your own layout, or build on a library such as the Vercel AI SDK's Vue bindings.

Keep exploring

Put one agent on your site today

Start on the free plan. Upgrade when conversations grow.