Skip to content

Install guide · Angular

Add the Quackback widget to Angular

Angular apps call the Quackback widget directly. Init it with afterNextRender in your root component, which runs only in the browser, so the same code works with or without server rendering.

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.

Your team’s viewYour customers’ view
Feedback
Review
Status
Board
Tags

Install the widget in Angular

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.

Read the full install docs

Install the package

Add @quackback/widget with your package manager.

Terminal
npm install @quackback/widget

Add the workspace URL to your environment

Generate environment files with ng generate environments if your project doesn't have them.

src/environments/environment.ts
export const environment = {
  quackbackUrl: "https://your-workspace.quackback.io",
};

Init in the root component

afterNextRender skips the server and runs once in the browser after the first render. That needs Angular 17 or later.

src/app/app.component.ts
import { Component, afterNextRender } from "@angular/core";
import { RouterOutlet } from "@angular/router";
import { Quackback } from "@quackback/widget";
import { environment } from "../environments/environment";

@Component({
  selector: "app-root",
  standalone: true,
  imports: [RouterOutlet],
  template: "<router-outlet />",
})
export class AppComponent {
  constructor() {
    afterNextRender(() => {
      Quackback.init({ instanceUrl: environment.quackbackUrl });
    });
  }
}

Identify signed-in users

Your backend signs a five-minute token for the signed-in user. The app fetches it once and passes it to identify.

How identify works

Sign a token on your server

Copy the signing secret from Settings, under Widget, then Install, into a server-only env variable. Return { ssoToken } for the current session, and 401 when nobody is signed in.

server/widget-sso.ts
import { SignJWT } from "jose";

const secret = new TextEncoder().encode(process.env.WIDGET_SIGNING_SECRET);

app.get("/api/widget-sso", async (req, res) => {
  const user = req.user; // from your auth middleware
  if (!user) return res.status(401).end();

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

  res.json({ ssoToken });
});

Identify from a service

Call identify when the app loads with a session and right after sign-in. Call logout from your sign-out flow.

src/app/feedback-widget.service.ts
import { Injectable, inject } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { Quackback } from "@quackback/widget";

@Injectable({ providedIn: "root" })
export class FeedbackWidgetService {
  private http = inject(HttpClient);

  identify() {
    this.http
      .get<{ ssoToken: string }>("/api/widget-sso")
      .subscribe({
        next: ({ ssoToken }) => Quackback.identify({ ssoToken }),
        error: () => {}, // not signed in: stay anonymous
      });
  }

  logout() {
    Quackback.logout();
  }
}

Good to know on Angular

Widget events and methods
Not in ngOnInit with SSRngOnInit runs on the server during server rendering, where there's no DOM. afterNextRender only runs in the browser.
Older AngularBefore Angular 17, init in ngOnInit and guard it with isPlatformBrowser(this.platformId) if you use Angular Universal.
Change detectionThe widget lives outside Angular. If an event handler from Quackback.on updates your component state, run it inside NgZone or use a signal.

Common questions

Is there an Angular module?

Not yet. Angular apps import Quackback from @quackback/widget and call it directly, usually from a small service like the one above.

Can I open the widget from a menu item?

Yes. Call Quackback.open({ view: "new-post" }) from a click handler. Pass launcher: false to init if you'd rather hide the floating button.

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.

Put feedback inside your Angular app