Django static files: How to configure and serve them

In Django, static files are the non-dynamic assets that shape your web application’s front end, including CSS, JavaScript, and images.
You need to manage static files carefully because Django treats them differently in development and production environments.
Keep reading as we walk you through configuring and serving static files in your Django project. You’ll learn how to:
- Set up your project. Configure the settings.py file so Django knows where to find and serve your assets.
- Use static files in templates. Load and link stylesheets, scripts, and images in your HTML templates.
- Prepare for deployment. Run the collectstatic command to gather all your static files in a single production-ready directory.
- Serve files in a live environment. Configure NGINX to deliver collected static files efficiently.
- Optimize asset delivery. Implement caching and file hashing to improve loading speed and performance.
How to configure static files in Django settings
You configure static files in Django through the settings.py file. In it, you define key parameters that tell Django where to find and how to serve your assets.
Setting STATIC_URL and STATICFILES_DIRS
In development, you mainly configure two settings: STATIC_URL and STATICFILES_DIRS.
- STATIC_URL defines the URL prefix Django uses when linking to static assets.
- STATICFILES_DIRS lists the directories where Django searches for project-level static files.
Add the following to your project_name/settings.py file:
# project_name/settings.py # URL prefix for static files. # Example: '/static/css/style.css' STATIC_URL = '/static/' # Additional directories Django will search for static files, # in addition to each app's 'static' folder. STATICFILES_DIRS = [ BASE_DIR / "static", ]
App-specific static files structure
By default, Django looks for static files inside a static folder within each app directory. This approach keeps every app’s assets organized and self-contained.
A good practice is to create a subdirectory inside static named after the app itself. Doing so prevents filename conflicts when multiple apps include assets with the same name, such as style.css.
Here’s an example structure:
my_app/ ├── __init__.py ├── models.py ├── static/ │ └── my_app/ │ ├── style.css │ └── main.js └── views.py
After configuring and organizing your static files, use them in your Django templates to load stylesheets, scripts, and images.
How to use static files in Django templates
To use static files in Django templates, load the static template tag library and use the {% static %} tag to generate the correct URL for each asset.
Loading the {% static %} tag
Place the {% load static %} tag at the top of any template that references static assets. This makes the {% static %} tag available in that template.
{% load static %} <!DOCTYPE html> <html>
Examples for CSS, images, and JS
After loading the static tag library, link your CSS, JavaScript, and image files with the {% static %} tag. This tag takes the asset’s relative path and generates the full URL based on your STATIC_URL setting.
Here’s an example using the my_app structure:
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>My App</title> <link rel="stylesheet" href="{% static 'my_app/style.css' %}"> </head> <body> <h1>Welcome!</h1> <img src="{% static 'my_app/images/logo.png' %}" alt="Logo"> <script src="{% static 'my_app/main.js' %}"></script> </body> </html>
The next step is to prepare your static files for deployment so Django can serve them efficiently in production.
Preparing static files for deployment
In a production environment where DEBUG is set to False, Django’s development server stops serving static files.
Therefore, you must collect all project static assets into a single directory that your web server can access. The django.contrib.staticfiles app, included in INSTALLED_APPS by default, handles this process.
Configuring STATIC_ROOT
The STATIC_ROOT setting defines the directory where Django collects all static files from your project and its apps for deployment.
Don’t confuse STATIC_ROOT with STATICFILES_DIRS:
- STATICFILES_DIRS tells Django where to look for static files during development.
- STATIC_ROOT tells Django where to place the collected files for production.
Add this line to your project_name/settings.py file:
# project_name/settings.py # Absolute path to the directory where collectstatic gathers static files for deployment. STATIC_ROOT = BASE_DIR / "staticfiles"
Running collectstatic
Use the python manage.py collectstatic command to gather all static files from your STATICFILES_DIRS and app directories, then copy them into the folder defined by STATIC_ROOT.
Run the following command in your terminal:
python manage.py collectstatic
Django will prompt you to confirm, then copy the files and create the staticfiles directory if it doesn’t exist.
While collectstatic prepares your files for production, Django also provides built-in tools for serving static files during development.
How to serve Django static files in production
In production, configure a dedicated web server such as NGINX or Apache to serve static files directly from the STATIC_ROOT directory.
This setup improves efficiency by letting your Django application server handle dynamic requests while the web server delivers static assets.
NGINX example configuration
A typical NGINX setup uses a location block to intercept requests for static files and serve them directly from the filesystem. NGINX forwards all other requests to your Django application.
Here’s a basic server block configuration:
server { listen 80; server_name your-domain.tld; # Serve static files location /static/ { alias /path/to/your/project/staticfiles/; } # Forward requests to Django app location / { proxy_pass http://127.0.0.1:8000; # Gunicorn running on port 8000 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
In this example, NGINX serves any request starting with /static/ directly from the staticfiles directory, while forwarding all other requests to your Django app.
Using a CDN for Django static files
A content delivery network (CDN) offers an even faster way to serve static assets. By delivering files from servers closer to your users, a CDN improves performance and reduces load on your application server.
To use a CDN:
- Run collectstatic to gather all files into the STATIC_ROOT directory.
- Upload the contents of STATIC_ROOT to your CDN provider’s storage, such as Amazon S3 or Cloudflare R2.
- Update your settings.py file to point STATIC_URL to your CDN domain:
# settings.py STATIC_URL = "https://your-cdn-provider.com/static/"
Once configured, the {% static %} tag generates URLs that point to your CDN, speeding up delivery of your site’s assets.
With your static files served through a web server or CDN, you can optimize them further to improve loading speed and overall performance.
Optimizing Django static files
To improve your application’s front-end performance, add caching and file versioning to your static assets.
Caching with headers
You can tell browsers to cache your static files by adding caching headers in your web server configuration. This lets the browser store a local copy of the files for a set time, avoiding unnecessary downloads on repeat visits.
In NGINX, add the expires and add_header directives inside your static location block:
location /static/ { alias /path/to/your/project/staticfiles/; expires 30d; add_header Cache-Control "public, no-transform"; }
Using ManifestStaticFilesStorage
Long-term browser caching creates a problem when you update a file: users may still load the old cached version. Django solves this with a technique called cache-busting.
When you enable ManifestStaticFilesStorage, Django renames each static file with a hash of its content during the collectstatic process. For example, style.css becomes style.a1b2c3d4.css.
Because the filename changes whenever the content does, the browser must download the new version.
Enable it by adding this line to settings.py:
# settings.py STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
In addition to optimizing your own assets, you’ll often need to include third-party static libraries in your Django project.
Integrating third-party static libraries in Django
You can integrate third-party front-end libraries such as Bootstrap or jQuery into your Django project with just a few steps. The process works the same for any library.
- Download the library’s compiled CSS and JS files.
- Create a folder inside your project’s main static directory (the one defined in STATICFILES_DIRS). A common practice is to name it vendor.
- Place the library files inside this folder. For example, with Bootstrap you might have:
- static/vendor/bootstrap/css/
- static/vendor/bootstrap/js/
- Link to these files in your templates using the {% static %} tag, just as you would with your own assets:
{% load static %} <link rel="stylesheet" href="{% static 'vendor/bootstrap/css/bootstrap.min.css' %}"> <script src="{% static 'vendor/bootstrap/js/bootstrap.bundle.min.js' %}"></script>
What should you learn after configuring Django static files?
Now that you understand how to manage static assets, the next step is learning how Django handles application data and user authentication.
A key part of this is customizing the Django user model. Doing so lets you extend the default user schema to fit your project’s needs.
Getting this structure right is crucial, since it directly affects how you implement features like user profiles, permissions, and personalized content.
All of the tutorial content on this website is subject to Hostinger's rigorous editorial standards and values.