Why use Django {% static %} template tag?

Code Review Doctor
3 min readNov 5, 2020


If you’re familiar with Django static files in you would make a similar suggestion:

screenshot taken from https://django.doctor

But why? Again if you’re familiar with Django static files you may say yes, because we may be serving from S3 in production. But there’s more to it.

If you’re not familiar: {% static %} returns the path of static file so the browser can request the file. On our local dev environment it’s from the local file system, but changing STATICFILES_STORAGE will change that: third-party libraries such as whitenoise or django-storages changes the behavior in order to improve performance of the production web server.

So what factors will affect the path of the static URLs?

Renamed files

If STATICFILES_STORAGE perform file revving for cache busting purposes then the file being served will be renamed. javascript.js may be renamed to javascript-23e2332.js. The STATICFILES_STORAGE generates a hash from the file’s contents and renames the file to include the hash. Then a manifest file is created that looks like:

{ 'javascript.js': 'javascript-23e2332.js'}

This is called revving. When {% static ‘javascript.js’ %} is called, 'javascript.js' is looked up in the manifest and ultimately 'javascript-23e2332.js' is rendered in the template.

This is for cache busting: revving allows cache headers to safely be set to cache forever in the CDN or browser. Next time the content of the file changes then the rev changes and after deploying the template will be serving a different rev so cache is busted. Such aggressive caching would be a lot harder without this revving.

So {% static %} abstracts this mechanics away so we can focus on more important things.

Where the website lives may change

Over time the place the website is served from can change due to business requirements changing:

  • Change from subdomain serving to path: foo.example.com to example.com/foo/ and bar.example.com to example.com/bar/ for marketing reasons.
  • Merging multiple codebases into the same repository for improving development efficiency

This means /static/ can no longer be used as it would be unclear which files should be served: foo’s files or bar’s files? During the refactor to facilitate the change the developer could replace all of foo’s /static/ with /foo/static/ and vice versa. But the developer has enough on their plate. If {% static .. %} was used from day one then that’s one things that’s not needed.

So {% static %} prevents CSS from breaking because where the website is served from changed.

Different domain

Django suggest not serving static files from the web server in production. One way to do that is to upload the files to object storage like S3 and serve the files from there instead.

If STATICFILES_STORAGE serves from S3, then the domain will likely be different from the url of the webserver.

So using {% static ‘javascript.js’ %} ultimately renders https://my-s3-url.com/javascript.js instead of /static/javascript.js.

So {% static %} handles changes in the domain the files are served from.

I’m a GitHub bot that suggest Django improvements to your code. You can check your entire codebase at django.doctor or install the GitHub PR bot to reduce dev effort and improve your code.