Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Installing 3rd Party Code into our JS/CSS

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

We now have a nice new JavaScript and CSS system that lives entirely inside of the assets/ directory. Let's move our public styles into this. Open public/styles/app.css, copy all of this, delete the entire directory... and then paste into the new app.css. Thanks to the encore_entry_link_tags() in base.html.twig, the new CSS is being included... and we don't need the old link tag anymore.

Go check it out. Refresh and... it still looks great!

Installing 3rd Party JavaScript/CSS Libraries

Go back to base.html.twig. What about these external link tags for bootstrap and FontAwesome? Well, you can totally keeps these CDN links. But we can also process this stuff through Encore. How? By installing Bootstrap and FontAwesome as vendor libraries and importing them.

Remove all of these link tags... and then refresh. Yikes! It's back to looking like I designed this site. Let's... first re-add bootstrap. Find your terminal. Since the watch command is running, open a new terminal tab and then run:

yarn add bootstrap --dev

This does three things. First, it adds bootstrap to our package.json file. Second it downloads bootstrap into our node_modules/ directory... you would find it down here. And third, it updated the yarn.lock file with the exact version of bootstrap that it just downloaded.

If we stopped now... this wouldn't make any difference! We downloaded bootstrap - yay - but we're not using it.

To use it, we need to import it. Go into app.css. Just like in JavaScript files, we can import from inside CSS files by saying @import and then the file. We could reference a file in the same directory with ./other-file.css. Or, if you want to import something from the node_modules/ directory in CSS, there's a trick: a ~ and then the package name: bootstrap.

@import '~bootstrap';
... lines 2 - 34

That's it! As soon as we did that, Encore's watch function rebuilt our app.css file... which now includes Bootstrap! Watch: refresh the page and... we're back! So cool!

The two other things we're missing are FontAwesome and a specific Font. To add those, head back to the terminal and run:

yarn add @fontsource/roboto-condensed --dev

Full disclosure: I did some searching before recording so that I knew the names of all the packages we need. You can search for packages at https://npmjs.com.

Let's also add the last one we need:

yarn add @fortawesome/fontawesome-free --dev

Again, this downloaded the two libraries into our project... but doesn't automatically use them yet. Because those libraries both hold CSS files, go back to our app.css file and import them: @import '~' then @fortawesome/fontawesome-free. And @import '~@fontsource/roboto-condensed'.

@import '~bootstrap';
@import '~@fortawesome/fontawesome-free';
@import '~@fontsource/roboto-condensed';
... lines 5 - 34

The first package should fix this icon... and the second should cause the font to change on the whole page. Watch the font when we refresh... it did change! But, uh... the icons are still kind of broken.

Importing Specific Files from node_modules/

To be totally honest, I'm not sure why that doesn't work out-of-the box. But the fix is kind of interesting. Hold command on a Mac - or ctrl otherwise - and click this fontawesome-free string.

When you use this syntax, it goes into your node_modules/ directory, into @fortawesome/fontawesome-free... and then if you don't put any filename after this, there's a mechanism where this library tells Webpack which CSS file it should import. By default, it imports this fontawesome.css file. For some reason... that doesn't work. What we want is this all.css.

And we can import that by adding the path: /css/all.css. We don't need the minified file because Encore handles minifying for us.

@import '~bootstrap';
@import '~@fortawesome/fontawesome-free/css/all.css';
@import '~@fontsource/roboto-condensed';
... lines 5 - 34

And now... we're back!

The main reason I love Webpack Encore and this system is that it allows us to use proper imports. We can even organize our JavaScript into small files - putting classes or functions into each - and then import them when we need them. There's no more need for global variables.

Webpack also allows us to use more serious stuff like React or Vue: you can even see, in webpack.config.js, the methods to activate those.

But usually, I like using a delightful JavaScript library called Stimulus. And I want to tell you about it next.

Leave a comment!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=8.0.2",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "symfony/asset": "6.0.*", // v6.0.3
        "symfony/console": "6.0.*", // v6.0.3
        "symfony/dotenv": "6.0.*", // v6.0.3
        "symfony/flex": "^2", // v2.1.5
        "symfony/framework-bundle": "6.0.*", // v6.0.4
        "symfony/monolog-bundle": "^3.0", // v3.7.1
        "symfony/runtime": "6.0.*", // v6.0.3
        "symfony/twig-bundle": "6.0.*", // v6.0.3
        "symfony/ux-turbo": "^2.0", // v2.0.1
        "symfony/webpack-encore-bundle": "^1.13", // v1.13.2
        "symfony/yaml": "6.0.*", // v6.0.3
        "twig/extra-bundle": "^2.12|^3.0", // v3.3.8
        "twig/twig": "^2.12|^3.0" // v3.3.8
    },
    "require-dev": {
        "symfony/debug-bundle": "6.0.*", // v6.0.3
        "symfony/stopwatch": "6.0.*", // v6.0.3
        "symfony/web-profiler-bundle": "6.0.*" // v6.0.3
    }
}