Generate Static Html With Flask Frozen

Oct 19, 2020


If you already have a Flask project which you want to convert to static html, Flask-Frozen is up to the task.

If you just want to generate static HTML, refer to Which Static Site Generator To Use.

The latest version is Version 0.15 (Jun 27, 2017), but it generally works well.

Another issues that it is pretty slow as it run in sequential (about 1 page per second) and hardly utilize a single CPU fully. It might be possible to hack the code to utilize multiple CPU.

Install & Setup

pip install Frozen-Flask


# import flask app from your existing applicationfrom application import appfrom flask_frozen import Freezer# optional# from flask_minify import minify# minify(app=app, html=True, caching_limit=0) # , js=True, cssless=True# default to application root directory (same level as "templates") named "build"FREEZER_DESTINATION = '../build' # MimetypeMismatchWarning: Filename extension of u'new-york' (type application/octet-stream) does not match Content-Type: text/html; charset=utf-8# If the urls are '/new-york', it will warn of MimetypeMismatchWarning# You could either disable warning, or change path to '/new-york/', which generate 'new-york/index.html'FREEZER_IGNORE_MIMETYPE_WARNINGS = True# If run the static generation for 30 minutes and then it crashed, this will only generate files which are not generated yet (basically continue from last run)# If you change the page code and the content is different, it will not regenerate the pageFREEZER_SKIP_EXISTING = True# This is useful during development as you might want to remove certain @freezer.register_generator to speed up the process, but don't want those generated files to be deletedFREEZER_REMOVE_EXTRA_FILES = False# load the above FREEZER_ configurationsapp.config.from_object(__name__)freezer = Freezer(app, with_static_files=True, log_url_for=False, with_no_argument_rules=False)@freezer.register_generatordef url_generator():    yield '/'    yield '/about'@freezer.register_generatordef venues_generator():    from application.models import Venue    items = Venue.query(Venue.is_active == True)    for _item in items:      # yield f"/venues/{_item.url_name}"      yield '', {'url_name': _item.url_name}if __name__ == '__main__':    freezer.freeze()

Flask Routing

If the route is @app.route('/about'), it will generate about file. If the route is @app.route('/about/'), it will generate about/index.html file.

If the route @app.route('/about/privacy'), you must change @app.route('/about') to @app.route('/about/'), as generated about must be a directory in order for privacy to be generated within it.

└── about
    ├── index.html
    └── privacy

NOTE: You can use @app.route('/about/', strict_slashes=False) for optional trailing slashes, and still generate about/index.html.


❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.