StackBlitz blog version 2.0

Hello and welcome to our new blog! We've been working on some crazy new things that we can't wait to share with y'all. But to start off, this first post will be about how & why we built the blog itself (what can we say- we're geeks for web development! :).

Like many other open source projects, we originally started by posting on Medium because of its simplicity and organic reach. However, due to recent changes they've made (i.e. that annoying pop-up window they won't let anyone turn off) we decided it was time to invest in our own blog that we ourselves host & own.

In this post we want to share the process and some technical details behind building the "online journal" itself. We hope it will help you with your own decisions and implementation for a private or company blog.

The choice Permalink

So, the second decision after the "let's get to blogging" resolution was: how do we publish? The two main choices are:

The usual considerations are that platforms give you a ready tool (just sit down and start writing) and a bigger reach, whereas a self-built ones grant full control.

For us at StackBlitz, there was an additional important aspect to keep in mind, and it made the final choice a no-brainer.

As we've realized a while ago, a huge driving force behind our work is wanting to help JavaScript developers write their code easier. We are crazy about promoting Web Platform, experiments, and open-source projects. Doubling-down on that made sense: open source it is.

The solution that we choose had to be also relatively frictionless: easy to start with, and to extend later. Oh, and – as StackBlitz itself – it should be fast too!

There are at least two aspects to being fast:

So... Hugo? WordPress? Gatsby? Permalink

Enter "open source blogging platform" into Google, and you will see dozens of different options to choose from. Here are some of the pros and cons for the solutions we've considered:

Hugo Permalink

WordPress Permalink

Gatsby Permalink

Enter Eleventy Permalink

Eleventy fits all the initial criteria: It's a simple, but extensible open-source project, and it's also written in the JavaScript - language we live and breathe. It's less popular than the aforementioned options but already has a vibrant community. It uses Markdown, it has some plugins, but they seem to be really lightweight. In fact, 11ty's architectural complexity is quite small – we were able to start playing with it in no time, which is always an advantage.

So, how did we set it up? Well, glad you've asked!

The markup Permalink

The posts are written in Markdown files, and each of these starts with frontmatter - a kind of header that includes metadata needed for the post. Like this:

---
title: Hello, my first post!
description: Here I'm introducing my blog
date: 2020-12-12
layout: layouts/post.njk
---


# Hello World!

This blog ......

💡 Tip: Permalink

If you find yourself needing to specify the same property/value pair for all the files of a given type (e.g. posts), you can extract them to a data file, like this posts.json:

{
"tags": [
"posts"
],
"layout": "layouts/post.njk"
}

These properties will be applied to all posts within the directory that includes the posts.json file.


The markdown itself is fine, but we needed more – thankfully, we have plugins! Some of the extensions we're using are:

Besides the article content, we need layouts. Eleventy can work with pretty much everything you'd expect: Handlebars, EJS, Pug, HAML... The default one is Nunjucks, and we've played with it before and liked it, so it stayed.

The styles Permalink

If you've been working with frontend for more than a couple of years you've probably seen it all: 100% custom styling, advanced SCSS codebases, Bootstraps, styled-components, oh my!

The solution that seems to be hitting the right spot for us though is Tailwind CSS. It's just a great mixture of rules and flexibility. The only customization needed was the font, the StackBlitz color, and styling for the post body.

The optimizations Permalink

If it's your first time playing with Tailwind, the 2.3MB of CSS code it spills out may be intimidating, to say the least, but after purging against the compiled HTML templates, it goes down to... 28.86KB, which we certainly can live with.

Another resource we can optimize is images. What we can do here is to serve them using responsive width descriptors within the <source srcset=... element, and also provide the WebP format for browsers that support it. The resulting HTML for images ends up looking like this:

<picture>
<source
srcset="/img/posts/teacup_1920-1920w.webp 1920w,
/img/posts/teacup_1920-1280w.webp 1280w,
/img/posts/teacup_1920-640w.webp 640w,
/img/posts/teacup_1920-320w.webp 320w"

sizes="(max-width: 608px) 100vw, 608px"
type="image/webp"
>

<source
srcset="/img/posts/teacup_1920-1920w.jpg 1920w,
/img/posts/teacup_1920-1280w.jpg 1280w,
/img/posts/teacup_1920-640w.jpg 640w,
/img/posts/teacup_1920-320w.jpg 320w"

sizes="(max-width: 608px) 100vw, 608px"
type="image/jpeg">

<img src="/img/posts/teacup_1920.jpg" alt="teacup">
</picture>

Not terribly pretty to read or write, but hey, we have robots to do it!

And lastly, a prefetch: when a reader hovers a link (or touches on a touchscreen), we're creating a <link rel="prefetch" href="..."> element that suggests browser to fetch the link's target in advance. The implementation is quite straightforward and fits in a couple of lines of code:

// Define event listeners
['mouseover', 'touchstart'].forEach(type =>
document.addEventListener(type, prefetch, {
capture: true,
passive: true
})
);

// Hold the already fetched urls,
// so we don't prefetch multiple times
const prefetched = new Set();

// Prefetch event handler
function prefetch({ target: { tagName, href, origin } }) {
if (tagName !== 'A'
|| origin !== location.origin
|| prefetched.has(href)) {
return;
}
document.head.insertAdjacentHTML(
'afterend',
`<link rel="prefetch" href="${href}" />`
)
prefetched.add(href);
}

The results Permalink

We've ended up with a fairly easy to use – and extend – blogging setup. We've pushed it to GitHub, and set it up with Netlify (Total deploy time: 58s⚡️). We've also made sure it performs well on the speed and other accessibility fields by running the Lighthouse audit. The results?

Our Lighthouse score: 4x100%

Well, it looks like the blog is ready. And we are ready to publish too! In fact, we can't wait to share with you some of the cool stuff we've been preparing for you in the last year. Much of it will make static site generators like Eleventy even easier to set up and use 😉.

So stay tuned!

Thank you, JavaScript community! ❤️ Talk to you soon!

(In the meantime, you can follow our twitter profile - there's always something interesting happening there!)


Acknowledgments Permalink

  1. It is a great feeling to really only have to go the last mile. We wouldn't be able to have so much fun if it weren't for the awesome groundwork the Eleventy community has put in.
  2. Adam Wathan's Tailwind CSS, after just a couple hours of working with it, feels like second nature.
  3. We were also heavily inspired by Malte Ubl's high-performance-blog template - highly recommended if you want to kick off your blog project.
  4. The Shades of Purple theme for the code snippets is provided by the awesome Awais

Tomek Sułkowski

Founding Engineer & DevRel at StackBlitz. Let's talk about docs, live examples, teaching, and experimenting in browsers!

Recent Posts