Academic Website VII: Dirty Tricks | Hendrik Erz

Abstract: Over the past weeks, I have shared many tips on how to set up your own, personal website. Today I want to finish up the series (for now) with a small and incomplete collection of "dirty tricks" that I find very appealing in the context of personal websites; from automating away chores to giving a better user interaction.

Over the past weeks, I have covered all that I know about setting up a personal website for yourself. As you were able to see, there is a lot to know. Despite the length of the articles, they barely scratch the surface of possibilities when it comes to the web. I have been making websites for the past 20 years and there are still things I don’t know. This should give you an idea of how vast the web is.

Today, I want to finish off this article series with a quick section on tips and tricks of what you can do with your personal website. This is an incomplete enumeration, and there are many additional cool things that you will discover over the course of managing your website.

Custom Landing Pages

I am starting with two tips that I already shared. The first one is to create custom landing pages for conferences, presentations, or your university courses. You can use them to collect useful knowledge and additional material for whatever circumstance you find yourself in. With the knowledge you have now, you can do that very easily. Read more on that in my very first article in this series.

Creating custom landing pages involves either creating a new file for a page (if you’re using a static site generator) or creating a new page in your backend. The most important thing for these landing pages is that they need to be easily memorable. If that is not possible, you can always use a link shortener, but this is the second-best option after creating, e.g., “”.

Making Your Blogposts Citeable

This is the second tip that I already shared. Read in article number 5 on how to use Dublin Core and Highwire Press tags to tell Zotero that people can store a reference to your blog posts in their reference manager.

Use Categories for Article Series

If you have ever visited the “Resources” section in the navigation up top, you will have noticed that there are two article series linked: “How I work” and “Academic Website”. How did I do that?

Well, the dumb solution to creating such a section would obviously be to manually copy and paste title, URL, and abstract of each article into this section. But what do I do if I need to correct a typo, or add a new article? Then I would have to remember to always change that list of articles as well.

Or I can use something different. Specifically, while you can’t see them because I chose to hide them, behind the scenes my blog makes use of categories. You certainly have seen those on other blogs already. Now, I don’t feel that using categories for arbitrary categorization of my random blurbs of thought that I often publish on the blog makes sense. But sometimes, there are good reasons for that: either because I want to collect a set of articles relevant to visitors of my IC2S2 poster (see the first tip), or because I have an entire series that makes sense to read chronologically.

In both cases, I can create a new category and assign it to all blog posts that should form a group. I currently have four such categories: IC2S2 (for all articles I linked on my custom landing page), “How I work” for that article series, and “Academic Website” for this one. The last category is the dreaded “Uncategorized” one that you may know if you’ve ever managed a WordPress page. What I then do on my resources page is simply add a component that dynamically generates an article list from that category and spits it out. This will ensure that (a) the info in this list stays up to date, and (b) I can add new articles to those lists simply by assigning the corresponding category.

I always found categories for blogs a bit difficult to manage, especially if they have this diary-style, but this is the first time I have found an (in my opinion) extremely useful use-case for those. Whenever I update, add, or remove articles from any of these series, all places on my website where I cross-link them will stay updated without me having to remember to go to all of these places manually.

Use the Zotero API to Keep your List of Publications Up-To-Date

At this point you know that I’m too lazy to keep lists of articles up-to-date manually. I really like the approach of “automating the boring stuff”, and luckily there is a way of doing the same for your list of publications.

On my CV-page, there is a section with my publications, always up-to-date. But you know what? I didn’t write a single character in that list myself. Instead, what I do is add all my new publications to my Zotero. I do so by following the exact same steps that I do for adding other papers to my library. Then, I drag those into a special collection that you have, too, called “My publications”. You can’t add literature directly to that one, because you’ll have to confirm a few things before, but once my new publications are in that list, I can access them anywhere on the web.

Specifically, Zotero has an API (Application Programming Interface) that will always spit out my up-to-date references.

Here’s what I do to render this list on my CV page:

  1. I select a citation style. You can choose whichever one you want, all are available at I usually default to elsevier-harvard. (The API requires the slug for the style, visible when you move with your cursor over a style and look at the link.)
  2. Then, I create a list of item types that I want to include in the list of publications. I do so to control which ones actually end up in the list on my CV. The available types are documented on the Zotero website. This then looks like this: itemType=book || journalArticle.
  3. I have my website go to the actual URL for retrieving a list of publications by fetching the entire URL:<user-id>/publications/items?format=bib&style=elsevier-harvard&itemType=book%20||%20journalArticle&linkwrap=1 – just remember to replace <user-id> with your user-ID, which you can find on your Zotero profile. The additional linkwrap argument ensures that Zotero creates actual clickable links from the URLs in the citations. All options are documented on the Zotero website.

