Building Your Own Static Website Generator

Switching your website from a dynamic approach to a static one doesn’t imply learning a new technology stack. In fact, you can turn almost any dynamic web framework into a static website generator.

Modern web frameworks are incredibly flexible, you can do virtually anything from your local environment: create command lines, API endpoints, manage the file system, etc.

A website is a just a directory with a bunch of documents inside. Static-generating a website means pre-rendering those documents as to make them readily accessible without the need for complex CPU-intensive tasks down the road. Changing the website’s content means re-rendering its web pages, but it’s not as resource demanding as asking a web server to re-render resources on each visit.

When you transform a web framework like Symfony, Laravel, or Ruby on Rails into a website generator, your web pages are still built using a templating engine and services located in your Model layer. All you need is a command line or an endpoint in your Controller layer to write the Build logic.

Here is for example the static file generator service I wrote in my local Symfony application:

<?php
namespace App\Service;
use Twig\Environment as TemplatingService;

class StaticFileGenerator {
    private $templating;
    private $folder;
    
    public function __construct(
        TemplatingService $templating
    ){
        $this->templating = $templating;
        $this->folder = __DIR__ . '/../../static/';
    }
   
    public function render($template, $dest, $args = []){
        if(!file_exists(dirname($this->folder . $dest))){
            mkdir(dirname($this->folder . $dest));
        }
        
        file_put_contents(
            $this->folder . $dest,
            $this->templating->render(
                $template,
                $args
            )
        );
        
        return $dest;
    }
    
    public function build($pages){
        $beg = microtime(true);
        
        if(!file_exists($this->folder)){
            mkdir($this->folder);
        }

        foreach($pages as $page){
            $this->render(
                $page['template'],
                $page['dest'],
                $page['args']
            );
        }

        return microtime(true) - $beg;
    }
}

I then just request the data I need, use Twig as a templating engine to generate all the files I need (not just HTML, but also Javascript code or CSS), call this static file generator service by command line, and everything is written in the local /static folder.

I like to build my personal website’s assets in my local environment and upload them manually to Netlify by compressing the resulting static folder. 

Even though my website contains more than 500 web pages, it only takes half a second to build and another few seconds for Netlify to deploy the files. The resulting website also has a near-perfect performance score when I test it against Google Lighthouse.