Static Files (CSS, JS, Images)
Static files are the unchanging assets your site sends to the browser — stylesheets, JavaScript, images, and fonts — and Flask serves them automatically from a special folder named static .
Learn Static Files (CSS, JS, Images) in our free Flask course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free Flask course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll learn where static files live, how to link them from templates with url_for , and how to style and add behavior to the HTML pages you built in the previous lesson.
A static file is any file that the server sends to the browser unchanged — it isn't generated per request like a Jinja2 template. The most common ones are CSS stylesheets, JavaScript files, and images.
Flask reserves a folder named static for these assets. Any file you put there is automatically reachable at the /static/ URL — you don't write a route for it.
With that layout, static/style.css is served at /static/style.css . Run the app with flask run and open that path in your browser to confirm the file loads.
Inside a template you build the URL to a static file with url_for('static', filename='...') . Flask returns the correct path, so your links keep working even if the app is mounted at a subpath later.
The example below defines a route that renders a template, and the template uses url_for to load a stylesheet, a script, and a logo image. The route returns the rendered HTML page to the browser.
When you run this, url_for("static", filename="style.css") prints /static/style.css . In the browser the page loads with your stylesheet, script, and logo all wired up correctly.
In a real app the HTML lives in templates/index.html and you render it with render_template . The route stays tiny; the template and the CSS file do the visual work.
The code below renders index.html and passes a page title. The template links static/style.css , and the route returns the finished HTML response.
Complete the app and template below. Replace each ___ so the page links its stylesheet and image from the static folder.
The file isn't inside the static folder, or the filename is misspelled. Confirm the path is static/style.css and that you referenced filename='style.css' exactly.
You hard-coded /static/style.css . Use url_for('static', filename='style.css') so the URL is rebuilt correctly no matter where the app is mounted.
Build a page that pulls in both a stylesheet and a JavaScript file from the static folder.
Lesson 6 complete — your pages can have style now!
You learned where static files live, how Flask serves them at /static/ , and why url_for('static', filename=...) is the safe way to link them from templates.
🚀 Up next: Request & Response Objects — read incoming data and craft exactly the response you want to send back.
Practice quiz
By default, which folder does Flask serve static files from?
- public
- static
- assets
- files
Answer: static. Flask reserves a folder named 'static' next to your app and serves its files automatically.
At what URL is static/style.css served by default?
- /assets/style.css
- /css/style.css
- /files/style.css
- /static/style.css
Answer: /static/style.css. Files in the static folder are reachable at the /static/ URL, so static/style.css maps to /static/style.css.
Which call builds the URL to a static file in a template?
- url_for('static', filename='style.css')
- static_url('style.css')
- url('static/style.css')
- asset('style.css')
Answer: url_for('static', filename='style.css'). url_for('static', filename='...') asks Flask for the correct path to a static asset.
Why prefer url_for over hard-coding /static/style.css?
- It is shorter to type
- It caches files automatically
- It rebuilds the correct URL even if the app moves to a subpath
- It minifies the CSS
Answer: It rebuilds the correct URL even if the app moves to a subpath. Hard-coded paths break when the app is mounted elsewhere; url_for always generates a valid link.
How do you rename the static folder to 'assets'?
- app.static_folder = True
- Flask(__name__, static_folder='assets')
- STATIC
Answer: Flask(__name__, static_folder='assets'). Pass static_folder='assets' to Flask() to change the folder name from the default 'static'.
Where must the static folder sit?
- Inside templates/
- Anywhere on the system path
- In the project root only after deploy
- Next to app.py (or your package)
Answer: Next to app.py (or your package). Flask finds the static folder using the __name__ you passed to Flask(__name__), so it must sit next to your app.
What argument names the file inside url_for('static', ...)?
- filename
- path
- src
- file
Answer: filename. You pass filename='style.css' to identify the file relative to the static folder.
A static CSS request returns 404. What is a likely cause?
- The browser cache is stale
- Debug mode is off
- The file is not inside the static folder or is misspelled
- url_for was used
Answer: The file is not inside the static folder or is misspelled. A 404 usually means the file is not in the static folder or the filename does not match exactly.
Which folder holds the HTML that links the static files?
- static/
- views/
- pages/
- templates/
Answer: templates/. Rendered HTML lives in templates/, and those templates link to assets in static/ via url_for.
What does the 'static' argument to url_for refer to?
- A custom view you must define
- The built-in static endpoint
- A config flag
- The templates folder
Answer: The built-in static endpoint. 'static' is the built-in endpoint Flask registers for serving files from the static folder.