Handling Environments with Typeform

Easing testing and maintenance with a customised redirection

Thomas Vanderstraeten
Typeform's Engineering Blog
5 min readDec 5, 2018

--

At Seraphin, we make extensive use of Typeform to handle our online insurance subscription process. We have found that it greatly increased our overall form completion rate while providing an unmatched speed of deployment 🚀— all the while allowing to alleviate the coding burden from our devs, as the business can manage most of our forms directly.

Let me introduce our typical use case for Typeform at Seraphin: we have a home-built product landing page (say, the Digital Nomad Insurance page), from which the user is directed to a form when they click the call-to-action. After submission of the form, the user is redirected to our website and we collect all of her data from the Typeform API to continue the process seamlessly.

Still, there was something that we started missing after deploying a large number of forms across the website: environments management! For each form we created, we had to have at least 2 versions: one for production purposes and one for the dev and staging environments. This way, we made sure that:

  • 🗳️ We could always distinguish real data from test data when analysing responses
  • 🔗 Users would get redirected to the right URL on completion (production, staging, localhost), so we can do E2E testing easily
  • ⚙️ Business integrations (e.g. with IFTT, Zapier, Built.io…) would only be triggered by real production responses

However this proved to be a real pain, as we needed to maintain 2 versions simultaneously. This is okay if you’re making a lot of changes and trials on the test version before rolling out to production, but once you’ve come to a stable version you want to reduce the duplication.

So that’s how we came up with a creative hack to handle all our environments on the same Typeform, using a combination of hidden fields, a parameterised redirection from Typeform, and an AWS Lambda Serverless function. This proved to be a funny thing to implement and it’s currently working quite well. Hope you can learn from it as well 💪 !

The approach

The key architectural catch is that we perform a double redirection after the form submission. First the Typeform will redirect to the Lambda function, passing important parameters in the URL query, then the Lambda will read these query parameters and perform a second redirection to the right environment-dependent URL accordingly.

Architectural setup

So you can fully grasp what’s at play and replicate the setup, we will go step-by-step here:

  • Adding a hidden environment field to your form
  • Creating the Lambda function (with an API endpoint)
  • Performing a parameterised redirection to the Lambda
  • Finally setting up the Lambda function to redirect once again

Each of these steps is important for the integration to be fully functional.

Adding a hidden environment field

Can you see the hidden field in there?

Start by adding an environment hidden field to your Typeform. You will be assigning its value directly from the calling website. So when your website references a form from one of the devs’ local machines, it should do so with a link like https://example.typeform.com/1234?environment=development, and so on for the other environments. It is easy to achieve this with a Presenter pattern (if you’re on a RoR stack for example) or any other construct that modifies the Typeform link on the fly depending on the current environment.

Creating a redirector Lambda function

From the AWS Lambda console, create a new Node.js function, and assign it a new (open, without access key) API Gateway endpoint. Make sure to note the URL generated (let’s say it is https://redirector.com). Then copy-paste the following code in the function body, for minimal testing:

This code snippet will simply redirect any HTTP request made to the endpoint to the example.com website, using a 302 temporary redirection.

Save the function in the AWS console, and try to visit the API Gateway endpoint URL created with the function (https://redirector.com in our case): you should be automatically redirected to example.com.

Adding a parameterised redirection

Next, head to the Typeform admin console and navigate to the redirection settings. There, make sure that the redirection routes to https://redirector.com?environment=${environment}, where the ${environment} flag means you should select directly the value of the hidden environment field.

Now if you save and try to complete your form, you will be redirected to the Lambda function, which will redirect you to example.com, regardless of the environment parameter passed in the URL query.

Handling the redirection per environment

Finally we want to have a dynamic redirection per environment. For this, let’s use the very simple code snippet for the Lambda function:

So when the Lambda receives an HTTP request, it will look for the corresponding environment in the query parameters, and depending on the value provided it will redirect the requester to the right URL (note the localhost URL for development and the staging subdomain for staging).

Save the Lambda function. Now you should have a fully operational per-environment redirection for your Typeform! 🎉

Other things to consider 🤔

The above approach solves the problem of having to maintain duplicate forms per environment. Now, when it comes to handling responses to your Typeform, you can easily filter them to only get the ones flagged with the production environment.

Similarly for your business integrations (with IFTT, Zapier, Built.io,…), you can build custom logic to only act upon incoming responses if they have the right environment.

As a final remark, note that you can (and probably should) use other less obvious keywords than environment for the hidden field. This way, your users are not tempted to mess up with your testing environments if they see the hidden value (be creative!).

👋🏼 Cheers from Seraphin!

Happy Typeform hacking!

Cheers,
Thomas and the whole
Seraphin team

--

--