Logo

dev-resources.site

for different kinds of informations.

Handle your Symfony assets without WebpackEncoreBundle, ViteBundle or AssetMapper

Published at
1/8/2025
Categories
symfony
css
javascript
php
Author
abdounikarim
Categories
4 categories in total
symfony
open
css
open
javascript
open
php
open
Author
12 person written this
abdounikarim
open
Handle your Symfony assets without WebpackEncoreBundle, ViteBundle or AssetMapper

A little context

You actually need to handle assets in your Symfony application and you don't know how to do this ?

I'm gonna show you here one way, without using WebpackEncoreBundle, ViteBundle or AssetMapper.

However, this is not the best way to handle assets with Symfony, but maybe it's the easiest one.

So, why are you showing us this way ? 🤔

Because... sometimes, you can need to handle assets this way, for example:

  • you don't have many time and can't wait to learn AssetMapper
  • you are a young symfony developer and you don't want to spend too much time learning frontend tools like Webpack or Vite
  • you have a wonderful legacy project and need to migrate it step by step
  • you just have a few frontend assets and don't want to use a more robust solution

Create a Symfony project

Let's start by creating a fresh new Symfony project executing this command:

symfony new --webapp symfony-handle-assets
Enter fullscreen mode Exit fullscreen mode

If you don't have the Symfony CLI binary, you can install it from here.
But if you don't want, you can also create a Symfony project by using Composer.

Remove Symfony AssetMapper files

We're gonna start by... removing some files.
Yeah, actually we don't need the files installed for AssetMapper, so we're gonna delete them.
But before, start by removing these libraries:

composer remove symfony/asset-mapper symfony/ux-turbo symfony/stimulus-bundle
Enter fullscreen mode Exit fullscreen mode

Delete also the assets directory.
Congrats, you did it 🎉

Now, get back on our subject.💪

Our first Controller

Start the Symfony webserver by running:

symfony serve -d
Enter fullscreen mode Exit fullscreen mode

Create now a new Symfony Controller by using the Symfony MakerBundle with this shiny command:

./bin/console make:controller
Enter fullscreen mode Exit fullscreen mode

I named this controller FrontController, but you can name it whatever you want. I choose to not generate tests.
Thanks to the MakerBundle, we have this content:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

final class FrontController extends AbstractController{
    #[Route('/front', name: 'app_front')]
    public function index(): Response
    {
        return $this->render('front/index.html.twig', [
            'controller_name' => 'FrontController',
        ]);
    }
}
Enter fullscreen mode Exit fullscreen mode

We also have the associated file front/index.html.twig, in templates directory, with this content:

{% extends 'base.html.twig' %}

{% block title %}Hello FrontController!{% endblock %}

{% block body %}
<style>
    .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
    .example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
</style>

<div class="example-wrapper">
    <h1>Hello {{ controller_name }}! ✅</h1>

    This friendly message is coming from:
    <ul>
        <li>Your controller at <code>/Users/abdounikarim/Web/poc/poc-symfony-handle-assets/src/Controller/FrontController.php</code></li>
        <li>Your template at <code>/Users/abdounikarim/Web/poc/poc-symfony-handle-assets/templates/front/index.html.twig</code></li>
    </ul>
</div>
{% endblock %}
Enter fullscreen mode Exit fullscreen mode

Start by updating our FrontController to go on / and remove the controller_name variable, we are not gonna use it:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

final class FrontController extends AbstractController{
    #[Route('/', name: 'app_front')]
    public function index(): Response
    {
        return $this->render('front/index.html.twig');
    }
}
Enter fullscreen mode Exit fullscreen mode

Update also the associated template content, here front/index.html.twig:

{% extends 'base.html.twig' %}

{% block title %}Hello FrontController!{% endblock %}

{% block body %}
<style>
    .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
    .example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
</style>

<div class="example-wrapper">
    <h1>Hello from Symfony without WebpackEncoreBundle, ViteBundle or AssetMapper ! 👋</h1>

    This friendly message is coming from:
    <ul>
        <li>Your controller at <code>/Users/abdounikarim/Web/poc/poc-symfony-handle-assets/src/Controller/FrontController.php</code></li>
        <li>Your template at <code>/Users/abdounikarim/Web/poc/poc-symfony-handle-assets/templates/front/index.html.twig</code></li>
    </ul>
