UserChoice

UserChoice is an embeddable choice-based conjoint survey. Respondents choose between product concepts to reveal which trade-offs they prefer.

@sensefolks/userchoiceWCAG 2.1 AA

What UserChoice Measures

Repeated choices compare product attributes and combinations.

See the conjoint analysis guide for the method.

Refreshing the page restarts the survey with blank answers.

When should I use UserChoice?

Use UserChoice to compare realistic product combinations.

  • Product concepts — Compare realistic combinations of features, price, or service levels
  • Plan design — Learn which bundles people prefer when benefits compete
  • Concept validation — Compare candidate configurations before building
  • Beta and early-access research — Study preference with an engaged audience

Installation

CDN

html
<script type="module" src="https://unpkg.com/@sensefolks/[email protected]/dist/sf-userchoice/sf-userchoice.esm.js"></script>

NPM

bash
npm install @sensefolks/userchoice

How do I embed UserChoice?

HTML

html
<sf-userchoice 
  survey-key="your-survey-uuid" 
  completion-message="Thank you for your feedback!">
</sf-userchoice>

React

jsx
import '@sensefolks/userchoice';

function App() {
  return (
    <sf-userchoice 
      survey-key="your-survey-uuid" 
      completion-message="Thank you!">
    </sf-userchoice>
  );
}

See the embedding tutorial for Next.js, Vue, Nuxt, Angular, Svelte, Astro, and TypeScript setup.

API Reference

Properties

PropertyAttributeTypeDefaultDescription
surveyKeysurvey-keystring—Required. UUID of the survey from your dashboard
completionMessagecompletion-messagestring'Thank you for your response!'Message shown after submission
thankYouMessagethank-you-messagestring—Overrides the saved survey thank-you message
sessionData—Record<string, string | number | boolean>{}Complete typed Session Data matching every field in the schema defined during survey creation

Events

EventDescriptionDetail Properties
sfErrorFired on load, submit, or validation errorssurveyKey, errorType, errorMessage

CSS Custom Properties

Set theme variables on the component:

PropertyDefaultDescription
--sf-primary#005fccPrimary accent color
--sf-primary-hover#0047a3Primary color hover state
--sf-text-primary#111827Primary text color
--sf-text-secondary#6b7280Secondary/muted text color
--sf-error-color#dc2626Error state color
--sf-error-text#991b1bError message text color
--sf-card-bg#ffffffCard/container background
--sf-card-border#d1d5dbCard/container border color
--sf-card-radius8pxCard/container border radius
--sf-button-radius6pxButton border radius
--sf-transition150ms easeDefault transition timing
--sf-selected-bg#e8f0feSelected card background
--sf-selected-border#005fccSelected card border color
--sf-card-shadow0 1px 3px rgba(0,0,0,0.1)Card shadow
--sf-card-shadow-hover0 4px 12px rgba(0,0,0,0.15)Card hover shadow
--sf-none-bg#f9fafb"None" option background
--sf-none-border#9ca3af"None" option border
--sf-error-bg#fef2f2Error state background
--sf-error-border#fecacaError state border
--sf-progress-bg#e5e7ebProgress bar track background
--sf-progress-fill#005fccProgress bar fill color
css
/* Override theme tokens on the component */
sf-userchoice {
  --sf-primary: #7c3aed;
  --sf-primary-hover: #6d28d9;
  --sf-card-radius: 12px;
  --sf-button-radius: 8px;
  --sf-selected-bg: #ede9fe;
  --sf-selected-border: #7c3aed;
  --sf-selected-ring: rgba(0, 95, 204, 0.2);
  --sf-button-text: #ffffff;
  --sf-none-hover-bg: #f3f4f6;
}

CSS Parts

Style exposed elements with ::part():

css
/* Survey container */
sf-userchoice::part(survey-container) { }

/* Steps */
sf-userchoice::part(step) { }
sf-userchoice::part(choice-task-step) { }
sf-userchoice::part(survey-fields-step) { }
sf-userchoice::part(completion-step) { }

/* Headings */
sf-userchoice::part(heading) { }
sf-userchoice::part(task-heading) { }
sf-userchoice::part(survey-fields-heading) { }
sf-userchoice::part(completion-heading) { }

/* Task header & progress */
sf-userchoice::part(task-header) { }
sf-userchoice::part(task-instructions) { }
sf-userchoice::part(progress-indicator) { }
sf-userchoice::part(progress-label) { }
sf-userchoice::part(progress-track) { }
sf-userchoice::part(progress-bar) { }
sf-userchoice::part(progress-fill) { }
sf-userchoice::part(progress-text) { }

/* Concepts */
sf-userchoice::part(concepts-container) { }
sf-userchoice::part(concept) { }
sf-userchoice::part(concept-selected) { }
sf-userchoice::part(concept-unselected) { }
sf-userchoice::part(none-option) { }
sf-userchoice::part(concept-header) { }
sf-userchoice::part(concept-radio) { }
sf-userchoice::part(concept-title) { }
sf-userchoice::part(concept-attributes) { }
sf-userchoice::part(concept-attribute) { }
sf-userchoice::part(attribute-label) { }
sf-userchoice::part(attribute-value) { }

/* Buttons */
sf-userchoice::part(button-container) { }
sf-userchoice::part(button) { }
sf-userchoice::part(back-button) { }
sf-userchoice::part(next-button) { }
sf-userchoice::part(submit-button) { }

/* Survey Fields form */
sf-userchoice::part(form-container) { }
sf-userchoice::part(form-field) { }
sf-userchoice::part(form-label) { }
sf-userchoice::part(form-input) { }
sf-userchoice::part(form-select) { }
sf-userchoice::part(hcaptcha-container) { }
sf-userchoice::part(input) { }
sf-userchoice::part(select) { }
sf-userchoice::part(required-indicator) { }
sf-userchoice::part(radio-group) { }
sf-userchoice::part(radio-option) { }
sf-userchoice::part(radio-input) { }
sf-userchoice::part(radio-label) { }
sf-userchoice::part(checkbox-group) { }
sf-userchoice::part(checkbox-option) { }
sf-userchoice::part(checkbox-input) { }
sf-userchoice::part(checkbox-label) { }

/* Completion */
sf-userchoice::part(completion-summary) { }
sf-userchoice::part(summary-text) { }

/* Messages & errors */
sf-userchoice::part(message) { }
sf-userchoice::part(error-message) { }
sf-userchoice::part(loading-message) { }
sf-userchoice::part(error-container) { }
sf-userchoice::part(troubleshooting-link) { }

/* Branding */
sf-userchoice::part(branding) { }
sf-userchoice::part(branding-link) { }
sf-userchoice::part(branding-logo) { }

/* Accessibility */
sf-userchoice::part(announcements) { }

Completion and validation styles

CSS PartElement
success-messageSubmission confirmation
survey-field-error-messageRespondent-field validation feedback

Use --sf-success-bg, --sf-success-border, and --sf-success-text for the confirmation background, border, and text.

Accessibility

  • Full keyboard navigation (Tab, Arrow keys, Enter/Space)
  • ARIA labels and live regions for screen readers
  • Progress announcements ("Choice Task 2 of 5")
  • Focus indicators and high contrast mode support
  • Respects prefers-reduced-motion

Browser Support

BrowserVersion
Chrome88+
Firefox85+
Safari14+
Edge88+
IE11Not supported