Contact Forms

Build and manage contact/quote request forms with configurable fields.

List Form Fields

const fields = await client.getFormFields('proj_123');
fields.forEach(f => {
  console.log(f.type, f.label, f.required ? '(required)' : '');
});

Create Form Field

const field = await client.createFormField('proj_123', {
  type: 'dropdown',
  label: 'Budget Range',
  required: true,
  width: 'half',
  options: [
    { id: '1', label: 'Under $1k', value: 'under-1k' },
    { id: '2', label: '$1k - $5k', value: '1k-5k' },
    { id: '3', label: '$5k - $10k', value: '5k-10k' },
    { id: '4', label: 'Over $10k', value: 'over-10k' }
  ],
  allowOther: true
});

Checkout and save buttons

// FormFieldType covers 12 field types. Two of them are buttons that REPLACE
// the Request-a-Quote call to action rather than sitting beside it.

// Add to Cart — checks out through a connected store.
await client.createFormField('proj_123', {
  type: 'add-to-cart',
  label: 'Add to Cart',
  addToCartLabel: 'Add to Cart',
  addToCartStyle: 'filled',
  // ALWAYS set this explicitly. A missing value is read as 'woocommerce' by
  // every consumer, so on a Shopify-only workspace the button's checkout URL
  // never resolves — and since it replaced the quote button, the form is left
  // with no working call to action at all.
  addToCartProvider: 'shopify',   // 'woocommerce' | 'shopify'
});

// Save Configuration — Enterprise only, and additionally requires
// projectSettings.enableSaveConfiguration. Keep required: false: the field
// renders no input, so a required flag makes the form unsubmittable against
// an error attached to an element the shopper never sees.
await client.createFormField('proj_123', {
  type: 'save-configuration',
  label: 'Save Configuration',
  required: false,
  saveConfigLabel: 'Save my configuration',
  saveConfigStyle: 'outline',
});

Continue reading