Install guide · Nuxt
Add the Quackback widget to Nuxt
In Nuxt, the widget belongs in a client-only plugin, so it never runs during server rendering. Runtime config carries the workspace URL to the browser and keeps the signing secret on the server.
Get your widget snippet
- 14-day Pro trial, no card needed
- Your workspace URL and snippet, ready to copy
- The widget is on every plan, including Free
The widget your customers see inside your app.
Install the widget in Nuxt
First, in Quackback, open Settings, then Widget, and turn on Show on your website. Until it's on, the snippet loads but the launcher stays hidden. Every snippet uses your-workspace.quackback.io as a placeholder. Swap in your workspace URL, or your custom domain, from Settings, under Widget, then Install.
Install the package
Add @quackback/widget with your package manager.
npm install @quackback/widgetAdd runtime config
The public key reaches the browser. The private one stays on the server for identify later. Nuxt fills both from env variables at runtime.
export default defineNuxtConfig({
runtimeConfig: {
widgetSigningSecret: "", // NUXT_WIDGET_SIGNING_SECRET
public: {
quackbackUrl: "", // NUXT_PUBLIC_QUACKBACK_URL
},
},
});
// .env
// NUXT_PUBLIC_QUACKBACK_URL=https://your-workspace.quackback.ioCreate a client-only plugin
The .client suffix tells Nuxt to run it in the browser only. It runs once per app load, so the launcher appears on every page.
import { Quackback } from "@quackback/widget";
export default defineNuxtPlugin(() => {
const config = useRuntimeConfig();
Quackback.init({ instanceUrl: config.public.quackbackUrl });
});Identify signed-in users
A Nuxt server route signs a five-minute token for the signed-in user. The client plugin fetches it and passes it to identify.
How identify worksAdd a server route that signs the token
Copy the signing secret from Settings, under Widget, then Install, into NUXT_WIDGET_SIGNING_SECRET. Read the user from your session however your auth module exposes it.
import { SignJWT } from "jose";
export default defineEventHandler(async (event) => {
const user = await getSessionUser(event); // your auth helper
if (!user) throw createError({ statusCode: 401 });
const config = useRuntimeConfig(event);
const secret = new TextEncoder().encode(config.widgetSigningSecret);
const ssoToken = await new SignJWT({
sub: String(user.id), // stable user id, never the email
email: user.email,
name: user.name,
})
.setProtectedHeader({ alg: "HS256" })
.setExpirationTime("5m")
.sign(secret);
return { ssoToken };
});Identify from the plugin
Don't await the fetch, so it doesn't hold up hydration. A 401 means nobody is signed in. Call Quackback.logout() wherever you sign users out.
import { Quackback } from "@quackback/widget";
export default defineNuxtPlugin(() => {
const config = useRuntimeConfig();
Quackback.init({ instanceUrl: config.public.quackbackUrl });
$fetch<{ ssoToken: string }>("/api/widget-sso")
.then(({ ssoToken }) => Quackback.identify({ ssoToken }))
.catch(() => {}); // not signed in: stay anonymous
});Good to know on Nuxt
Widget events and methodsCommon questions
Is there a Nuxt module?
Not yet. A client plugin is a few lines and gives you full control. Framework adapters ship on request.
Does this work with static generation?
The widget plugin does, because it runs in the browser. Identify needs a server route, so a fully static site leaves visitors anonymous unless another backend signs the token.
Will the widget slow down my site?
The script loads asynchronously, and the panel loads in an iframe when the browser is idle, so it stays off your critical path. Its theme and settings come from your workspace, so changing them needs no redeploy.
Is the Quackback widget free?
Yes. The widget is on every plan, including Free, with feedback, live chat, help articles and your changelog inside it. Every signup starts with a 14-day Pro trial.
Have another question? Talk to the team.