---
title: Quickstart
description: Install the Feeblo widget SDK and open your first feedback widget in a few minutes.
---

Four steps stand between you and a working widget: install, mount, trigger, identify.
None of them takes more than a minute.

1. **Install**

    **Vanilla JS**

    ```bash
    npm install @feeblo/sdk
    ```

    **React**

    ```bash
    npm install @feeblo/sdk @feeblo/sdk-react
    ```

    Both packages ship ESM and UMD builds with no runtime dependencies. The React package
    re-exports everything from the core SDK, so you only need both when you want the
    components and hooks.

2. **Mount the widget**

    **Vanilla JS**

    Call `init` with your Feeblo organization ID:

    ```ts
    import { Feeblo } from "@feeblo/sdk";

    const widget = Feeblo.init("org_123");
    ```

    `init` returns a chainable handle, so you can keep configuring it:

    ```ts
    const widget = Feeblo.init("org_123").setBoard("roadmap");
    ```

    **React**

    Wrap your app in `FeebloProvider`. It mounts the widget and hands control to its hooks:

    ```tsx
    import { FeebloProvider } from "@feeblo/sdk-react";

    <FeebloProvider organizationId="org_123">
      <App />
    </FeebloProvider>
    ```

    Config props like `organizationId`, `mode`, `theme`, and `placement` recreate the
    underlying widget when they change, so treat them as configuration rather than state.

3. **Add a trigger**

    Give any element the `data-feeblo-feedback` attribute. The SDK scans for these elements
    and opens the widget when a user clicks one:

    ```html
    <button data-feeblo-feedback>Give feedback</button>
    ```

    This works the same in React, since scanning happens at the DOM level. For programmatic
    control:

    **Vanilla JS**

    ```ts
    widget.open();
    ```

    **React**

    ```tsx
    import { useFeeblo } from "@feeblo/sdk-react";

    function FeedbackButton() {
      const feeblo = useFeeblo();

      return <button onClick={() => feeblo.open()}>Give feedback</button>;
    }
    ```

    `useFeeblo` also exposes `close`, `setBoard`, `openModule`, `metadata`, `identify`, plus
    reactive `isOpen` and `isReady` values. It throws outside a provider.

4. **Identify the user**

    Attach a user to each piece of feedback:

    **Vanilla JS**

    ```ts
    Feeblo.identify({
      id: "u_1",
      email: "ada@example.com",
      name: "Ada Lovelace",
    });
    ```

    **React**

    Pass the identity as the `user` prop. Changes call `identify` on the live widget without
    recreating it:

    ```tsx
    <FeebloProvider organizationId="org_123" user={currentUser}>
      <App />
    </FeebloProvider>
    ```

    Only `id` is required. Anonymous submissions work fine; add a signed token when you want
    posts tied to a verified identity. [Identifying users](/developers/identity) covers the
    identity object and custom fields, [Widget SSO](/developers/widget-sso) covers signing.

## Widget modes

Feedback collection is the default mode. Two others exist:

1. **Updates**

    A card-based product updates panel:

    ```ts
    const updates = Feeblo.init("org_123", { mode: "updates" });
    ```

2. **Hub**

    Several modules behind one launcher. Pass any subset, in order. The array position
    decides which module shows first:

    ```ts
    const hub = Feeblo.init("org_123", {
      mode: "hub",
      modules: ["updates", "feedback"],
    });

    hub.openModule("feedback");
    ```

    In React, set `mode` and `modules` on `FeebloProvider` instead.

[Configuration](/developers/configuration) documents every option, including `placement`
for the built-in launcher.

## Next steps

<CardGroup cols={2}>
  <Card title="Configuration" href="/developers/configuration">
    Modes, placement, debug logging, and every init option and provider prop.
  </Card>
  <Card title="Triggers and events" href="/developers/triggers-and-events">
    Trigger attributes, programmatic control, and widget events (`useFeebloEvent` included).
  </Card>
</CardGroup>
