Install guide · SvelteKit
Add the Quackback widget to SvelteKit
SvelteKit runs your root layout on every page, and onMount only fires in the browser. That makes the layout the right home for the widget, with a server endpoint to sign identify tokens.
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 SvelteKit
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/widgetInit in the root layout
Read the workspace URL from a PUBLIC_ env variable. Returning destroy from onMount cleans up if the layout ever unmounts.
<script lang="ts">
import { onMount } from "svelte";
import { Quackback } from "@quackback/widget";
import { PUBLIC_QUACKBACK_URL } from "$env/static/public";
let { children } = $props();
onMount(() => {
Quackback.init({ instanceUrl: PUBLIC_QUACKBACK_URL });
return () => Quackback.destroy();
});
</script>
{@render children()}
<!-- .env: PUBLIC_QUACKBACK_URL=https://your-workspace.quackback.io -->Open it from your own button
Call Quackback.open from any component, straight to a view.
<script lang="ts">
import { Quackback } from "@quackback/widget";
</script>
<button onclick={() => Quackback.open({ view: "new-post" })}>
Send feedback
</button>Identify signed-in users
A +server.ts endpoint signs a five-minute token for the signed-in user. The layout fetches it once and passes it to identify.
How identify worksAdd an endpoint that signs the token
Copy the signing secret from Settings, under Widget, then Install, into WIDGET_SIGNING_SECRET. $env/static/private keeps it out of the client bundle. This assumes your auth hook sets locals.user.
import { error, json } from "@sveltejs/kit";
import { SignJWT } from "jose";
import { WIDGET_SIGNING_SECRET } from "$env/static/private";
import type { RequestHandler } from "./$types";
const secret = new TextEncoder().encode(WIDGET_SIGNING_SECRET);
export const GET: RequestHandler = async ({ locals }) => {
const user = locals.user; // set by your auth hook
if (!user) error(401);
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 json({ ssoToken });
};Identify from the layout
Fetch once on mount. Call Quackback.logout() in your sign-out action.
onMount(() => {
Quackback.init({ instanceUrl: PUBLIC_QUACKBACK_URL });
fetch("/api/widget-sso")
.then((res) => (res.ok ? res.json() : null))
.then((data) => data && Quackback.identify({ ssoToken: data.ssoToken }));
return () => Quackback.destroy();
});Good to know on SvelteKit
Widget events and methodsCommon questions
Is there a Svelte store or adapter?
Not yet. Svelte apps import Quackback from @quackback/widget and call it directly. Subscribe to events such as vote with Quackback.on, which returns an unsubscribe function you can return from onMount.
Does it work with prerendered pages?
Yes. The widget inits in the browser after the page loads. Identify needs the endpoint, which only runs where SvelteKit has a server.
Do visitors have to sign in to use the widget?
No. Once Show on your website is on in your widget settings, the launcher appears for every visitor after init. Anonymous visitors can still post, vote and chat, and can leave an email inline. When you identify them later, what they did before signing in moves onto their account.
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.