Static Content Deployment

Why browsers read pub/static, what setup:static-content:deploy does, and the symlinks developer mode uses instead.

Syntaxbin/magento setup:static-content:deploy [-f] [-s quick|standard|compact] [-a frontend] [-t Vendor/theme] [-j 4] [<locale> ...]

No browser reads app/design or app/code. It reads pub/static, the only directory the web server exposes. Static content deployment is the step that collects, compiles and copies view files from modules and themes into pub/static/<area>/<Vendor>/<theme>/<locale>/. Every theme and every locale gets its own tree, which is why the directory is large and why restricting the deploy to the themes and locales in use saves real time.

The command

bin/magento setup:static-content:deploy does the work. In production mode it is mandatory: nothing is generated on request, so a file you changed is invisible until the command runs. It also writes pub/static/deployed_version.txt, the value Magento puts into asset URLs so browsers stop using cached copies. The default strategy is quick; standard and compact are also available through -s, and -j runs several jobs in parallel.

Developer mode does it for you

In developer and default modes files are materialised on request, and where possible as symlinks into the source directory, so editing a source file changes what the browser receives. For that reason the command refuses to run in those modes unless you pass -f.

What trips people up

Stale files. If a change does not appear, delete the generated trees and let them rebuild: pub/static/frontend and var/view_preprocessed, then bin/magento cache:flush. Keep pub/static/.htaccess.

Example

Example · bash
# Run from the Magento root, as the file-system owner.

# In developer mode the command declines, by design:
bin/magento setup:static-content:deploy
# NOTE: Manual static content deployment is not required in "default" and "developer" modes.
# In "default" and "developer" modes static contents are being deployed automatically on demand.
# If you still want to deploy in these modes, use -f option: 'bin/magento setup:static-content:deploy -f'

# In production mode it is required, and -f is not needed:
bin/magento deploy:mode:set production
bin/magento setup:static-content:deploy en_US de_DE -j 4
# New content version: 1759658400
# Execute: frontend/Acme/storefront/en_US
# Execute: frontend/Acme/storefront/de_DE
# Execute: adminhtml/Magento/backend/en_US

bin/magento cache:flush

# Where the files land:
#   pub/static/frontend/Acme/storefront/en_US/css/styles-m.css
#   pub/static/frontend/Acme/storefront/de_DE/css/styles-m.css
#   pub/static/deployed_version.txt   <- 1759658400

When to use it

  • A CSS change works locally but not on staging after a release.
  • Cut build time by deploying only the one theme and one locale the store uses.
  • Recover a storefront that renders unstyled after a half-finished deploy.
  • Explain to a colleague why editing a .less file on a production server changes nothing.

More examples

Clearing stale static content in developer mode

The usual fix when an asset change refuses to appear. Deleting the generated trees makes the next request rebuild them from source. Delete the contents, not the directories: pub/static/.htaccess and var/view_preprocessed are expected to exist, and removing the .htaccess file exposes the directory listing.

Example · bash
# Developer mode, change not showing up
rm -rf pub/static/frontend/*
rm -rf var/view_preprocessed/*
bin/magento cache:flush

# pub/static/.htaccess must survive; check it is still there
ls -la pub/static/.htaccess

A narrow deploy for one theme

The default deploy builds every registered theme, including Blank, Luma and the admin theme, in every enabled locale. On a build server that is minutes you do not need. Restrict the area, the theme and the locale, and exclude what you never serve. Keep the admin area deployed, or the admin loads without styles.

Example · bash
# Storefront theme only, one locale, compact output
bin/magento setup:static-content:deploy -f \
    --area frontend \
    --theme Acme/storefront \
    --strategy compact \
    en_US

# The admin still needs its own area
bin/magento setup:static-content:deploy -f --area adminhtml en_US

Where it sits in a production build

The order matters. Code generation and dependency injection compilation come before static deployment, because the deploy reads generated files, and the cache flush comes last. This is the sequence a release script runs after pulling new code; running the static deploy first and compiling afterwards produces a storefront with missing assets.

Example · bash
composer install --no-dev
bin/magento setup:upgrade --keep-generated
bin/magento setup:di:compile
bin/magento setup:static-content:deploy -f en_US -j 4
bin/magento cache:flush

Discussion

  • Be the first to comment on this lesson.