In my Flask app I serve the static assets through the app in the dev env, but I'd like to use a CDN in production. Every asset is loaded in a template called base.html
, so I guess the easiest solution is to pass a variable to the render function and use it in the template like:
<script src="{{ STATIC_URL }}/js/main.js"></script>
Normally it would be an empty string in the dev env, and the cdn url in production. I'd like to avoid passing this STATIC_URL
variable to every view. I could make it work with
@bp.context_processor
def set_static_path():
return dict(STATIC_URL='https://foo.bar.com')
But for me this seems a little hacky. Is there a better way to solve this problem?
There's no need to change how you link to static files, you can still use url_for('static', filename='myfile.txt')
. Replace the default static view with one that redirects to the CDN if it is configured.
from urllib.parse import urljoin
# or for python 2: from urlparse import urljoin
from flask import redirect
@app.endpoint('static')
def static(filename):
static_url = app.config.get('STATIC_URL')
if static_url:
return redirect(urljoin(static_url, filename))
return app.send_static_file(filename)
Whether you're on a dev machine or production, set the STATIC_URL
config value to the CDN and requests for static files will be redirected there.
Redirects are relatively cheap, and are remembered by browsers. If you get to the point where performance is meaningfully affected by them, you can write a function that links directly when using the CDN.
@app.template_global()
def static_url(filename):
static_url = app.config.get('STATIC_URL')
if static_url:
return urljoin(static_url, filename)
return url_for('static', filename=filename)
The template_global
decorator makes the function available in all templates. Use it instead of url_for
when you need urls for static files.
There may be a Flask extension that does this for you already. For example, Flask-S3 provides a url_for
that serves static files from AWS S3.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With