I bought the prince.gr domain at 2001. I actually had to mail a bunch of papers to a different city on a remote island, and wait two or three weeks for the written confirmation. We used Netscape back then, and later Microsoft Internet Explorer 4, and they where fine. Wayback Machine has (mostly broken and incomplete) captures of that domain from October 2001, but I have zipped backups of almost all my previous creations. I had to dig deep into old backup folders in an old hard disk to grab these screenshots — I found a bunch of CDs too, deep in a drawer full of useless cables and hardware, but didn’t have the stomach to put them in the (aging) optical reader of my desktop. I might even have the first version of prince.gr in there — the one that got me my first paid job in the industry!

I used Macromedia Flash (acquired by Adobe Systems in 2005) a lot those days, while mp3 was all the rage, so the first sites I built were a combination of those technologies. Later, I learned PHP, and rebuilt my site on ExpressionEngine at 2007, I think. The next year I made a basic CMS with PHP and MySQL and migrated my content there, before moving to WordPress and make custom themes — that should be late 2009. I’ve been using WordPress ever since, but I find it hard to keep up with PHP development these days, since I have settled on the front-end part of website building.


The articles that I have authored from time to time are pure, handmade HTML. I had invested a great deal of time configuring the various platforms I’ve used to not mess with my code! So, the general idea (of this redesign) was to keep the old markup, serve static HTML files from GitHub Pages or Netlify (that is where I ended up, by the way), to gain speed and drop the cost of shared hosting, but I didn’t want to copy and paste the header and footer and every piece of irrelevant to the article markup, every single time! That is what the CMSs where invented to do, if I’m not mistaken! I decided to use Pug. The source files, .pug, .scss and .es6 are “transpiled” with Prepros. I could use Gulp or Webpack or Middleman, Haml or Twig or whatever is hip or fresh or a thing these days, but I like this setup, it is fast and it works.

The file system, at the start of the redesign process

Bulma is used to style the site — a custom build of some defaults and utilities. The final (minified) stylesheet is smaller than 70 KB, without the stylesheets that are needed for the third-party scripts (3 KB for the minified stylesheet of Prism, 18 KB for the minified stylesheet of lightgallery.js, along with a few icon fonts and a handfull of images) — however, these are not loaded on every page! I could certainly optimize further but it is not worth it· there is a service worker that caches those assets to localStorage after all.

The JavaScript code that is required is: Prism (16 KB, minified custom build), that styles code blocks nicely and makes the code readable, the lightgallery.js (24 KB, custom build) which is needed for image zooming and galleries, and a dozen lines of custom code that initializes the above. I don’t need share, like or tweet buttons — I’m pretty sure that whoever feels the need to share my content to the “social” networks will be able to do that without extra tracking code! I also don’t need jQuery any more. The contact form is handled by Netlify. I have no analytics JavaScript.

I found JustComments, CommentBox and Commento for commenting on the articles, cloud-hosted, and not funded with ads or selling customer and user data. I liked the pay-as-you-go system of JustComments but I was afraid that, with the public API they have, a script kiddie could easily consume my credits for no reason… CommentBox should be free for my usage case but with the fear of overflowing the free tier, while Commento is $3 per month, which is nothing compared to the disadvantages that the “free” Discus and Facebook comments bring along.


The file structure initialy looked like the screenshot. The general idea was for the articles to be in /LANG/article/ARTICLE_TITLE URLs, article archives / category listings whould be in /LANG/articles/ARTICLE_CATEGORY, the transpiled styles and scripts whould be in /assets/ and all the sources in /src/. I had to adjust some things along the way but the idea is mostly unchanged. I do have to copy the content of the most recent article in the /index.html file, with the correct canonical <link>. Every time I write an article I have to create / update 5 or 6 .pug files (!), but it is easier and faster than it sounds — and is quite similar to how we used to build website 20 years ago, with tools like Dreamweaver… Thankfully, the web platform has greatly improved during those 20 years, and these static pages that I now serve are accessible, mobile friendly, based on modern web standards and contain Schema.org code.

There is a block with variables at the top of every article source file, with the relevant information, and Prepros simply “concatenates” extended and imported Pug files and builds a single HTML file — here is the source of this article at the time of writing:

// /src/pug/en/article/pvgr-v9.pug
extends ../../_layout

block vars
  //- imports Prism style and script
  - var has_code = true

  //- imports lightGallery styles and scripts
  - var has_gallery = true

  //- controls the HTML lang attribute, “logo” language and paths @ header
  - var is_english = true

  //- self-explanatory, used in different places in other partial Pug files
  - var permalink_english = '/article/en/pvgr-v9.html'
  - var permalink_greek = '/article/el/pvgr-v9.html'
  - var canonical = 'https://www/pvgr.eu'+ permalink_english
  - var title = 'pvgr.eu redesign, version 9 | The blog of Panayiotis «pvgr» Velisarakos'

block content
  article.content.article-content(itemscope itemtype='http://schema.org/Article')
    .article-header.article-header-projects
      meta(itemprop='author' content='Panayiotis “pvgr” Velisarakos')
      h1.article-title(itemprop='name headline') Τhe 9th redesign of <strong>pvgr.eu</strong> (former <em>prince.gr</em>)
      time.article-subtitle(datetime='2019-04-18T15:00' itemprop='datePublished') 18 April 2019

    figure.article-photo.article-thumb(itemprop='image' itemscope itemtype='https://schema.org/ImageObject')
      img(src='/assets/img/articles/pvgr-v9.svg' alt='' itemprop="url")
  …
// /src/pug/_layout.pug
doctype html

block vars

html(lang=is_english ? 'en-US' : 'el')
  head
    meta(charset='UTF-8')
    meta(name='viewport' content='width=device-width, initial-scale=1.0')
    title #{title}
    link(href='/assets/css/pvgr.css' rel='stylesheet')
    link(href=canonical rel='canonical')

    if has_code
      link(href='/assets/css/vendor/prism.css' rel='stylesheet')

    if has_gallery
      link(href='/assets/css/vendor/lightgallery.css' rel='stylesheet')

  body
    .site-wrapper
      include _header

      main(class='site-content')
        block content

      include _footer

    if has_code
      script(src="/assets/js/vendor/prism.js")

    if has_gallery
      script(src="/assets/js/vendor/lightgallery.min.js")

    script(src="/assets/js/pvgr.js")

The excellent book of Jeremy Keith, Going Offline helped me build a ServiceWorker script, that saves static resources (stylesheets, javascripts, images) and articles in browser Cache, and serves an “offline” page in case the visitors looses the connection while browsing my site, IF the requested page has not yet been saved to the cache! Good stuff!