To see your own user ID, log in to Zotero web, then go to Settings → Feeds/API. Your user ID is the number at the top of the page.

Finally, I do some caching magic so that my website doesn’t contact Zotero too often (because I don’t publish something everyday). For a static website, what you can do is download the list of references shortly before the build process automatically. Whenever an update is needed, you can simply run the build process again.

To show you a little trick: You can even control the style that the citations are in on my CV page by using the style URL-parameter. Try it for yourself – how about using the APA style? Or do you prefer the American Sociological Review style? Or how about the German KZfSS one? Isn’t that cool?

Calculate the Reading Time

Another cool small trick that you can do if you write blogposts is to give visitors an approximate amount of time they will need to read your article. If you look at the top of this page, you will see how long it takes to read this article.

This is actually a very simple thing to do. What you need to do is take the content of a post, split it into words, and divide that by the rough amount of words a person can read per minute. I have chosen the somewhat arbitrary amount of 200 words per minute (which works out pretty good I feel).

For my site, this even fits into a single line of PHP: round(count(explode(' ', $post_content)) / 200). (The reason I can keep this so simple is that I’m using Markdown, so the few additional “words” which this simple method will count don’t matter too much. If your blog posts are in HTML format, that will be a bit more difficult.)

Of course, you can adapt the number of words per minute for every single visitor. How? With my next tip!

Storing Visitor Preferences GDPR-compliant

This is probably a bit arbitrary, but my website actually does this. You know, if you scroll to the very end of this page, you will see a three-way-toggle that should be preset to the middle. What this toggle does is it allows you to switch the website appearance between dark and light mode. It has three states: The first one indicates that the website should always be light, the third one indicates it should always be dark, and the middle one makes the website follow your operating system.

If you now set the toggle to “always dark” or “always light” and reload the website, it will remember your choice! Without logging in to something! And without any cookie.

But how does it do that? Well, here’s the code:

// The default is to follow the operating system
let mode = 'system'
// Then, let's see if the user's browser supports local storage
if (typeof(Storage) !== "undefined") {
    // It does! So let's see if we have stored the mode in there already.
    let store = localStorage.getItem('ui-mode')
    if (store !== null) {
        mode = store // Retrieve the user-customized value.

// Pre-set the three-way and the body with the corresponding mode

Whenever the user switches this toggle back and forth, this will call JavaScript event listeners that update the localStorage with the new value:

function switchMode (mode = 'system') {
    if (![ 'light', 'dark', 'system'].includes(mode)) {

    // This function switches between light, dark, and system modes
    document.body.classList.remove('dark', 'light')
    if (mode !== 'system') {
    // Additionally, save the corresponding mode in the web storage for
    // persistency, if the browser supports that.
    if (typeof(Storage) !== "undefined") {
        localStorage.setItem('ui-mode', mode)

And that’s all there is to it. Of course, I had to write all the corresponding CSS code necessary to actually make the website look light and dark. But this is a great way of adding user-customizability without breaking GDPR. Because again: Everything here happens on the user’s side.

You can of course also use localStorage to let visitors set their own reading pace. (For that you will need to calculate it in JavaScript, not in PHP as I do. So you’ll store the word count somewhere on the website, and then let JavaScript calculate the reading time.)

There are many more things you can do with localStorage. However, there is one thing you should keep in mind: This storage can be cleaned or removed at any time, so whatever you store in there, it should either have a backup somewhere, or it shouldn’t matter too much. When the browser is updated, or the user chooses to clear all site data, localStorage contents will also be gone.

The End of the Journey

And there you have it. There are tons of other cool things you can do once you have a website. In this article, I simply wanted to give you a quick overview over the few possibilities that I myself make use of. Always remember: If you don’t see value in something, don’t implement it. But if you have a nice idea, google it and ask around, because it is very likely possible to implement.

Adding these tiny things can make your website stand out from others, and give it a personal touch. I will continue to change my website whenever I have a useful idea for it, and the journey will probably never end.

I hope that in this very long article series I was able to show you the entire journey from thinking about what you will want to do with your website through actually setting it up to showing you how you can make it machine-readable. I have poured almost twenty full years of experience with the web into this series; starting in 2004 when I first got an internet access. I hope that this will enable you to create a website that reflects you, and that will bring you both visibility but also joy to tinker with.

After you’ve set up a website, please feel free to share it with me – either via Bluesky, Mastodon, or email. I would love to see what you come up with and give you a bit more reach by retweeting it!

So long, all the best, and stay sharp!

Suggested Citation

Erz, Hendrik (2024). “Academic Website VII: Dirty Tricks”., 11 Jan 2024,

Ko-Fi Logo
Send a Tip on Ko-Fi

Did you enjoy this article? Leave a tip on Ko-Fi!

← Return to the post list