Typeform

Article author
Memberstack Team
  • Updated

You can use the new Memberstack 2.0 front-end API and the following code to inject Typeform embedded widgets w/ hidden fields on your page.

This article applies to static / multi-page sites like Webflow.  See here if you’re using a single-page app framework (like React or Vue).

The following code has been adapted to fit the new approach for embedding Typeform widgets.

ℹ️ Memberstack's getCurrentMember() method runs AFTER the page loads, so the member data isn’t available right away. This means we can’t statically embed a Typeform widget w/ hidden member fields (because the member data will be undefined at first.)

To solve this, we must use JavaScript to dynamically create a form widget when member data is ready and then inject it on the page.

Create the Typeform Widget

Place at the end of the body section or in a custom code embed on whatever page you want the form to appear

<script>
const TYPEFORM_ID = "your app id here";

// the config below matches typeform hidden field IDs to corresponding memberstack field IDs
// add an  object for every field you want to pass to typeform
const TF_CONFIG_MAP = [
  {
    typeform_field_id: "first_name",
    memberstack_field_id: "customFields.first-name",
  },
  {
    typeform_field_id: "phone",
    memberstack_field_id: "customFields.phone",
  }
]

// don't add again if you already have this in your code from other integration snippets
const memberstack = window.$memberstackDom 

// YOU DONT NEED TO MODIFY ANYTHING BELOW THIS LINE

function generateHiddenFields({ config, member, useEmail, useId }){
  let str
  let fields = config;
  if (!fields) {
    str = []
    return
  } else {
    str = fields.map((key) => {
    let { memberstack_field_id, typeform_field_id } = key;
    let ms_field_value = memberstack_field_id.split(".").reduce((acc, val) => {
      return acc[val];
    }, member);
      return `${typeform_field_id}=${ms_field_value}`;
    })
  }
  str.push(`memberstack_id=${member.id}`)
  str.push(`email=${member.auth.email}`)
  return str.join(', ')
}

const GENERATED_TYPEFORM_STRING = generateHiddenFields({
  config: configMap,
  member
})

function injectTypeform(member) {
  // dynamically creates a new div to use for the Typeform widget
  let tfEl = document.createElement("div");

  // use the id of an EXISTING page element that you want to use as a form container.
  // We are using tf-wrapper as an example. 
  // Make sure an element with this id exists in Webflow!
  let anchor = document.getElementById('tf-wrapper')
  
	// gives the dynamically created Typeform widget an id for reference
  tfEl.id = 'tf-form';

  // data attributes that Typeform expects on the newly created div
	// you probably don't need to modify any of these
  tfEl.setAttribute('data-tf-widget', TYPEFORM_ID);
  tfEl.setAttribute('data-tf-inline-on-mobile', true);
  tfEl.setAttribute('data-tf-hide-headers', true);
  tfEl.setAttribute('data-tf-medium', 'snippet');

  // pass in CSVs of key value pairs for hidden fields
  tfEl.setAttribute('data-tf-hidden', GENERATED_TYPEFORM_STRING);

  // append the newly created embed div onto the container element we identified earlier
  anchor.appendChild(tfEl)

  // create a dynamic script tag to inject Typeform's library on to the page
  var typeformScript = document.createElement('script');
  typeformScript.setAttribute('src','//embed.typeform.com/next/embed.js');

  // inject the Typeform library into the head section of the page
  document.head.appendChild(typeformScript);
}

memberstack.getCurrentMember()
  .then(({ data: member }) => {
		// other 3rd party integration functions can go here
		// ie: initIntercom(member)

		// only inject form if member object is not null
   if(member) { injectTypeform(member) }
})
</script>

Map Input Fields

You can pass as many key value sets of Typeform & Memberstack fields that you want inside of the TF_CONFIG_MAP array.

This configuration array will later be passed to a special Memberstack API method that returns a properly formatted string (of dynamic member data) that Typeform expects on the form widget’s data attributes.

The config array is just a set of objects that describe the field IDs for Typeform and Memberstack respectively.

// the config below matches typeform hidden field IDs -
// to corrosponding memberstack field IDs
// add an  object for every field you want to pass to typeform
const TF_CONFIG_MAP = [
  {
    typeform_field_id: "first_name",
    memberstack_field_id: "customFields.first-name",
  },
  {
    typeform_field_id: "phone",
    memberstack_field_id: "customFields.phone",
  }
]

⚠️ Make sure you’re spelling Typeform field IDs AND Memberstack custom fields exactly as they say to be referenced. For more info on Typeform attributes, see here.

For each object, you pass in the array, replace the <field-id> placeholder with the corresponding field ID for each service.

{ 
 typeform_field_id: "<typeform-field-id>",
"memberstack_field_id": "customFields.<fieldID>" }

The Custom Field ID can be found on each custom field’s setting popup.

Was this article helpful?

Comments

0 comments

Please sign in to leave a comment.