</div>
{% endblock %}
Enter fullscreen mode Exit fullscreen mode

The controller_name variable has been removed and the h1 tag has been updated.

Handle our assets

Get back to work, create now a app.css file in the css directory (create also this directory in the public existing one) with this content:

body{
    color: #F5F5F5;
    background-color: #999999;
}
Enter fullscreen mode Exit fullscreen mode

I also added the link to this previous file on our base.html.twig template:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Welcome!{% endblock %}</title>
        <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
        {% block stylesheets %}
            <link href="{{ asset('css/app.css') }}" type="text/css">
        {% endblock %}

        {% block javascripts %}
        {% endblock %}
    </head>
    <body>
        {% block body %}{% endblock %}
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Do the same by creating a JavaScript file, I called it app.js and add it in a js directory in public with this wonderful content:

console.log('Hello Symfony from our JavaScript file!🚀');
Enter fullscreen mode Exit fullscreen mode

Here, a simple console.log, but you can put here what you want. Don't forget to add the link in the base.html.twig template:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Welcome!{% endblock %}</title>
        <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
        {% block stylesheets %}
            <link rel="stylesheet" href="{{ asset('css/app.css') }}" type="text/css">
        {% endblock %}

        {% block javascripts %}
            <script src="{{ asset('js/app.js') }}"></script>
        {% endblock %}
    </head>
    <body>
        {% block body %}{% endblock %}
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

If you try to access to your homepage, you should have a wonderful ugly design 🤮

Symfony handle assets - design base

Here, we just add CSS and JavaScript files on our base.html.twig template. It means that these files are gonna be used in all of our application, you can put in here all of your common application code.

Yeah, but if I want to have CSS and JavaScript files which contains only code used in specific page, how can I do this ?

Follow the guide 😅

Start by creating a new index.css file, in our css directory(in public) :

ul{
    list-style-type: none;
}
code{
    color: #FFFFFF;
    background-color: #000000 !important;
}
Enter fullscreen mode Exit fullscreen mode

Nothing special here, just a boring CSS code, free to you to add your own code.

Open now your index.html.twig template, and override the stylesheets block and add a link to our fresh CSS file:

{% extends 'base.html.twig' %}

{% block title %}Hello FrontController!{% endblock %}

{% block stylesheets %}
    <link rel="stylesheet" href="{{ asset('css/index.css') }}" type="text/css">
{% endblock %}

{% block body %}
<style>
    .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
    .example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
</style>

<div class="example-wrapper">
    <h1>Hello from Symfony without WebpackEncoreBundle, ViteBundle or AssetMapper!👋</h1>

    This friendly message is coming from:
    <ul>
        <li>Your controller at <code>/Users/abdounikarim/Web/poc/poc-symfony-handle-assets/src/Controller/FrontController.php</code></li>
        <li>Your template at <code>/Users/abdounikarim/Web/poc/poc-symfony-handle-assets/templates/front/index.html.twig</code></li>
    </ul>
</div>
{% endblock %}
Enter fullscreen mode Exit fullscreen mode

Refresh your browser page, and... we broke our wonderful design 😭.

Symfony handle assets - design index

How can we do now, we lost the previous style ? Are you kidding us ? 😠

Don't panic, there is a simple way to get back the parent style, you just have to use the {{ parent() }} function:

{% extends 'base.html.twig' %}

{% block title %}Hello FrontController!{% endblock %}

{% block stylesheets %}
    {{ parent() }}
    <link rel="stylesheet" href="{{ asset('css/index.css') }}" type="text/css">
{% endblock %}

{% block body %}
<style>
    .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
    .example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
</style>

<div class="example-wrapper">
    <h1>Hello from Symfony without WebpackEncoreBundle, ViteBundle or AssetMapper!👋</h1>

    This friendly message is coming from:
    <ul>
        <li>Your controller at <code>/Users/abdounikarim/Web/poc/poc-symfony-handle-assets/src/Controller/FrontController.php</code></li>
        <li>Your template at <code>/Users/abdounikarim/Web/poc/poc-symfony-handle-assets/templates/front/index.html.twig</code></li>
    </ul>
</div>
{% endblock %}
Enter fullscreen mode Exit fullscreen mode

Try again to refresh your browser page, the design must be almost the same as before, but don't dream, it's still wonderfully ugly.😅

