Recently, I finally got around to designing something of a portfolio website for me. There really is never time to do these, is there? You can head over to GitHub to view the source if you want, no need to keep it private. 

The general setup is a Jigsaw-based static site using TailwindCSS as style framework. The whole site does not have a single line of JavaScript in production which – surprise! – massively simplifies the setup! (Also, like, loading times are amazeballs.)


Before deciding on the frameworks to use, I set up some constraints for the design and more so for the technical foundation of the site:

  • Graceful degradation on older browsers
  • Very good accessibility
  • Responsive-ish layout
  • Fast
  • Low-barrier content modification

Along came also some quirky demands like wanting to use flexbox for layout and having Twig or Blade as a Template Engine as I am most comfortable thinking template logic in those. I also wanted to write as little as possible server or generation code as this site will – for the foreseeable future – not have any dynamic content. Nevertheless, some kind of content editing that can be easier than always writing everything in HTML was added as a nice-to-have.

In my toolbox, these requirements form a straight path towards static site generators. Among these, since I am well-versed in Laravel, Jigsaw is the obvious choice for me. One never knows if there's any modifications to be made and it always helps to know ones way around the underlying architecture.

Choosing TailwindCSS as a style framework was a no-brainer. It is a wonderfully simple solution and I find myself clicking with the utility-only approach.

Getting it done

Jigsaw provides several events to modify and extend the build process. Since my goal was to add content to the resulting HTML files after all other build steps, I opted for adding a handler on the afterBuild event:

// in Jigsaw's bootstrap.php

/** @var $events \TightenCo\Jigsaw\Events\EventBus */

The Inline Styles event handler is of course where the magic happens. First, all built html files need to be gathered, Symfony's Finder component is great at that:

$htmlFilesFinder = Finder::create()

Then, we can fetch the compiled CSS and inject it into a style tag in the head using SimpleXML:

$htmlFile = simplexml_load_file($htmlFilePath);

        $cssPath = $jigsaw->getDestinationPath() . (string)$htmlFile->head->style['data-src'];

        $cssContents = file_get_contents($cssPath);

        $htmlFile->head->style = $cssContents;

        file_put_contents($htmlFilePath, $htmlFile->asXML());

The full code is available on GitHub: