When I started this blog, I embraced some free services, like Disqus or Google Analytics. These services are quite invasive for users’ privacy. Over the years, I have tried to correct this to reach a point where I do not rely on any “privacy-hostile” services.
- Before: Google Analytics
- After: nothing
Google Analytics is a ubiquitous solution to get a powerful analytics solution for free. It’s also a great way to provide data about your visitors to Google—also for free. There are self-hosted solutions like Matomo—previously Piwik.
I opted for a simpler solution: no analytics. It also enables me to think that my blog attracts thousands of visitors every day.
- Before: Google Fonts
- After: self-hosted
Google Fonts is a very popular font library and hosting service,
google-webfonts-helper service makes it easy to self-host any font
from Google Fonts. Moreover, with help from
pyftsubset, I include only the characters used in this
blog. The font files are lighter and more complete: no problem
spelling “Antonín Dvořák”.
- Before: YouTube
- After: self-hosted
Some articles are supported by a video (like “OPL2LPT: an AdLib sound
card for the parallel port“). In the past, I was using YouTube,
mostly because it was the only free platform with an option to disable
ads. Streaming on-demand videos is usually deemed quite difficult. For
example, if you just use the
<video> tag, you may push a too big
video for people with a slow connection. However, it is not that hard,
thanks to hls.js, which enables to deliver video sliced in
disabled are still delivered with a progressive version of medium
In “Self-hosted videos with HLS”, I explain this approach in more details.
Disqus is a popular comment solution for static websites. They were recently acquired by Zeta Global, a marketing company and their business model is supported only by advertisements. On the technical side, Disqus also loads several hundred kilobytes of resources. Therefore, many websites load Disqus on demand. That’s what I did. This doesn’t solve the privacy problem and I had the sentiment people were less eager to leave a comment if they had to execute an additional action.
proxy_hide_header Set-Cookie; proxy_hide_header X-Set-Cookie; proxy_ignore_headers Set-Cookie;
Another option would have been to not provide comments anymore. However, I had some great contributions as comments in the past and I also think they can work as some kind of peer review for blog articles: they are a weak guarantee that the content is not totally wrong.
<form id="lf-search" action="https://duckduckgo.com/"> <input type="hidden" name="kf" value="-1"> <input type="hidden" name="kaf" value="1"> <input type="hidden" name="k1" value="-1"> <input type="hidden" name="sites" value="vincent.bernat.ch/en"> <input type="submit" value=""> <input type="text" name="q" value="" autocomplete="off" aria-label="Search"> </form>
- Before: RSS feed
- After: still RSS feed but also a MailChimp newsletter
Nowadays, RSS feeds are far less popular they were before. I am still baffled as why a technical audience wouldn’t use RSS, but some readers prefer to receive updates by mail.
MailChimp is a common solution to send newsletters. It provides a simple integration with RSS feeds to trigger a mail each time new items are added to the feed. From a privacy point of view, MailChimp seems a good citizen: data collection is mainly limited to the amount needed to operate the service. Privacy-conscious users can still avoid this service and use the RSS feed.
- rendering mathematical content (like in “TLS computational DoS mitigation”),
- moving footnotes as sidenotes when the screen is large enough,2
- enhancing videos to use HLS (see “Self-hosted videos with HLS”), and
- enhancing photo galleries with a lightbox (see “Debian on Thinkpad Edge 11”).
The remaining code is still here but is self-hosted.
Content-Security-Policy header controls the resources that
a user agent is allowed to load for a given page. It is a safeguard
and a memento for the external resources a site will use. Mine is
moderately complex and shows what to expect from a privacy point of
Content-Security-Policy: default-src 'self' blob:; script-src 'self' blob: https://d1g3mdmxf8zbo9.cloudfront.net/js/; object-src 'self' https://d1g3mdmxf8zbo9.cloudfront.net/images/; img-src 'self' data: https://d1g3mdmxf8zbo9.cloudfront.net/images/; frame-src https://d1g3mdmxf8zbo9.cloudfront.net/images/; style-src 'self' 'unsafe-inline' https://d1g3mdmxf8zbo9.cloudfront.net/css/; font-src 'self' about: data: https://d1g3mdmxf8zbo9.cloudfront.net/fonts/; worker-src blob:; media-src 'self' blob: https://luffy-video.sos-ch-dk-2.exo.io; connect-src 'self' https://luffy-video.sos-ch-dk-2.exo.io https://comments.luffy.cx; frame-ancestors 'none'; block-all-mixed-content;
I am quite happy having been able to reach this result. 😊