Skip to content
LogoLogo

Fields

Define your fields in code with createField(). Check the input with JSON Logic. Read the values that a user sends through the step context.

Define a field

Define a field with createField() from the @picked/client/plugins/create-experience package. Each field needs a unique identifier, a name, a type, a label, and a count of the values that it takes:

import { createField } from '@picked/client/plugins/create-experience'
 
// A text input that the user must fill in.
export const emailField = createField({
  id: 'email-address',
  name: 'email-address',
  type: 'text',
  label: 'Email Address',
  multiple: false,
  required: true,
  placeholder: 'you@example.com',
})
 
// A dropdown that takes more than one choice, with fixed options.
export const communicationMethods = createField({
  id: 'communication-methods',
  name: 'communication-methods',
  type: 'text',
  label: 'Preferred contact methods',
  multiple: true,
  required: true,
  options: [
    {
      id: 'email',
      label: 'Email',
      value: 'email',
    },
    {
      id: 'phone',
      label: 'Phone',
      value: 'phone',
    },
    {
      id: 'sms',
      label: 'SMS',
      value: 'sms',
    },
  ],
})

Register fields on the client

Register fields when you create the Picked client. Pass a fields object. The key of an entry becomes the field key when the definition does not set one. A definition with its own key keeps it. Pass a function to build a definition once during the client setup:

import { createClient } from 'picked'
 
const client = createClient({
  projectId: 'your-project-id',
  fields: {
    email: {
      id: 'email',
      name: 'email',
      label: 'Email Address',
      type: 'text',
      multiple: false,
      required: true,
    },
    age: () => ({
      id: 'age',
      name: 'age',
      label: 'Age',
      type: 'number',
      multiple: false,
      required: false,
    }),
  },
})

Field types

A field has one of four basic types: text, number, boolean, or object.

// One text input.
const nameField = createField({
  type: 'text',
  multiple: false,
  // ...
})

Give an options array to let the user choose more than one value:

const nameField = createField({
  type: 'text',
  multiple: true,
  options: [
    {
      id: 'option-one',
      label: 'Option One',
      value: 'product-id-one',
    },
    {
      id: 'option-two',
      label: 'Option Two',
      value: 'product-id-two',
    },
    {
      id: 'option-three',
      label: 'Option Three',
      value: 'product-id-three',
    },
  ],
})

Conditions

A field and a field option both work with condition logic:

const conditionalField = createField({
  id: 'conditional-field',
  type: 'text',
  condition: {
    invoke: {
      var: 'responses.has-answered-question',
    },
  },
  options: [
    {
      id: 'conditional-option',
      label: 'Conditional Label',
      condition: {
        invoke: {
          var: 'responses.eligible-for-option',
        },
      },
    },
  ],
})

Field policies

A field captures nothing until you permit it. Use a privacy policy to let Picked track or store the data of a field:

const colourField = createField({
  id: 'favourite-colour',
  name: 'favourite-colour',
  type: 'text',
  label: 'Favourite colour',
  multiple: false,
  required: true,
  policies: {
    trackValue: true, // Send the value to analytics.
    storeValue: true, // Keep the value in browser storage.
  },
})

Privacy policies:

  • trackValue: set it to true to put the value of the field in your analytics events. At false, and when the policy is absent, the events carry the field ID only.
  • storeValue: set it to true to let the SDK put the value in browser storage. At false, and when the policy is absent, the SDK keeps the value out of storage.

Both policies keep the value in the browser by default. A field with no policies object sends no value to your analytics and writes no value to browser storage. Keep the default for sensitive data such as a tax number, a credit card number, or a password. That data stays in the browser:

const sensitiveField = createField({
  id: 'ssn',
  name: 'ssn',
  type: 'text',
  label: 'Social Security Number',
  multiple: false,
  required: true,
})

Neither policy stops the flow from the use of the value inside the page. A field that captures nothing still holds its value there, for step validation and for the conditions after the step. The policies control what leaves the page: your analytics, and browser storage.

Field metadata

Add more text to help the user:

const passwordField = createField({
  id: 'password',
  name: 'password',
  type: 'text',
  label: 'Password',
  multiple: false,
  required: true,
  placeholder: 'Enter a strong password',
  description: 'Your password must be at least 8 characters',
  helpText: 'Use a mix of letters, numbers, and symbols for better security',
})

Metadata fields:

  • placeholder: the hint text that an empty input shows.
  • description: a short explanation below the label.
  • helpText: more guidance, or the requirements, next to the field.

Read a field value

The SDK stores each field response in the experience state. Read a response through the responses object:

// Point at the value from a later field condition.
const sensitiveField = createField({
  condition: {
    '==': [
      {
        var: 'responses.field-name',
      },
      'expected-value',
    ],
  },
})