Skip to main content
Technology & EngineeringForm Survey Services246 lines

Formbricks

Integrate Formbricks open-source surveys for in-app, website, and link-based feedback collection. Covers the JavaScript SDK for targeted in-app surveys, REST API for response management, and self-hosting configuration with TypeScript.

Quick Summary23 lines
You are an expert at integrating Formbricks, the open-source survey platform, into web applications. You configure in-app surveys triggered by user actions, collect website feedback via no-code widgets, and manage response data through the REST API.

## Key Points

- **Showing surveys without event triggers** — random pop-ups annoy users and tank completion rates.
- **Forgetting to call `formbricks.logout()`** on sign-out — the next user inherits the previous user's identity and attributes.
- **Not setting user attributes** — you lose the ability to target surveys by plan, role, or tenure.
- **Running the JS SDK in SSR** — Formbricks requires `window`. Initialize only on the client side inside `useEffect`.
- Collecting in-app feedback triggered by specific user actions (post-onboarding, feature usage, churn signals).
- Running NPS or CSAT surveys inside your product without redirecting users externally.
- Self-hosting a survey platform for GDPR compliance and full data ownership.
- A/B testing onboarding flows by surveying different user segments.
- Building product analytics feedback loops where survey data feeds into your data warehouse.

## Quick Example

```bash
NEXT_PUBLIC_FORMBRICKS_ENV_ID=clu...
NEXT_PUBLIC_FORMBRICKS_API_HOST=https://app.formbricks.com
FORMBRICKS_API_KEY=fb_...
```
skilldb get form-survey-services-skills/formbricksFull skill: 246 lines
Paste into your CLAUDE.md or agent config

Formbricks Skill

You are an expert at integrating Formbricks, the open-source survey platform, into web applications. You configure in-app surveys triggered by user actions, collect website feedback via no-code widgets, and manage response data through the REST API.

Core Philosophy

Event-Triggered Surveys

Formbricks excels at showing the right survey at the right moment. Trigger surveys based on user actions (e.g., completed onboarding, clicked upgrade, visited pricing page) rather than showing them randomly. Use the track() method to fire custom events and tie them to survey display rules.

Privacy-First Data Collection

Formbricks is self-hostable and GDPR-friendly by design. When self-hosting, all data stays on your infrastructure. Use the userId parameter to associate responses with known users without leaking PII to third parties. For anonymous surveys, omit userId entirely.

Progressive Survey Delivery

Avoid survey fatigue by using Formbricks' built-in targeting: show surveys only to specific user segments, limit display frequency, and stop showing a survey once a user has responded. Configure these rules in the dashboard or via API attributes.

Setup

Install the JavaScript SDK for in-app surveys:

// npm install @formbricks/js

import formbricks from "@formbricks/js";

formbricks.init({
  environmentId: process.env.NEXT_PUBLIC_FORMBRICKS_ENV_ID!,
  apiHost: process.env.NEXT_PUBLIC_FORMBRICKS_API_HOST!, // https://app.formbricks.com or self-hosted URL
  userId: currentUser?.id,          // optional: for identified users
  attributes: {                      // optional: for targeting
    plan: currentUser?.plan,
    role: currentUser?.role,
  },
});

For the REST API:

const FB_API_HOST = process.env.FORMBRICKS_API_HOST;
const FB_API_KEY = process.env.FORMBRICKS_API_KEY;

async function fbFetch<T>(path: string, init?: RequestInit): Promise<T> {
  const res = await fetch(`${FB_API_HOST}/api/v1${path}`, {
    ...init,
    headers: {
      "x-api-key": FB_API_KEY!,
      "Content-Type": "application/json",
      ...init?.headers,
    },
  });
  if (!res.ok) throw new Error(`Formbricks ${res.status}: ${await res.text()}`);
  const json = await res.json();
  return json.data as T;
}

Environment variables:

NEXT_PUBLIC_FORMBRICKS_ENV_ID=clu...
NEXT_PUBLIC_FORMBRICKS_API_HOST=https://app.formbricks.com
FORMBRICKS_API_KEY=fb_...

Key Patterns

Track Custom Events for Survey Triggers

Do this — fire events that trigger contextual surveys:

// Track when a user completes onboarding
async function completeOnboarding(userId: string) {
  await saveOnboardingComplete(userId);
  formbricks.track("onboarding_completed");
}

// Track when a user hits a feature wall
function handleFeatureGate(feature: string) {
  formbricks.track("feature_gate_hit", { feature });
  showUpgradeModal();
}

// Track page-specific events
function ProductPage() {
  useEffect(() => {
    formbricks.track("viewed_pricing_page");
  }, []);
  return <PricingContent />;
}

Not this — showing surveys on every page load without any targeting or event context.

Set User Attributes for Targeting

Do this — update attributes so surveys reach the right segments:

// Set attributes when user context changes
async function onPlanUpgrade(newPlan: string) {
  formbricks.setAttribute("plan", newPlan);
  formbricks.setAttribute("upgraded_at", new Date().toISOString());
}

// Set attributes on login
function onUserLogin(user: { id: string; plan: string; role: string; createdAt: string }) {
  formbricks.setUserId(user.id);
  formbricks.setAttribute("plan", user.plan);
  formbricks.setAttribute("role", user.role);
  formbricks.setAttribute("signup_date", user.createdAt);
}

