Skip to main content

DocsRespondents

Respondents

Because the form renders inside your product, it can behave like your product: recognize the signed-in user, remember progress, and let people return to edit. Needs @usefillo/* 0.7.0 or newer.

View as Markdownllms.txt for agents

Identify who's filling the form

Pass your signed-in user with the respondent prop. Every response that person submits arrives with their id, email, and name attached — in the responses grid, the response drawer, webhooks, Zapier, and CSV export — and a person view filters everything one respondent ever submitted. respondent.id is your own user id; it’s the identity key within your workspace.

identify your user
"use client";

import { FilloForm } from "@usefillo/react";

// Pass your signed-in user. Every response this person submits now arrives
// with their id, email, and name attached — in the responses grid, webhooks,
// Zapier, and CSV export. Safe to pass late (after your session loads).
export function NpsForm({ user }: { user: { id: string; email: string; name: string } }) {
  return (
    <FilloForm
      formId="nps"
      respondent={{ id: user.id, email: user.email, name: user.name }}
    />
  );
}

The same option works on <FilloProvider>, the framework-free renderForm() (with setRespondent() to bind late), and createFormController().

DOM / headless
import { createFormController } from "@usefillo/core";

// The respondent option works everywhere the engine does — the DOM renderer
// (renderForm), the headless controller, and <FilloProvider> in React.
const form = renderForm("#form", {
  formId: "nps",
  respondent: { id: user.id, email: user.email, name: user.name },
});
// Late-bind it once your session resolves:
form.setRespondent({ id: user.id, email: user.email, name: user.name });

By default identity is an unverified claim from the page — fine for enriching your own dashboards. Turn on verification when you rely on it.

Verify identity

In Fillo → Settings → Developers → Identity verification, generate a workspace secret. From then on, Fillo records a respondent only when the submission carries a valid HMAC-SHA256(userId, secret) computed on yourserver — so a script on the embedding page can’t claim to be another user. Verified responses are marked as such in the grid, drawer, and payloads.

compute the hash server-side
// On YOUR server — never in the browser (the secret must not ship to clients).
// Copy the secret from Fillo → Settings → Developers → Identity verification.
import { createHmac } from "node:crypto";

export function respondentHash(userId: string): string {
  return createHmac("sha256", process.env.FILLO_IDENTITY_SECRET!)
    .update(userId)
    .digest("hex");
}

Then pass it with the identity:

pass the hash
// Pass the server-computed hash alongside the identity. Once your workspace
// has a secret, Fillo records identity ONLY when the hash validates, so a
// script on the page can't impersonate or enrich another user's profile.
<FilloForm
  formId="nps"
  respondent={{ id: user.id, email: user.email, hash }}
/>

Never compute the hash in the browser — that would expose the secret. If verification is on and no valid hash arrives, the response is still recorded, just anonymous.

Save and resume

Turn on Save and resumein a form’s Respondents settings. The SDK then autosaves in-progress answers as the visitor types and restores them when they return — after a reload, a closed tab, or (for a verified respondent) on another device. A “picked up where you left off” notice appears with a Start over action. Unsubmitted drafts are deleted on submit, on start over, or automatically 7 days after the last change. It’s a per-form setting the renderer honors — no code changes. Headless UIs can read resumedDraft and call resetDraft() / flushDraft().

One response per person

Two per-form settings, both keyed on the identified respondent:

  • Reject repeats (submissionLimit: "once_per_person") — one response per person; a repeat submit returns the standing response. Anonymous submits are rejected, so the form must be embedded with identify().
  • Update their response (responseMode: "upsert") — the same person edits their response in place instead of creating duplicates. It re-anchors to the current form version, emits a response.updated webhook event, and — for a verified respondent — prefills their previous answers for editing. This turns a one-shot form into a living record: a profile, a preference center, a recurring check-in.

Both are unenforceable without identity, so turn on verification before you rely on them for anything that matters.

Erase a person (GDPR)

From the person view (filter the responses grid to one respondent), Forget person removes their profile, drafts, and identity across the workspace while leaving the answers anonymous; Delete person + responses also deletes their responses and the uploaded files in your connected storage. Both act workspace-wide, because identity is workspace-level.

Was this page useful?

Was this page helpful?
Powered by Fillo