Building a client side proxy

Our client, an international initiative bringing unbiased journalism to citizens of a repressive regime, asked us to build a website that gives new meaning to the word “accessible”.

When we talk about inclusivity and accessibility in software design and development, we usually think about keyboard access, screen readers, using thoughtful imagery and content. But what if your audience is actively being blocked from using the website you are building? Can we use front-end technology to enforce the right of free access to information?

Think about it: an offline first-website that proxies any request to the best available mirror

- Our tech lead during architecture talks

A proxy in the service worker

We built a news website, accessible even when servers are blocked, without the need for a permanent VPN connection. How? By leveraging the service worker — a browser script that can handle any request a website makes — to act as a proxy, redirecting all requests to the best available mirror.

These mirrors are hosted on ‘too big to block’-platforms, following the principle of Collateral Freedom. After the visitor opens the website once over a VPN, the service worker is downloaded and installed. The VPN can then be disabled, and the service worker will take over to request content from non-blocked servers, effectively acting as a proxy.

Uncensored communication status

The service worker maintains an index of available mirrors and periodically checks ‘down’ mirrors if they can be reached again. An icon on the website shows the measure of ‘blockedness’, ranging from green to yellow to red. Yet even a red status won’t prevent our audience from using the website: visitors can bookmark articles that get stored locally for offline use, and any article or page they visited earlier will be cached offline as well.

There you have it: we built an ‘offline first’-solution that proxies any request to the best available mirror, preventing authorities from censoring our content. This is what we mean with next level accessibility.

Technical stuff

  • Our unique solution requires a fast JAMstack build with complete control over full and partial builds and server configuration. Using headless Wordpress with a RESTful API, Eleventy with Nunjucks templating and no client side framework whatsoever gives us all we need.
  • We built for performance, following the stale-while-revalidate pattern: locally cached content has priority, and if newer content is available from the server, the user can choose to refresh the page. Bandwidth usage is kept as low as possible.
  • When a mirror is taking too long to respond, we mark it with an ‘unreliable’ status. This way the user won’t be waiting for a server that is not quite down but severely throttled.
  • All assets (eg. images) are hosted on a primary server to reduce deployment size and hosting cost. Being outside the influence of a blocking agent, every mirror can redirect these requests to the primary server.
  • Our next step in this project: use IPFS (a P2P or peer-to-peer networking protocol) to distribute content. This means a centralised server is not needed to distribute content: users (peers) distribute content themselves.
← All blog posts