Styles and scripts
AssetMapper handles styles and scripts in Symfony. It needs neither Node.js nor a build: the browser loads files as JavaScript modules, and Symfony adds a version to their names so that an old cache is not shown after an update.
Where the files live
| Path | Purpose |
|---|---|
assets/app.js | The main script |
assets/styles/app.css | Styles |
assets/controllers | Stimulus controllers |
importmap.php | The list of modules to load |
Adding to a page
{# templates/base.html.twig #}
<head>
{% block javascripts %}
{{ importmap('app') }}
{% endblock %}
</head>The importmap() function prints everything needed. Styles are imported from the main script:
// assets/app.js
import './styles/app.css';
console.log('The page has loaded');Images
A file from the assets folder is printed with the asset() function:
<img src="{{ asset('images/logo.png') }}" alt="Logo">The address includes the file's version: /assets/images/logo-3c16d92m.png.
Third-party packages
php bin/console importmap:require bootstrapThe command downloads the package and records it in importmap.php. After that it is imported as usual:
import 'bootstrap/dist/css/bootstrap.min.css';
import { Modal } from 'bootstrap';Stimulus
Stimulus ties small scripts to the markup. A controller is a file in assets/controllers:
// assets/controllers/counter_controller.js
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ['output'];
count = 0;
increment() {
this.count++;
this.outputTarget.textContent = this.count;
}
}<div data-controller="counter">
<button data-action="click->counter#increment">+1</button>
<span data-counter-target="output">0</span>
</div>The file name counter_controller.js gives the name counter. The controller needs no registration.
Turbo
The Turbo package from the same family loads pages without a full reload: following links and submitting forms get faster without a line of your own JavaScript.
Preparing for deployment
php bin/console asset-map:compileThe command copies every file with its version into public/assets, and the web server serves them directly.
When you need a build
For TypeScript, Sass or React there is another path — Webpack Encore or Vite. They require Node.js and a build step but support any front-end tooling.
Common mistake
If you run asset-map:compile on your own machine, Symfony starts serving the built files from public/assets, and style changes stop showing up. Delete that folder — and files are taken from assets again. The command is run only when deploying to a server.