No third-party JavaScript, no cookie
The site is fully functional without third-party JavaScript (excluding CDN & DNS) and cookies as I browse the Internet (including my own blog) with uBlock Origin hard mode on.
Optional first-party JavaScript, GDPR compliant
The only first-party JavaScript used are here to provide these functions:
Down for now as no one is really commenting and I’m tired of maintaining such a deprecated project.cusdis.umd.js
,iframe.umd.js
& possiblyzh-cn.js
(in CJK posts): self-hosted Cusdis w/ security patches, an open-source & lightweight (less than 10kB) comment system. You can disable it by blockinghttps://log.vinfall.com/js/*
script.js
1: self-hosted umami, an open source Google Analytics alternative. It’s GDPR compliant by default plus my bonus setting to respect Do Not Track header in case anyone still use it. Moreover, it’s hosted in the data center of Frankfurt, Germany to improve privacy at the expense of speed. Of course Germany is still included in 14 Eyes countries but this is already the best choice on Vercel. Let’s go back to the topic, uBlock Origin would block the defaultumami.js
in v1 andscript.js
in v2 as I don’t obfuscate the name. If that is not the case, you can disable it by blockinghttps://stat.vinfall.com/stats/script.js
katex.min.js
&auto-render.min.js
: KaTeX library for math typesetting, only loaded in posts with LaTeX support enabled. It’s supposed to work without client side JavaScript, but I have not found an elegant solution yet.translate.js
: self-hosted translate.js, a machine translation API frontend. I’m using v3 (aka.client-edge
) powered by Microsoft (Azure?) translation API. I’ve yet to write a Vercel route to only load this in URLs with?lang=
parameter. For the time being, if you don’t want to use this, simply blockhttps://blog.vinfall.com/translate.js
As you can see from the footer, this site is built by a static site generator named Hugo with all possible privacy enhanced settings turned on. Also, starting from 2024-01-28, there would be no new X (Twitter) outlinks to avoid Elon’s walled garden, which, to my surprise, is very easy since there is only one post containing such link.
There is no annoying cookie placeholder (with so-called essential cookies always enabled) you don’t care about or intrusive Enable JavaScript to Browse the Site banner. I make sure it’s hustle-free by default so you don’t have to.
Terminal friendly, and accessibility
Besides that, if you use good old TBB (Text-Based Browser) like W3M or Lynx, bare reading, created/updated date and word count will work fine. The only thing (excluding JavaScript/image ofc) not working is the Font Awesome CSS in the sidebar (or footer in portrait orientation), which should have rendered a few icons of my socials.
If you are using W3M, press <Shift> + <l>
will list all links on the page including those social links.
It’s easier in Lynx: lynx -listonly -dump $URL
. The hidden links are what you need.
I rarely add images/videos in posts as they usually have no benefit but distraction, but when I do, they are all converted using ImageMagick/FFmpeg into AVIF2/WebM formats and have proper name & alternative text so you get the idea without loading it in the first place.
I wished to add alternative typeface like OpenDyslexic to improve accessibility. But judging from google/fonts#558, it seems that such fonts are misleading and do not work much as intended.
Full-text RSS, even for tags
The site provides native full-text RSS.
It’s also possible to receive updates for certain tags/categories simply by adding a /index.xml
suffix.
For example, if you only want a RSS for /tags/dev, just use /tags/dev/index.xml as your feed URL.
Full-text search
Yes, static sites can have search as well. Simply head to /search and explore a bit. This is powered by pagefind (Rust & WASM under the hood, thus requiring JavaScript), which breaks PGP key authentication as expected :) I’ve yet to solve it…
š” Tip
Currently CJK segmentation is not well supported and requires manual spacing. Simple words should work fine though.
iCalendar subscription
iCalendar (ICS) subscription is also available as an alternative to RSS. Initially I wished to provide a post calendar view, just like the one Curl maintainer Daniel Stenberg has on his blog, but settled on this. You can subscribe ICS to have that on your local calendar instead.
Translate via URL param
You can read my posts in your preferred language by adding a url parameter namely
Deactivated by default as it slows down the whole website at a large scale.?lang=WhateverSupported
.
For example, to read this page in Japanese, simply head to `/about?lang=japanese.
You can manually activate it by running the following code in console using developer tools:
var script = document.createElement('script');
script.src = '/translate.js';
script.onload = function() {
var elementsToTranslate = ['page__body', 'aside__desc', 'TableOfContents']; // only translate these elements
var documents = [];
elementsToTranslate.forEach(function(elementIdOrClassName) {
var element = document.getElementById(elementIdOrClassName) || document.getElementsByClassName(elementIdOrClassName)[0];
if(element) {
documents.push(element);
}
});
translate.setDocuments(documents);
translate.language.clearCacheLanguage(); // clear cached language on page switch to avoid overload
translate.language.setUrlParamControl('lang'); // access via `?lang=english`
translate.selectLanguageTag.show = true;
translate.ignore.tag.push('blockquote'); // do not translate quote
translate.ignore.class.push('highlight', 'page__header', 'page__footer', 'aside__about', 'aside__tag'); // ignore as failsafe
translate.service.use('client.edge'); // bleeding edge version API
translate.execute();
};
document.body.appendChild(script);
A few things to keep in mind:
- Supported language list is available here
- This would transfer my post content to M$ which I wish to avoid as much as possible, but since I can’t prevent you from doing so, make sure to at least use this feature instead of Google Translate
- Block method is mentioned in #Optional first-party JavaScript, GDPR compliant
SSL/TLS Full, HSTS and TLS 1.3
It’s almost common sense that we should go HTTPS and drop TLS 1.0/1.1, as SSL Labs (May 2024) reports over 99.7% of top sites have secure renegotiation.
The site is set to SSL/TLS Full (but not strict) in Cloudflare dashboard, with HTTP Strict Transport Security (HSTS) including subdomains enabled (but I have not set a Max-Age). It also have TLS 1.3 support of course, but that’s Vercel’s business. The minimum TLS version is set to TLS 1.2 as I see no request with lower versions for a long time.
Dark Theme
This is personal and may not be an awesome feature for many. But as one of those who values their retinas when working at 3 AM, I take pride in the membership of darktheme.club.
PGP-Signed Page
One killer feature of my previous blog framework bm is the ability to generate a signature for every output file in the built static site. It’s the only site generator I know about that has this feature, no matter dynamic or static.
I really miss this feature and could not find any resource to achieve this, except the blog of bm’s own author. And even himself does not use it now.So I spent a whole night and implemented it myself3.
We use about in this example (self-reference/fractalš¤£):
# Import public key into GnuPG
wget https://blog.vinfall.com/pubkey.asc
gpg --import ./pubkey.asc
# Download and verify
wget https://blog.vinfall.com/about/
wget https://blog.vinfall.com/about/index.html.asc
TZ=UTC gpg --no-options --keyid-format long --verify index.html.asc index.html
The above should output a message containing Good signature
,
otherwise the file is corrupted.
By the way, as long as you download the public key from the site
and its fingerprint is
(the public key is updated on 2024-06-16, new fingerprint should be
A61AF15A44205E4B2BABFEA09A92DEDB762B3A03
58222FDBCBFB1D0D51AE0088C20D48DA42BADC2E
),
you may safely discard any additional warning.
PS: If you are interested in adding this feature to your site, check Add PGP Signature to Hugo/Hexo/Any Static Site. Also, Regarding the Perfect GPG Keychain can be helpful.
PPS: Currently broken due to #Full-text search, I’d fix it before October.
Todo
A list copied from my personal wiki, and provided as a demonstration of possible upcoming features. They may or may not get implemented anyway.
- Add bio
- Add Tartarus (personal blocklist)
- Add PGP public key to contact me
/random
(need further investigation)- Copy code button (no JavaScript?)
- Overlay image in pure CSS
- Improve accessibility
- Reading status bar/minimap
- Add ABC Notation support
- Alternative Internet protocol (doubt if anyone except me will use it…)
- 3D model rendering
- Mermaid rendering
- Colored tags
- Admonitions (Callouts)
- Binary map mini-game…
The End
OK, so much talk on a site that transfers only 70 kB data4 when visiting this page. It cannot beat the speed of sourcehut5, but it gets most of my aesthetics & philosophy delivered.
Blacklight reported 0 tracker by the way. ↩︎
Starting from 2024-02-02 since MSEdge 121 rolls out with AVIF support in Jan 2024. ↩︎
Please note I sign pages only (not images, CSS, non-existent JavaScript etc). ↩︎
Open developer tools and check it yourself. Note in LaTeX-enabled posts this would be significantly larger but still relatively small ↩︎