npm package: @restorehub/widget
Description: Embeddable Discord verification widget for Restore Hub. Add Discord SSO and member verification to any website with one line of code.
Author: Restore Hub
Latest version: 1.0.4

# @restorehub/widget

Add a "Login with Discord" button to any website. Users verify through Discord OAuth, get a role in your server, and your site gets their identity — all in one click.

## Install

```bash
npm install @restorehub/widget
```

## Which approach should I use?

### I want a pre-built Discord button (React)

Renders a styled button with the Discord logo. Drop it in and it works.

```jsx
import { RestoreHubButton } from "@restorehub/widget/react";

function App() {
  return (
    <RestoreHubButton
      serverSlug="your-server-slug"
      onSuccess={(result) => {
        console.log("Verified!", result.user.username);
        console.log("Token:", result.token);
      }}
      onError={(err) => console.error(err)}
    />
  );
}
```

**Props:**

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `serverSlug` | string | required | Your server's slug from the dashboard |
| `onSuccess` | function | — | Called with `{ token, user }` after verification |
| `onError` | function | — | Called if verification fails or popup is closed |
| `buttonText` | string | "Login with Discord" | Button label |
| `buttonColor` | string | "#5865F2" | Button background color |
| `buttonTextColor` | string | "#FFFFFF" | Button text color |

### I want to use my own button (any framework)

`verify()` doesn't render anything — it just opens the popup. Attach it to whatever button you want.

```html
<button id="discord-btn">Sign in with Discord</button>

<script type="module">
  import { verify } from "@restorehub/widget";

  document.getElementById("discord-btn").onclick = async () => {
    try {
      const result = await verify("your-server-slug");
      console.log("Verified!", result.user.username);
      console.log("Token:", result.token);
    } catch (err) {
      console.error("Failed:", err.message);
    }
  };
</script>
```

## What happens when the user clicks

1. A popup opens showing the Discord OAuth consent screen
2. User clicks "Authorize" — Discord confirms their identity
3. Restore Hub verifies them, assigns their role, signs a JWT
4. Popup closes automatically
5. Your `onSuccess` callback fires with the user's info and a signed token

## Verifying the token on your backend

The `result.token` is a signed JWT. Don't trust it client-side — verify it on your server:

```bash
curl -X POST https://api.restorehub.net/api/widget/token/verify \
  -H "Content-Type: application/json" \
  -d '{"token": "eyJhbG..."}'
```

```json
{
  "valid": true,
  "userId": "123456789",
  "username": "johndoe",
  "serverId": "abc-123",
  "guildId": "987654321"
}
```

## Error handling

```js
try {
  const result = await verify("my-server");
} catch (err) {
  // err.code is one of:
  // "POPUP_BLOCKED"       — browser blocked the popup
  // "POPUP_CLOSED"        — user closed without completing
  // "VERIFICATION_FAILED" — blocked by security checks
  // "NETWORK_ERROR"       — connection issue
  // "TIMEOUT"             — took longer than 10 minutes
}
```

## Setup (one time)

1. Create an account at [restorehub.net](https://restorehub.net)
2. Add your Discord bot and server
3. Go to **Server Settings → Widget** and enable it
4. Add your website's domain to **Allowed Origins**
5. Use the server's **slug** (from General settings) in your code

## Links

- [Dashboard](https://restorehub.net/dashboard)
- [Docs](https://restorehub.net/docs/widget)
- [Discord](https://discord.gg/kHhBFzxyms)

## License

MIT