DEV Community

loading...
Cover image for How to handle Webflow Multi-Reference Fields in Form Submissions

How to handle Webflow Multi-Reference Fields in Form Submissions

ymusleh profile image Yusuf Musleh ・7 min read

Summary

Creating a Collection Item in a Webflow CMS when a user submits a form is a common use case for a Webflow site. There have been multiple ways to achieve this using the many low-code/no-code automation tools. However, historically there's been a common complaint amongst many makers; that things get tricky when the form contains multi-reference fields because of the way Webflow formats them in the form submission event data.

In this article I'll walk you through solving this problem using Autocode. You can see it in action right away by performing form submissions from a sample Webflow site and see collection items created in the CMS when forms are submitted.

First, you need to clone the Webflow site by clicking here, then pressing the Clone button on the top right to copy the sample blog form site to your own Webflow account. Then, you need to map the values of each category field in the form to the corresponding Category item ID and publish the site. (If you're not sure how to get the category IDs, check the How It Works section below).

Once you've cloned and published the Webflow site, click here to open the starter app in Autocode. You can checkout the source code if you'd like, then install the app to your Autocode account. You'll then be asked to link your Webflow site, simply follow the instructions to do so. Next, you'll need to set the COLLECTION_ID environment variable for the Blog Posts collection in the site you cloned. (If you're not sure how to get the collection id, check the How It Works section below).

After that, you're good to go! Once the app finishes installing and deploying, you can go to your Blog Site and submit a form selecting some Categories (multi-reference fields). A new blog post will appear in the CMS referencing the correct categories that were selected!

Webflow Form

Webflow CMS

Introduction

Webflow is a great tool for building websites and e-commerce stores with little to no code required. Utilizing their powerful drag & drop UI builder bundled with their CMS, means you can go from an idea to a live website in a very short period of time. It has become a very common tool in the arsenal of many makers.

One of common use cases or flows many people build on Webflow is a form that stores submissions in the Webflow CMS. In other words, being able to create a Collection Item when a user submits a response to a form on the site. There have been multiple ways to achieve this using the many low-code/no-code automation tools. However, historically there's been a common complaint amongst many makers; that things get tricky when the form contains multi-reference fields.

Say you have a blogging website that allows users to create blog posts by submitting a form on your site. In that form you allow your users to tag their blog posts with different topic categories. These categories are fetched from a collection you created in your Webflow CMS. These categories are represented as a multi-reference field in your Blog Posts.

The Problem

Generally the automation of this process involves 2 steps:

  1. Listening to when a form is submitted
  2. Creating a new Collection Item using the data from the submitted form

While most tools do a great job handling the first step, listening to form submissions from Webflow. Passing in that data directly to the default Webflow Create Collection Item connector/module would usually fail when multiple items are selected in the multi-reference field. This is because of how Webflow represents multi-reference field data in the event object and what the connector/module expects.

Below is sample payload that Webflow sends when a form is submitted (in this case Categories is the multi-reference field):

{
  "d": "2020-08-26T16:29:54.226Z",
  "_id": "000000000000000000000000",
  "data": {
    {
      "Title": "[SOME_TITLE]",
      "Content": "[SOME_CONTENT]",
      "Categories": "000000000000000000000001,000000000000000000000002,000000000000000000000003"
}
  },
  "name": "FORM_NAME",
  "site": "000000000000000000000000"
}
Enter fullscreen mode Exit fullscreen mode

Notice how the data in Categories is a comma-separated string instead of an array. If you try to pass this in directly to the connector/module that creates a collection item it would consider the whole string as a single ID and fail to identify a Category with that ID.

[400] ValidationError: Validation Failure Referenced item not found: categories
Enter fullscreen mode Exit fullscreen mode

Because of this, many folks handle this by stitching together multiple connectors/module to modify the data, and manually make API calls to Webflow to solve this problem.

In this article, I'll show you how to easily handle this using Autocode. A Node.js API development platform and online code editor/IDE with built-in autocomplete, that handles Webflow's authentication, listening to form submission events and creation of collection items.

All you need to follow along is a Webflow account, with this sample blog site cloned, and a free Autocode account.

How It Works

Prerequisites

Before you start, you'd need to setup clone and setup the Webflow site:

  • Click on the Clone button on the top right corner of this page
  • Map each of the category fields in the form to their corresponding Category Item IDs Mapping category IDs

You can find the category IDs, by navigating to the CMS, then clicking on each of the Category Items in the Categories Collection

Categories Collection Item IDs

  • Publish the cloned site to be able to make form submissions

Publish Webflow Site

Let's Get Started

When you link your Webflow site to your app, Autocode takes care of the Authentication, creation and validation of webhooks to listen to form submission events, and making API calls to Webflow.

This app listens to all form_submission events coming from the linked Webflow site by default, you'll notice a wild card * is specified in the form_name field in the event handler. If you'd like to specify a certain form to listen to submission events from, you can add a new form_submission event handler and set the form_name to your specific form's name defined in the Webflow designer.

Diving into some code

The event handler is simply an exported JavaScript function that takes in a parameter called event that represents the event coming in from Webflow. This function runs every time a form is submitted on your site:

const lib = require('lib')({token: process.env.STDLIB_SECRET_TOKEN});

/**
* An HTTP endpoint that acts as a webhook for Webflow form_submission event
* @param {object} event
* @returns {object} result Your return value
*/
module.exports = async (event) => {
  // event handler logic
}
Enter fullscreen mode Exit fullscreen mode

We include all the logic that we would like to run whenever we get a new event, i.e. when a form is submitted on our site. The general structure of the event parameter object is as we described earlier:

{
  "d": "2020-08-26T16:29:54.226Z",
  "_id": "000000000000000000000000",
  "data": {
    {
      "Title": "[SOME_TITLE]",
      "Content": "[SOME_CONTENT]",
      "Categories": "000000000000000000000001,000000000000000000000002,000000000000000000000003"
}
  },
  "name": "FORM_NAME",
  "site": "000000000000000000000000"
}
Enter fullscreen mode Exit fullscreen mode
Creating a Collection Item with Multi-Reference fields

Now that we know how the event handler is setup and what the event object looks like, let's take a look at creating new collection items with these multi-reference fields.

When we get a new form submission we first check if the multi-reference field (in our case Categories) is present in the data object of the event. If it is, simply split it on the commas , to get a list of IDs, otherwise set it to an empty list:

let categoryIDs = (event.data.Categories && event.data.Categories.split(',')) || [];
Enter fullscreen mode Exit fullscreen mode

Based on the example event object mentioned earlier, it will convert it to the following:

["000000000000000000000001", "000000000000000000000002", "000000000000000000000003"]
Enter fullscreen mode Exit fullscreen mode

Note: You'd need to do this for every multi-refernce field you have in order to pass it in the endpoint below to create the collection item.

Next, to create the collection item in Webflow we utilize the
collections.items.create API endpoint from Autocode's Standard Library, and pass in the required fields:

  await lib.webflow.collections['@1.0.0'].items.create({
    collection_id: process.env.COLLECTION_ID,
    fields: {
      'name': `${event.data.Title}`,
      'categories': categoryIDs,
      '_archived': false,
      '_draft': false
    },
    live: true
  });
Enter fullscreen mode Exit fullscreen mode
  • collection_id: is the ID of the collection in the CMS to create the item in. To get that ID, navigate to the CMS tab in the Webflow designer of your site, then click on the settings button for the Collection (in this case Blog Posts) and it should be there

Webflow Collection ID

  • fields: the fields of the item that will be created. Notice how we passed in the categoryIDs list to the categories field to reference the categories that the blog post maps to in Webflow

  • live: whether or not the item should be published to the live site when created

Once that endpoint is called, the new item will be created and appear in the Blog Posts CMS in Webflow.

Webflow CMS Collection Item

Tying it all together

The final result of the event handler should look something like this:

const lib = require('lib')({token: process.env.STDLIB_SECRET_TOKEN});

/**
* An HTTP endpoint that acts as a webhook for Webflow form_submission event
* @param {object} event
* @returns {object} result Your return value
*/
module.exports = async (event) => {
  let result = {};

  let categoryIDs = (event.data.Categories && event.data.Categories.split(',')) || [];

  await lib.webflow.collections['@1.0.0'].items.create({
    collection_id: process.env.COLLECTION_ID,
    fields: {
      'name': `${event.data.Title}`,
      'categories': categoryIDs,
      '_archived': false,
      '_draft': false
    },
    live: true
  });

  return result;
};
Enter fullscreen mode Exit fullscreen mode

That's It!

Thank you for checking out this post. If you have any questions or feedback please feel free to join our community Slack channel. You can get an invite from the Community Tab in the top bar of the Autocode website.

You can also follow the Autocode team on Twitter for updates @AutocodeHQ.

Discussion

pic
Editor guide