You are tasked with implementing a privacy consent modal.
Your website is composed of different Webapps hosted on the same-origin, but under different context paths.
Are we going to have to implement a consent modal multiple times? Even sharing the HTML/styling template wouldn’t be possible. There is no common format that works for Vue.js template, Preact.h
function and React.createElement
function.
If we implement the consent modal independently of the existing apps, how are we going to integrate them? The existing apps need to know whether consent has been given to load additional scripts.
One solution is to iframe
the modal and use postMessage
to communicate with the parent app, but doing so would require us to carefully implement the event listener as any other iframes can now be a security concern.
We can do better. We can implement the consent modal as its own independent JavaScript bundle and include it into our existing Webapps. The Webapps and consent modal communicate state change with a simple callback function exposed on window
.
This is easy enough, let’s just implement the consent modal in React, right? But this raises a few issues.
First of all, bundling React or any other framework for that matter is going to make the bundle massive. The functionality we need is very simple, a modal with 3 buttons.
Second of all, if we were to use React for our consent modal and for the main app, this would mean we’ll be loading React twice. React isn’t a library like lodash where you could just pull in multiple versions. React is a framework that hooks into the browser’s event system. This causes issues when more than one instance of React is loaded.
This is where the title of this blog post comes into play. Applying the Rule of least power directs us to consider, could we implement the consent modal in pure JavaScript without any frameworks? Do we dare to reach for the DOM?
Heresy! It's forbidden dark art to use the DOM API directly! If we touch the DOM, we’ll suffer…wait what’s wrong with using the DOM again?
We’ve been shielded from the DOM for such a long time with modern frameworks, we’ve forgotten how to use it. Heck, some people have never even heard of it and have been productively relying on only knowing React Hooks as their first foray into web development.
The reason why web frameworks, such as React, sprung up was to allow us to handle the complexity of larger websites. It is difficult to manage state and events directly with the DOM, but we don’t have a large website in this case! The consent modal is tiny, in fact here is the entirety of the code for our demo.
Does this seem like too much code for a simple consent modal? Well, compare it to the same code implemented in React. The code is formatted with prettier, so it artificially made it a bit longer due to the style objects, but even then both implementations are similar. However, the React variant’s bundle blows up in size by over 50x as it needs to now include react
and react-dom
.
2.5KB consent-modal-2.0.0-min.js
132KB consent-modal-react-2.0.0-min.js
Here is the full demo of the consent modal in Vue.js and Preact Webapps. The full source code is all found within one organization.
Some details to connect the remaining dots.
window
using Webpackscript
tagThe demo site and the consent modal bundle are both arbitrarily hosted with GitHub Pages.
These ideas can be applied to many other features that need to be implemented cross-functionally over all Webapps. Consider the following features as independent JavaScript bundles
Essentially any reusable chunk of JavaScript that is framework-independent can be extracted. Those with a UI component can also be extracted if it can be its own independent root level DOM element in the HTML body.
Do you want to learn frontend architecture? You’re in luck, Battlefy is hiring.