Skip to content
Swingback, home
Docs / JavaScript

JavaScript

One script tag puts a feedback button at the corner of your pages. It opens your widget in a panel, with your user already signed in.

Add the script#

Your portal serves the script. Copy the tag from Settings → Widget, under Install, or write it with your portal's address:

<script src="https://acme.example.com/widget/v1.js" data-token-url="/feedback-token" async></script>

The button takes your widget's accent color, and sits on the side you chose under Settings → Widget. It opens a panel with your widget: feedback, the roadmap and the changelog, as on your portal. On a phone, the panel takes the screen above the button. Escape closes it.

The script loads nothing more until the button is pressed, but its settings: your portal's colors and the button's side, in the reader's language.

Sign your user in#

data-token-url names an endpoint of your server. Each time the widget opens, the script asks it for the signed-in user's identity token, with your page's cookies:

  • Answer { "token": "…" } with a token your server signs: Signing in your users shows how.
  • Answer { "token": null }, a 401 or a 403 when nobody is signed in. The widget then ends the session of a user it had, and keeps a guest's.

Without data-token-url, people read the widget, and writing asks them to sign in to your product, or to continue as guests where your portal takes them.

Options#

AttributeWhat it does
data-token-urlThe endpoint that answers with the signed-in user's identity token.
data-launcher="false"No button: your own control calls Swingback.open(). A close button shows while the panel is open.
data-manualNothing starts until your page calls Swingback.init({ ... }).

From your code#

Once loaded, the script is window.Swingback:

Swingback.open(); // the feedback
Swingback.open("changelog"); // or "roadmap", "new", { post: "dark-mode" }, { board: "ideas" }
Swingback.close();
Swingback.identify(); // after your user signs in or out: the widget asks for a token again
Swingback.logout(); // ends the widget's session, a guest's too
Swingback.on("error", (event) => console.warn("Feedback widget:", event.code));

Its events are ready, identified, signed-out, error, open and close. An error has the code of the widget's errors, or token_unavailable when your endpoint couldn't be asked.

Content Security Policy#

If your pages send one, allow your portal's address in script-src (the script), connect-src (its settings) and frame-src (the widget). The button needs no inline style. A browser too old to adopt a stylesheet gets a <style> element instead, with the script tag's own nonce, if it has one.

The npm package#

The same widget, from your bundle:

import { createSwingback, embed } from "@swingback/js";

const swingback = createSwingback({
  portal: "https://acme.example.com",
  tokenUrl: "/feedback-token", // or token: async () => (await yourApi.feedbackToken()) ?? null
});
swingback.open("roadmap");

// Or the widget inside an element of your page, filling it:
embed(document.getElementById("feedback"), { portal: "https://acme.example.com", tokenUrl: "/feedback-token" });

For React, see the React SDK.