Cover image
Cover image

Tappable

Tappable is a no-code Software as a Service product that enables the creation and publishing of Web Stories. I am the founder and CTO, and this article is an in-depth exploration about the way Tappable was built.

What is a Web Story?

Web Stories are the web-based version of the popular Story format. Popularized by Snap, and notoriously copied by Instagram, Stories are arguably the first mobile-native format. What text is to paper, and videos are to TVs, Stories are to smartphones.

Full-screen, imagery-rich, flexible and immersive, Stories were an instant hit. But they were limited to the walled gardens of social media companies.

With the development of the open source Web Stories framework, anyone can create Stories for the largest and most open platform: the web.

However, a new wall emerged: you need to be able to code to create Web Stories. So we built Tappable, allowing anyone to create and publish Stories on the web, no code required.

Publishing Stories on the web instead of on social media platforms solves three main issues:

  1. Distribution: Stories have a URL that can be shared anywhere, from messaging apps to QR codes.
  2. Discovery: Tappable Stories can be indexed by search engines, as they are just regular HTML pages.
  3. Ownership: Your content is yours, hosted on your domain, not on social media platforms.

These three characteristics make Web Stories especially attractive for the two main uses we see with our customers: editorial and marketing Stories.

How does Tappable work?

Tappable works similar to other design tools like Figma and Sketch so it will look and feel familiar to designers. Here's a video tutorial I recorded showing the creation of a marketing Story from A → Z.

Product highlights

As Tappable is a complex piece of software, there are a lot of considerations that were made when developing the product over the course of 3 years. In this section I want to elaborate on four different topics.

1. Choosing a grid

The Tappable grid

If you watched the video above, one of the main differences between Tappable and other design tools is the use of a grid. With Tappable, you are limited to placing elements on a 36×60 grid, and layers can not deviate from it. Choosing a fixed grid made it much easier to align items with each other, and between pages.

What this also means, is that the common alignment utilities Alignment icons are not needed anymore. Accurate alignment can be done visually, thanks to the constraints of the grid.

The hardest part was choosing the right grid size. Too coarse, and customers would not be able to reproduce the designs they wanted. Too fine, and visual alignment becomes difficult.

Ultimately, the size was chosen for its divisibility:

  • The width of 36 can be divided in 2, 3, 4, 6, 9 and 12 equally sized columns.
  • The height of 60 can be divided in 2, 3, 4, 5, 6, 10, 12, 15, 20 and 30 equally sized rows.

This allows customers to easily create the layouts they desire, without limiting creativity.

2. Hosting on the edge

Tappable's customers don't have to face the burden of hosting Stories. But how do we ensure Stories are consistently fast?

Our approach to performance has been focused on the edge.

Tappable, as a tool, generates the Story HTML on publication. That HTML is then stored on CDN edge servers, in over 200 locations all over the world.

Cloudflare Edge Nodes

Traditionally, only static assets like images and videos get stored in CDNs. At Tappable, we decided to store the HTML of the Story itself, and get rid of the origin altogether.

Since the data is stored close to where it is being requested, the TTFB has been pushed to less than 100ms, with Stories rendered in 730ms[1].

But it's not just the Story HTML that is distributed around the world. Tappable supports dynamic interactive elements such as forms, products, and links. These elements are stored as HTML partials, separate from the Story.

So you might be thinking: how do these partials get inserted in the Stories?

Tappable makes use of Cloudflare Workers to transform the Story HTML by injecting interactive elements, on every request. Cloudflare Workers are Javascript isolates, running the V8 runtime, and are the perfect combination of cheap, performant, scaleable and reliable. The whole process of transforming the Story HTML takes just a couple of milliseconds, and our Workers have served over 10 million Stories without downtime.

3. Encrypting leads

Tappable has a Forms feature that enables the collection of leads directly from within a Story. This is a really powerful way to ask for emails and phone numbers. But that data is also sensitive and often contains private and personal data.

By default, responses are emailed directly to our customers, and the data is not stored in our infrastructure.

But customers want to be able to see the leads they collected within Tappable, and export them as CSVs. So we needed to save the responses somehow, without Tappable being able to see the content of the responses.

To solve that, we built Form Encryption.

Form encryption

A customer wishing to save encrypted form responses with Tappable first needs to set up a password. With a decryption password set, four things happen:

  1. Their browser generates a 4,096 bit RSA key pair: a private key and a public key.
  2. Their browser encrypts the password 10,000 times using PBKDF2. This makes password cracking much more difficult.
  3. The 10,000 times encrypted password is used to encrypt the private key with AES encryption.
  4. The public key and the encrypted private key are then saved in Tappable's database.

The password that was typed in never left the browser. It was only used to encrypt the private key.