Symfony handle assets - design index - add parent

Do the same for JavaScript now, create an index.js file in the js directory(in public):

console.log('Hello Symfony from our index.js file!🚀');
Enter fullscreen mode Exit fullscreen mode

Don't forget to add the link in the index.html.twig template:

{% extends 'base.html.twig' %}

{% block title %}Hello FrontController!{% endblock %}

{% block stylesheets %}
    {{ parent() }}
    <link rel="stylesheet" href="{{ asset('css/index.css') }}" type="text/css">
{% endblock %}

{% block body %}
<style>
    .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
    .example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
</style>

<div class="example-wrapper">
    <h1>Hello from Symfony without WebpackEncoreBundle, ViteBundle or AssetMapper!👋</h1>

    This friendly message is coming from:
    <ul>
        <li>Your controller at <code>/Users/abdounikarim/Web/poc/poc-symfony-handle-assets/src/Controller/FrontController.php</code></li>
        <li>Your template at <code>/Users/abdounikarim/Web/poc/poc-symfony-handle-assets/templates/front/index.html.twig</code></li>
    </ul>
</div>
{% endblock %}

{% block javascripts %}
    {{ parent() }}
    <script src="{{ asset('js/index.js') }}"></script>
{% endblock %}
Enter fullscreen mode Exit fullscreen mode

You see, we can handle assets easily with our Symfony application 😉

Again, it's not the best way to do this, but... you now the drill.

And... please, don't ever deliver a project with a terrible design like this. And if you do it, whatever is the situation, never talk about this article 🤐

Happy coding 😀

symfony Article's
30 articles in total
Favicon
From Legacy to Modern: Creating Self-Testable APIs for Seamless Integration
Favicon
Symfony Station Communiqué — 10 January 2025 — A look at Symfony, Drupal, PHP, and other programming news!
Favicon
Symfony Station Communiqué — 03 January 2025 — A look at Symfony, Drupal, PHP, and other programming news!
Favicon
Exploring PHP Frameworks: In-Depth Comparison of Laravel, Symfony, and CodeIgniter
Favicon
WebForms Core Technology in PHP
Favicon
symfony
Favicon
Best PHP, Laravel, and Symfony conferences to attend in 2025
Favicon
PHP Frameworks: hidden errors to avoid
Favicon
Handle your Symfony assets without WebpackEncoreBundle, ViteBundle or AssetMapper
Favicon
Hello from Symfony
Favicon
Symfony Station Communiqué — 27 December 2024 — A look at Symfony, Drupal, PHP, and other programming news!
Favicon
Build a Symfony 7 boilerplate using FrankenPHP, Docker, PostgreSQL and php 8.4
Favicon
SymfonyCon Vienna 2024: Recap of our Experience
Favicon
Using Memcache for Session Storage in Legacy Symfony 1.4/1.5 Projects
Favicon
Doctrine’s Collection filter method - a double-edged sword
Favicon
5 Ways to Optimize Symfony Application Performance
Favicon
Symfony Station Communiqué — 06 December 2024 — A look at Symfony, Drupal, PHP, and other programming news!
Favicon
Symfony monitoring library implementation
Favicon
Symfony Station Communiqué - 29 November 2024. A look at Symfony, Drupal, PHP, and programming news!
Favicon
How To Handle Custom S/DQL Queries On Different Database Engine with DoctrineExpression
Favicon
Symfony Station Communiqué — 15 November 2024. A look at Symfony, Drupal, PHP, and programming news!
Favicon
Another Way to Structure your Symfony Project
Favicon
Automate Symfony EventSubscriberInterface::getSubscribedEvents()
Favicon
Using Symfony’s HeaderBag as a Service: A Debugging Superpower in API Contexts
Favicon
Creating focused domain applications. A Symfony approach (Saving the entity)
Favicon
Symfony Station Communiqué — 11 October 2024. A look at Symfony, Drupal, PHP, and Programming News!
Favicon
Symfony Station Communiqué — 08 November 2024. A look at Symfony, Drupal, PHP, and programming news!
Favicon
Introducing PHP Env Manager: Simplify Environment Management in PHP Applications
Favicon
Creating focused domain applications. A Symfony approach (Returning the result)
Favicon
That Strange PHP Code in Frameworks and CMSs

Featured ones: