How to serve static files in Flask
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Flask serves static files (CSS, JavaScript, images, fonts) from a static/ directory by default. Files in this directory are accessible at the URL /static/filename. The url_for('static', filename='...') function generates the correct URL for static assets in templates, including cache-busting query strings when files change. For production, a reverse proxy like Nginx should serve static files directly for better performance.
Default Static File Serving
Flask automatically serves files from a static/ directory relative to the application:
Files are accessible at:
http://localhost:5000/static/css/style.csshttp://localhost:5000/static/js/app.jshttp://localhost:5000/static/images/logo.png
Using url_for in Templates
url_for('static', filename='...') generates URLs like /static/css/style.css. Always use url_for instead of hardcoding paths because it handles URL prefixes, blueprints, and cache busting automatically.
Custom Static Folder
Sending Files Programmatically
send_from_directory
send_from_directory safely serves files from a directory, preventing path traversal attacks. It validates that the resolved path stays within the specified directory.
send_file
send_file sends a specific file with custom headers. as_attachment=True triggers a browser download instead of inline display.
Serving Files with Cache Control
In templates, url_for does not add cache-busting by default. Use a custom filter:
Blueprint Static Files
Each blueprint can have its own static folder, allowing modular applications with isolated assets.
Production: Nginx Reverse Proxy
In production, let Nginx serve static files directly instead of Flask:
Nginx serves static files 10-100x faster than Flask because it is optimized for file serving and does not involve Python.
WhiteNoise for Simple Deployments
For PaaS deployments (Heroku, Railway) without Nginx:
WhiteNoise serves static files efficiently from Python and adds proper cache headers.
Common Pitfalls
- Serving static files with Flask in production: Flask's built-in server is single-threaded and not optimized for file serving. Use Nginx, Apache, or a CDN for static files in production.
- Hardcoding
/static/URLs in templates: Hardcoded paths break when the static URL prefix changes or when using blueprints. Always useurl_for('static', filename='...'). - Path traversal with
send_file: Usingsend_file(user_input)directly allows attackers to read arbitrary files. Always usesend_from_directorywhich validates the path stays within the specified directory. - Caching stale CSS/JS after updates: Browsers cache static files aggressively. Without cache busting (versioned URLs or hash-based filenames), users see old CSS/JS after deployments.
- Placing
static/in the wrong directory: Flask looks forstatic/relative to the application module, not the working directory. Ifapp = Flask(__name__)is inmyapp/app.py, the static folder ismyapp/static/.
Summary
- Flask serves files from
static/at the URL/static/filenameby default - Use
url_for('static', filename='path/to/file')in templates for correct URLs - Customize with
static_folderandstatic_url_pathparameters inFlask()orBlueprint() - Use
send_from_directoryfor safely serving user-facing files from custom directories - In production, use Nginx or a CDN to serve static files instead of Flask
Related reading
- how to set camera position for 3d plots using python/matplotlib?
- How to set class attribute with await in __init__
- How to set common axes labels for subplots
- How to set env variable in Jupyter notebook
- How to set environment variables in Python?
- How to set environment variables in Python?
- How to set optuna's study.optimize verbosity to 0?
- How to set parameters to score function in sklearn SelectKBest
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.