Developer Documentation

Widget Integration

Embed the FWD Hub widget on your website with a single script tag. Optionally pass user identity for a seamless, personalized support experience.

Installation

Add the loader script to your HTML. The data-workspace attribute must match your workspace slug from the FWD Hub dashboard.

HTML
<script
  src="https://hub.flyweight.dev/widget/loader.js"
  data-workspace="your-workspace-slug"
></script>

The script creates a floating launcher button and loads the widget in an iframe. It works on any website — static HTML, React, Vue, Next.js, WordPress, etc. No build step required.

Single-Page Apps

The loader automatically tracks client-side navigation by intercepting pushState, replaceState, and popstate. No extra configuration needed for React Router, Next.js, Vue Router, or similar.

Next.js

Use the Next.js Script component for optimal loading:

app/layout.tsx
import Script from "next/script";

export default function Layout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Script
          src="https://hub.flyweight.dev/widget/loader.js"
          data-workspace="your-workspace-slug"
          strategy="lazyOnload"
        />
      </body>
    </html>
  );
}

JavaScript API

The loader exposes a global window.FWDHub object with the following methods:

FWDHub.open(module?)

Open the widget. Optionally pass a module name to open a specific tab: "messages", "help", "feedback", or "changelog".

// Open the widget
FWDHub.open();

// Open directly to the feedback tab
FWDHub.open("feedback");
FWDHub.close()

Close the widget.

FWDHub.identify(data)

Identify the current user. See User Identification below.

FWDHub.shutdown()

Remove the widget from the page entirely. Useful for cleanup on logout or when navigating to pages where the widget shouldn't appear.

User Identification

By default, visitors must enter their name and email before they can send messages or feedback. If your app already knows who the user is (they're logged in), you can pass their identity to the widget programmatically — skipping the identification form entirely.

JavaScript
FWDHub.identify({
  userId: "usr_123",             // Required — your system's user ID
  name: "Jane Doe",              // Optional — display name
  email: "jane@example.com",     // Optional — email address
  avatarUrl: "https://...",      // Optional — profile picture URL
  customData: {                  // Optional — any metadata
    plan: "pro",
    company: "Acme Inc"
  }
});
PropertyTypeRequiredDescription
userIdstringYesYour application's unique user ID. Used to link widget visitors to your user records.
namestringNoDisplay name shown in conversations.
emailstringNoEmail address for notifications and identification.
avatarUrlstringNoURL to the user's profile picture.
hmacstringNo*HMAC-SHA256 signature for secure identification. Required if your workspace has HMAC verification enabled.
customDataobjectNoArbitrary key-value data attached to the visitor (plan, company, etc.).

Timing

You can call FWDHub.identify() at any time — before or after the widget has loaded. If called before the widget iframe is ready, the data is queued and sent automatically once the widget initializes.

When both name and email are provided (either via identify() or the manual form), the visitor is considered identified and can access Messages and Feedback without the form prompt.

Example: React App

React
import { useEffect } from "react";
import { useUser } from "./auth"; // your auth hook

function App() {
  const user = useUser();

  useEffect(() => {
    if (user && window.FWDHub) {
      FWDHub.identify({
        userId: user.id,
        name: user.name,
        email: user.email,
        avatarUrl: user.avatarUrl,
        customData: {
          plan: user.plan,
          role: user.role,
        },
      });
    }
  }, [user]);

  return <div>...</div>;
}

HMAC Verification

HMAC verification prevents user impersonation. When enabled, the widget will reject identify() calls that don't include a valid HMAC signature. This ensures that only your server can identify users.

Setup

1. Go to your workspace Settings → API & Security in the dashboard.

2. Generate an HMAC secret. Keep this secret server-side only — never expose it in client-side code.

3. On your server, compute the HMAC-SHA256 of the userId using your secret, and pass it to the widget.

Server-Side Signature

Node.js
import crypto from "crypto";

function generateHmac(userId, secret) {
  return crypto
    .createHmac("sha256", secret)
    .update(userId)
    .digest("hex");
}

// In your API endpoint:
const hmac = generateHmac(user.id, process.env.FWD_HUB_HMAC_SECRET);
// Pass this hmac to your frontend

Client-Side Usage

JavaScript
// hmac comes from your server, NOT computed client-side
FWDHub.identify({
  userId: "usr_123",
  name: "Jane Doe",
  email: "jane@example.com",
  hmac: hmacFromServer,
});

When HMAC verification is enabled on your workspace and a visitor calls identify() without a valid hmac, the call will be rejected with an error.

Modules

The widget includes four modules. Each can be enabled or disabled from your workspace settings in the dashboard.

Messages

Real-time conversations between visitors and your team. Supports file attachments and screenshot capture.

Help Center

Searchable knowledge base organized into collections and articles. Full-text search included.

Feedback

Feature requests and bug reports from visitors. Conversations are threaded for follow-up.

Changelog

Product updates categorized as New, Improved, or Fixed. Tracks read state per visitor.