Poll Vote

Real-time polling component with single and multiple-choice voting, percentage results, three responsive templates, and the standard sign-in/lead/CTA configuration.

Import

import { PollVote } from "fansunited-frontend-components";
import { PollVoteProps, WidgetTemplate } from "fansunited-frontend-core";

Required props

PropTypeDescription
entityIdstringPoll identifier.
sdkFansUnitedSDKModelSDK instance.
templateWidgetTemplateSTANDARD, SPLIT, or OVERLAY.
languageLanguageTypeDisplay language.

Optional props

PropTypeDescription
themeOptionsCustomThemeOptionsSee Theming.
leadsLeadsOptionsSee Lead Collection.
consentsConsentsConfigProfile consent checkboxes. See Consents and the section below.
imagePosition"left" | "right"STANDARD template only.
defaultImagePlaceholderUrlstringFallback image URL.
userIsLoggedInbooleanHost auth state for sign-in-gated polls.
signInCTASignInCTADetailsSee Sign-in CTA. On a REGISTERED poll the options render locked and this CTA replaces the vote button; it does not use gate.
additionalCTAAdditionalCTADetailsSee Additional CTA.
rulesDisplayRulesDisplaySee Rules Display.
callbacksPollVoteCallbacksonFinish — see Callbacks.
aggregateTranslatedVotesbooleanResults show votes summed across every translation of the poll. Default false. See the section below.

Voting behavior

  • Single or multiple choice is determined by the poll configuration on the backend.
  • Vote attempt limits are enforced server-side. The component disables the form once a user has reached the limit and shows the results view instead.
  • Results are the poll's vote counts as loaded, with the user's vote added on submit.

Aggregated results across translations

For multilingual polls (one poll per language, linked in the poll's related entities as translatedTo / translatedFrom), set aggregateTranslatedVotes to show the combined vote count of all translations on the results screen.

<PollVote {...otherProps} aggregateTranslatedVotes />
  • Applies to every results screen: right after a vote, and when a returning user has reached the vote limit.
  • Translations are found from either side. From a translation, the widget follows the original's related polls to its sibling translations, so every language shows the same totals.
  • Options are matched by position, so every translation needs the same options in the same order. A translation with a different number of options is left out of the totals.
  • If the translations can't be loaded, the poll's own counts are shown.

Consents

Collect profile consents alongside the vote. The shape is the shared ConsentDef — see Consents for the full field reference and the URL tokens.

import { ConsentsConfig } from "fansunited-frontend-core";

const consents: ConsentsConfig = {
  items: [
    {
      consentId: "terms",
      body: "I accept the {{privacyPolicyUrl}} and the {{termsAndConditionsUrl}}",
      required: true,
    },
    { consentId: "marketing", body: "Send me news and offers by email", position: "after" },
  ],
};

<PollVote {...otherProps} consents={consents} />
Poll configurationConsent surface
authRequirement: "LEAD" + leads.position setThe lead form, at the lead's position — all consents, each position ignored
No lead form"before" → a gate screen shown before the poll; "after" → its own step between the vote and its submission

Without ctaLabel, the gate screen uses the poll's Start label and the consent step its Vote label — the step is what submits the vote.

Examples

Basic

<PollVote
  entityId="poll-123"
  sdk={sdk}
  template={WidgetTemplate.STANDARD}
  language="en"
/>

Customized

<PollVote
  entityId="poll-123"
  sdk={sdk}
  template={WidgetTemplate.OVERLAY}
  language="en"
  userIsLoggedIn={false}
  signInCTA={{ defaultLabel: "Sign in to vote", onClick: openSignIn }}
  leads={{
    position: "after",
    fields: ["fullName", "email"],
    campaignId: "poll-campaign",
    campaignName: "User Survey 2024",
    syncWithProfile: true,
  }}
  themeOptions={{ mode: "dark" }}
/>

Did this page help you?