// Reset on logout
function onLogout() {
  formbricks.logout();
}

Not this — showing every survey to every user without segmentation, causing survey fatigue.

Fetch and Analyze Responses via API

Do this — retrieve responses with typed interfaces:

interface FormbricksResponse {
  id: string;
  surveyId: string;
  finished: boolean;
  createdAt: string;
  updatedAt: string;
  person: { id: string; attributes: Record<string, string> } | null;
  data: Record<string, string | number | string[]>;
}

async function getSurveyResponses(surveyId: string): Promise<FormbricksResponse[]> {
  return fbFetch<FormbricksResponse[]>(`/management/responses?surveyId=${surveyId}`);
}

// Calculate NPS from responses
function calculateNPS(responses: FormbricksResponse[], questionId: string): number {
  const scores = responses
    .map((r) => Number(r.data[questionId]))
    .filter((n) => !isNaN(n));
  const promoters = scores.filter((s) => s >= 9).length;
  const detractors = scores.filter((s) => s <= 6).length;
  return Math.round(((promoters - detractors) / scores.length) * 100);
}

Not this — exporting CSV manually from the dashboard for every analysis run.

Common Patterns

Create a Survey via API

interface CreateSurveyPayload {
  name: string;
  type: "app" | "website" | "link";
  questions: Array<{
    type: "openText" | "multipleChoiceSingle" | "multipleChoiceMulti" | "rating" | "nps" | "cta";
    headline: string;
    required: boolean;
    choices?: Array<{ label: string }>;
    scale?: "number" | "star" | "smiley";
    range?: 5 | 10;
  }>;
}

const survey = await fbFetch<{ id: string }>("/management/surveys", {
  method: "POST",
  body: JSON.stringify({
    name: "Feature Feedback",
    type: "app",
    questions: [
      { type: "rating", headline: "How useful is this feature?", required: true, scale: "star", range: 5 },
      { type: "openText", headline: "Any suggestions?", required: false },
    ],
  } satisfies CreateSurveyPayload),
});

React Integration with Next.js App Router

// app/providers.tsx
"use client";
import { useEffect } from "react";
import formbricks from "@formbricks/js";

export function FormbricksProvider({ userId, attributes }: { userId?: string; attributes?: Record<string, string> }) {
  useEffect(() => {
    formbricks.init({
      environmentId: process.env.NEXT_PUBLIC_FORMBRICKS_ENV_ID!,
      apiHost: process.env.NEXT_PUBLIC_FORMBRICKS_API_HOST!,
      ...(userId ? { userId } : {}),
      ...(attributes ? { attributes } : {}),
    });
  }, [userId]);

  return null;
}

Webhook Integration

// Formbricks sends webhooks for response events
interface FormbricksWebhookPayload {
  event: "responseCreated" | "responseUpdated" | "responseFinished";
  data: FormbricksResponse;
}

app.post("/webhooks/formbricks", async (req, res) => {
  const payload = req.body as FormbricksWebhookPayload;
  if (payload.event === "responseFinished") {
    await syncToAnalytics(payload.data);
  }
  res.status(200).send("OK");
});

Anti-Patterns

  • Showing surveys without event triggers — random pop-ups annoy users and tank completion rates.
  • Forgetting to call formbricks.logout() on sign-out — the next user inherits the previous user's identity and attributes.
  • Not setting user attributes — you lose the ability to target surveys by plan, role, or tenure.
  • Running the JS SDK in SSR — Formbricks requires window. Initialize only on the client side inside useEffect.

When to Use

  • Collecting in-app feedback triggered by specific user actions (post-onboarding, feature usage, churn signals).
  • Running NPS or CSAT surveys inside your product without redirecting users externally.
  • Self-hosting a survey platform for GDPR compliance and full data ownership.
  • A/B testing onboarding flows by surveying different user segments.
  • Building product analytics feedback loops where survey data feeds into your data warehouse.

Install this skill directly: skilldb add form-survey-services-skills

Get CLI access →

Related Skills

Formik

Build React forms with Formik using useFormik hook, Field components, and schema validation via Yup or Zod. Covers form state management, custom field components, async validation, and TypeScript integration patterns.

Form Survey Services279L

Jotform

Integrate JotForm's REST API to create forms, retrieve submissions, process payments, manage widgets, and configure webhooks. Covers form CRUD, submission handling, payment gateway integration, and TypeScript client patterns.

Form Survey Services234L

React Hook Form

Build performant React forms with React Hook Form using register, validation, controllers, and form state management. Covers uncontrolled inputs, schema validation with Zod, controlled components, and TypeScript integration.

Form Survey Services249L

Surveymonkey

Integrate SurveyMonkey's REST API to create surveys, collect responses via collectors, process results, and configure webhooks. Covers survey design, collector management, response analysis, and TypeScript client patterns.

Form Survey Services258L

Tally

Integrate Tally forms via its API and embed SDK to handle submissions, configure webhooks, apply conditional logic, and embed forms seamlessly. Covers REST endpoints, webhook payloads, and front-end embedding with TypeScript.

Form Survey Services240L

Typeform

Integrate Typeform APIs to create forms, retrieve responses, configure webhooks, set up logic jumps, and embed forms in web applications. Covers the Create API, Responses API, and front-end embed SDK with TypeScript patterns.

Form Survey Services246L