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.