Static Websites with Flask

I was investigating static site generators last week, I have used a couple of them before; this website is generated by Pelican, I am one of the maintainers of MkDocs, I use Sphinx regularly and I have written my own before1.

However, this time I wanted something a little bit different. I wanted to generate a website based on some very specific logic. I was looking for something like a "static site generator framework". Most static site generators take a set of Markdown or reStructuredText files and merge them with a template (and generate the navigation etc.). For my needs, I needed to generate the site based on a specific data source. Only a small number of the pages would be truly static, the others I would just generate on a semi-regular basis.

Possible approaches

I considered writing a pre-processor that would generate a website Pelican could build - but that felt a little inflexible. I also thought about writing a plugin for Pelican, and I was just about to start when Rachid Belaid recommended Frozen-Flask. The chance to re-use my existing Flask experience and the Flask ecosystem was hard to turn down.

Getting stated

Spoiler: It couldn't be any easier. I am impressed.

This is the example in the documentation, and in many cases I'm sure it is all you need (after a pip install). I didn't do anything extra.

from flask_frozen import Freezer
from myapplication import app

freezer = Freezer(app)

if __name__ == '__main__':
    freezer.freeze()

It is easy to see how Frozen-Flask would find and generate URLs without parameters. However, I have some pages that are generated with code similar to the following. Will this work? How can it determine the possible values for page?

@pages.route('/<page>/')
def page(page):
    contents = store.get_page(page)
    return flask.render_template("page.html", contents=contents, name=page)

I was amazed that Frozen-Flask picked up all of these - from the documentation it sounds like they have found a way to hook into the url_for in Flask (the method that creates URL's for each of your endpoints). They then follow each of these links and essentially crawl the website. So if your pages are linked internally or don't require any parameters they will be generated automatically2. Very neat.

At some point I will have to look and see how this works.

Moving Beyond Static

I only thought of this advantage after the fact, but it occurs to me, that if I ever want to make this website dynamic, it would be very easy - I just need to remove Frozen-Flask and host it like any other site, the transition would be seamless.


  1. It was the cool thing to do a few years ago. Yeah, I regretted it. The amusing part is that I said "I wont do this again". It was only a while after I started working on MkDocs that I realised it was just another static site generator. With a different goal of course, so I think it works well. It is interesting how we can sometimes group these things differently when they are largely the same. 

  2. Any endpoints that are not called with display a warning, so you don't need to worry about pages being missed. Of course, if you don't link to every possible input, some will be. You can provide a URL generator to be safe. 


Thanks for reading. You should follow me on Twitter.

Do you have any feedback or comments? The best place for discussion is on Reddit or Hacker News. Otherwise, email me.