npm package: @getforty/widget
Description: Embeddable feedback widget and event tracking SDK for GetForty
Author: GetForty
Latest version: 1.1.5

# @getforty/widget

Embeddable feedback widget and event tracking SDK for GetForty.

## Installation

```bash
npm install @getforty/widget
```

Or include via CDN:

```html
<script src="https://unpkg.com/@getforty/widget@latest/dist/index.global.js"></script>
```

## Quick Start

### ES Module

```typescript
import { GetForty } from "@getforty/widget";

const widget = await GetForty.init({
  trackingId: "gf_xxxxxxxxxxxx", // Your workspace tracking ID
});

// Track events
widget.track("page_view", { page: "/pricing" });

// Identify users
widget.identify("user_123", { email: "user@example.com", plan: "pro" });

// Show feedback form
widget.showForm("my-feedback-form");
```

### Script Tag

```html
<script src="https://unpkg.com/@getforty/widget@latest/dist/index.global.js"></script>
<script>
  GetFortyWidget.GetForty.init({
    trackingId: "gf_xxxxxxxxxxxx",
  }).then(function (widget) {
    widget.track("page_view");
  });
</script>
```

## Configuration

```typescript
const widget = await GetForty.init({
  // Required
  trackingId: "gf_xxxxxxxxxxxx",

  // Optional - Form display
  mode: "modal", // 'modal' or 'inline'
  container: "#widget-container", // Container for inline mode

  // Optional - Appearance
  showBranding: true, // Show "Powered by GetForty"
  theme: {
    primaryColor: "#6366f1",
    backgroundColor: "#ffffff",
    textColor: "#1f2937",
    fontFamily: "Inter, sans-serif",
    borderRadius: "8px",
  },

  // Optional - Localization
  locale: "en", // 'en' or 'pt-BR'
  translations: {
    // Custom strings
    submit: "Send Feedback",
    success: "Thanks for your feedback!",
  },

  // Optional - Tracking
  autoTrackPageViews: true, // Auto-track page views

  // Optional - Development
  debug: false, // Enable debug logging
  apiBaseUrl: "https://getforty.club", // API endpoint
});
```

## API

### `GetForty.init(config)`

Initialize the widget with your configuration. Returns a Promise that resolves to a widget instance.

### `widget.track(eventName, properties?)`

Track a custom event.

```typescript
widget.track("purchase", {
  product: "Pro Plan",
  amount: 99.99,
  currency: "USD",
});
```

### `widget.identify(userId, traits?)`

Identify the current user. Call this when a user logs in.

```typescript
widget.identify("user_123", {
  email: "user@example.com",
  name: "John Doe",
  plan: "pro",
});
```

### `widget.showForm(formId)`

Display a feedback form programmatically.

```typescript
widget.showForm("clxxxxxxxxxxxxxxxxx");
```

### `widget.hideForm()`

Hide the currently displayed form.

### `widget.flush()`

Immediately send any queued events.

```typescript
await widget.flush();
```

### `widget.getSessionId()`

Get the current session ID.

```typescript
const sessionId = widget.getSessionId();
```

## Events

Subscribe to widget lifecycle events:

```typescript
// Form loading
widget.on("load:start", ({ formId }) => {
  console.log("Loading form:", formId);
});

widget.on("load:success", ({ form }) => {
  console.log("Form loaded:", form.title);
});

widget.on("load:error", ({ error, retryable }) => {
  console.error("Failed to load form:", error);
});

// Form submission
widget.on("submit:start", ({ answers }) => {
  console.log("Submitting...", answers);
});

widget.on("submit:success", ({ responseId }) => {
  console.log("Submitted! Response ID:", responseId);
});

widget.on("submit:error", ({ error, retryable }) => {
  console.error("Submission failed:", error);
});

// Modal/form visibility
widget.on("open", ({ mode }) => {
  console.log("Form opened in", mode, "mode");
});

widget.on("close", ({ reason }) => {
  console.log("Form closed:", reason); // 'user', 'submitted', or 'programmatic'
});

// Generic errors
widget.on("error", ({ type, message }) => {
  console.error(`${type} error:`, message);
});
```

Unsubscribe from events:

```typescript
const handleSuccess = ({ responseId }) => {
  console.log("Submitted:", responseId);
};

widget.on("submit:success", handleSuccess);
widget.off("submit:success", handleSuccess);
```

## Localization

Built-in support for English and Portuguese (Brazil):

```typescript
const widget = await GetForty.init({
  trackingId: "gf_xxxxxxxxxxxx",
  locale: "pt-BR", // Use Portuguese
});
```

Custom translations:

```typescript
const widget = await GetForty.init({
  trackingId: "gf_xxxxxxxxxxxx",
  locale: "en",
  translations: {
    submit: "Send",
    success: "Thanks!",
    required: "Please fill this in",
  },
});
```

## Theming

Customize the widget appearance:

```typescript
const widget = await GetForty.init({
  trackingId: "gf_xxxxxxxxxxxx",
  theme: {
    primaryColor: "#3b82f6", // Buttons, active states
    backgroundColor: "#f8fafc", // Widget background
    textColor: "#0f172a", // Text color
    fontFamily: "system-ui", // Font family
    borderRadius: "12px", // Border radius
  },
});
```

## TypeScript Support

Full TypeScript support with exported types:

```typescript
import type {
  WidgetConfig,
  WidgetTheme,
  WidgetEventMap,
  TrackEventOptions,
  FormConfig,
  Answer,
} from "@getforty/widget";
```

## Browser Support

- Chrome (last 2 versions)
- Firefox (last 2 versions)
- Safari (last 2 versions)
- Edge (last 2 versions)

## Bundle Size

- ~25KB gzipped (includes Preact runtime)
- Shadow DOM for style isolation
- No external dependencies at runtime

## License

MIT