This is what is called Public key cryptography. It allows anyone to encrypt data, while only allowing the private key holder to decrypt it. The public key, as its name implies, is meant to be fully public. It is used for one thing only: encrypt data. The private key needs to remain private, and is protected by the password the customer chose during set up.

When Tappable receives a form response, Tappable uses the public key to encrypt the data. The encrypted data is then saved.

The private key is the only way to unlock data encoded with a public key. And since the password used to encrypt the private key never left the device, Tappable has no way of accessing the private key. And hence, can not decrypt the stored data.

When a customer wants to view the form responses, the encrypted responses are downloaded to their device. Once they enter the password defined during setup, the following happens:

  1. Their browser downloads their encrypted private key.
  2. Their browser encrypts their password 10,000 times using PBKDF2.
  3. The 10,000 times encrypted password is used to decrypt their private key using AES.
  4. Their decrypted private key is used to decrypt the form responses using RSA.

The decrypted data is then displayed to the user, with the option to save it as a CSV.

4. Making Tappable Plug-and-Play

Tappable Stories fill a unique space in the marketing stack. They sit between ads and online stores, similar to landing pages.

Plug and play

But often, landing pages are riddled with trackers and privacy-invasive scripts. These trackers tend to make the landing pages slow, and in many jurisdictions, require consent.

At Tappable, we wanted to avoid showing consent banners. The only way to legally do that, is to avoid collecting personally identifiable information.

Sounds simple enough, but our customers want to be able to retarget their visitors and measure ad conversions. So how do we proceed?

The secret to retargeting and conversion measurement is called a click ID. Ad networks insert a unique click ID to the ad destination link, in the form of a URL parameter (fbclid for Meta ads and gclid for Google ads). That click ID is meaningless to anyone but the ad network.

To calculate conversion and allow for retargeting, advertisers can collect that ID (with consent of course), and send it back to the ad network using tracking pixels. The ad network can then match the ID received with the ID they created, thus knowing which user did what.

Tappable Stories don't have tracking pixels, don't store tracking information in cookies, and hence don't need consent. This allows Story viewers to get immersed in content straight away.

What we do instead is forward all tracking information. Tappable takes the click ID from the URL, and adds that ID to all the links in the Story. That way, when a viewer goes from the Story to the destination website, the click ID is still present, and (consented) tracking can happen like before.

Tech stack

These are the technologies I chose as CTO to build and launch Tappable.

The Tappable app is built with Vite + Vue 3 + Tailwind, and relies on the Firebase + Google Cloud platform for backend. Stories are powered by Cloudflare Workers and the Cloudflare CDN. Our infrastructure is fully serverless and scaleable to 0, defined in code with Terraform, and deployed through Cloud Build. Every provider we use is a green provider, as defined by the Green Web Foundation.

Profile picture

Web Stories

Profile picture

Cloudflare Workers

Profile picture

Cloudflare CDN

Profile picture

Cloudflare Pages

Profile picture

Vue 3

Profile picture

Vite

Profile picture

Tailwind CSS

Profile picture

Javascript

Profile picture

Node.js

Profile picture

Firebase

Profile picture

Firestore

Profile picture

Cloud Run

Profile picture

Cloud Storage

Profile picture

Pub/Sub

Profile picture

Cloud Build

Profile picture

Big Query

Profile picture

FFMPEG

Profile picture

Terraform

Credits

These are the 21 team members and talented people who contributed to Tappable over the course of 3 years. A big thanks to all!

Profile picture

Hans Pauwels

Founder & CEO

Profile picture

Charles-Axel Pauwels

Founder & CTO

Profile picture

Henri-Jérôme Pauwels

Founder & CMO

Profile picture

Louise Brunner

Frontend Developer

Profile picture

Caterina Rodomonti

Head of Sales

Profile picture

Mathilde Vasseur

Designer

Profile picture

Firdaws Oulad Ben Taib

Content Editor

Profile picture

Reinhilde Gielen

Sales

Profile picture

Oluwasegun Oluwadamilola

Sales

Profile picture

Alexandra Medzihradska

Sales

Profile picture

Anna Nogueira

Sales

Profile picture

Rafael Pamplona

Sales

Profile picture

Ekaterine Antelava

Sales

Profile picture

Sabine Boghossian

Content Editor

Profile picture

Ridge Kimani

Back-end Developer

Profile picture

Pieter Poppelsdorf

Sales

Profile picture

Daan Vandevoorde

Video Editor

Profile picture

Maurice Wirtz

Sales

Profile picture

Mathias Redl

Designer

Profile picture

Enrica Laneri

Video Editor

Profile picture

Sonia Ghariani

Sales


  1. Median value based on over 7 million Story views ↩︎