Is there a Flask or Jinja2 configuration flag / extension to automatically minify the HTML output after rendering the template?
8 Answers
Found a better way to do this. You can minify all your pages with this method:
from flask import Flask
from htmlmin.main import minify
app = Flask(__name__)
@app.after_request
def response_minify(response):
"""
minify html response to decrease site traffic
"""
if response.content_type == u'text/html; charset=utf-8':
response.set_data(
minify(response.get_data(as_text=True))
)
return response
return response

- 4,595
- 8
- 48
- 80
-
works perfectly as expected on python2.7, but behaves strangely on python2.6. Throws an "ValueError: zero length field name in format" exception. – 25mhz Jun 22 '16 at 21:01
-
1Thanks for that great code snippet. I've adapted it to **beautify**, not to minify the output: http://stackoverflow.com/a/43606937/2648551 – colidyre Apr 25 '17 at 10:06
-
1Doesn't that minify the output at EVERY request? Couldn't it alter the cache version of the template (or minify it before it saves the cache)? – jeromej Jul 05 '17 at 18:37
Have a look here https://github.com/cobrateam/django-htmlmin#using-the-html_minify-function
I realise it is mainly used for django but the example shows how to use this projects code to do what you want with a flask view, i think.

- 11,559
- 3
- 39
- 45
-
-
3Not anymore, after [this](https://github.com/cobrateam/django-htmlmin/commit/497efd73ddfbe9c7b83975dc413cd94ef78fbb2b). – alexcasalboni May 15 '14 at 08:11
-
2Is there a "deploy-time" solution, similar to how a lot of js projects do it? There is no reason to minify most templates and static data each time and on each request. Would be nice if it was possible to minify everything that's possible during, say, setup.py. – Dan M. May 21 '18 at 13:38
I use the following decorators
import bs4
import functools
import htmlmin
def prettify(route_function):
@functools.wraps(route_function)
def wrapped(*args, **kwargs):
yielded_html = route_function(*args, **kwargs)
soup = bs4.BeautifulSoup(yielded_html, 'html.parser')
return soup.prettify()
return wrapped
def uglify(route_function):
@functools.wraps(route_function)
def wrapped(*args, **kwargs):
yielded_html = route_function(*args, **kwargs)
minified_html = htmlmin.minify(yielded_html)
return minified_html
return wrapped
And simply wrapped the default render_template function like so
if app.debug:
flask.render_template = prettify(flask.render_template)
else:
flask.render_template = uglify(flask.render_template)
This has the added benefit of being auto added to the cache, since we don't actually touch app.route

- 883
- 1
- 8
- 17
-
Sadly you still need to apply to each of your view files importing it… I had hoped you could have just changed the engine and all output accross all my files would have been minified. – jeromej Jul 10 '17 at 00:32
-
Why do you use your own decorator and not [the one that already exists in `htmlmin`](https://htmlmin.readthedocs.io/en/latest/reference.html#htmlmin.decorator.htmlmin)? – bfontaine Mar 26 '22 at 12:19
-
1@bfontaine To be honest, I wrote this answer 6 years ago when I was just starting college. I have to assume I just didn't see it in their docs or was feeling clever or something similar. I don't think the answer I gave is horribly bad though. – Ethan McCue Mar 27 '22 at 15:10
-
Also @jeromej, 5 years too late but this answer *does* affect the the entire engine since it replaces flask.render_template. – Ethan McCue Mar 27 '22 at 15:12
I've written a flask extension to achieve that purpose. You can install it using pip install flask-htmlmin
and the source is available at https://github.com/hamidfzm/Flask-HTMLmin . Hope it will be useful.

- 4,595
- 8
- 48
- 80
-
From a thought of "I wonder how to easily minify HTML in flask" to "of course someone else had that question on SO" to "ah, naturally there is a library" and finally arrive at this answer with "the fabulous hamidfzm has a written a flask plugin that does it all in 2 lines" – kontur Mar 17 '20 at 09:44
Use the decorator.
from htmlmin.decorator import htmlmin
@htmlmin
def home():
...
Or you can just use:
re.sub(r'>\s+<', '><', '<tag> </tag>') # results '<tag></tag>'

- 1,986
- 12
- 14
-
1
-
Be careful with that regex, it might break your HTML in a visible way. Minifying the string `a big fat
edithere` results in the output `a bigfatedithere` -- the spaces have been clobbered. – smitelli Oct 20 '15 at 14:45 -
White space between characters are omitted by the standards. One of the reasons why for example in Django there is a **{% spaceless %}** tag and **htmlmin** has **minify** method. – Andrey Shipilov Oct 22 '15 at 01:28
-
Would that work with the cache or only Ethan McCue's answer would? (I've yet to investigate further but maybe you know the answer already_) – jeromej Jul 09 '17 at 23:48
-
Of course it will. Ethan's method is a ridiculous overkill just cause of bs4. – Andrey Shipilov Jul 10 '17 at 01:30
To extend the usefulness of the answer from @olly_uk and the comment by @Alexander, it appears that the django-htmlmin extension is now designed to be used with frameworks other than Django.
From the docs here, you can manually use the html_minify function in Flask views, like so:
from flask import Flask
from htmlmin.minify import html_minify
app = Flask(__name__)
@app.route('/')
def home():
rendered_html = render_template('home.html')
return html_minify(rendered_html)

- 486
- 7
- 9
-
-
1@llamawithabowlcut, html_minify is called after the template has been rendered at runtime. If the concern behind the question is performance, where possible I also couple this to a Flask cache (Flask-cacheify in my instance). If that's not possible, then yes it might be relatively expensive to call html_minify for each serving of a view. – Bletch Aug 09 '14 at 09:59
-
I can do this with the `re` module: `return sub(r'\s{2,}|[\r\n]', '', render_template('blah.html'))`... What makes minify special? – Vasili Syrakis Sep 05 '14 at 04:43
-
@Sasili Syrakis - For the OP's use case I'm not sure there is anything that would constitute 'special', but it is comment-aware - allowing you to include or exclude comments from the minified HTML. It also comes with a convenience decorator, has a command line version for static html files and allows you to include or exclude files by path. *I haven't tried these features with Flask. – Bletch Sep 06 '14 at 07:26
Modifying @Bletch answer for the latest version of htmlmin.
from flask import Flask
import htmlmin
app = Flask(__name__)
@app.route('/')
def home():
rendered_html = render_template('home.html')
return htmlmin.minify(rendered_html)
https://htmlmin.readthedocs.io/en/latest/quickstart.html
The minified html will still have some spaces between the tags. If we want to remove that, then remove_empty_space =True
attribute needs to be added while the template is rendered.
return htmlmin.minify(rendered_html, remove_empty_space =True)

- 635
- 1
- 7
- 19
In 2022, I have found better success using the minify-html package: https://github.com/wilsonzlin/minify-html
minify_html.minify(
"""
html here
""",
minify_js=True,
minify_css=True,
remove_processing_instructions=True,
)

- 186
- 1
- 3