Using Tailwind CSS with Symfony Encore
Tags: tailwindcss, symfony, webpack, guide
Published: 2022-08-01 08:45:42

## Why Tailwind CSS?

If you are reading this, you are probably in the same situation as me i.e. you can do backend development without breaking a sweat, but when you try your hand at some front-end development, it ends up looking like a throwback to 1994.   

I've tried bootstrap and various themes, and whilst they help, they tend to focus on a handful of specific page templates and deviating from them leaves me in the same situation as before.

Tailwind, on the other hand, has a collection of components that you can piece together, any way you want, to build up your own templates and spans everything from marketing pages to an e-commerce store and checkout pages to application UI, meaning you can get your product up and running with a beautiful looking front-end with little effort and leaving you more time to do the stuff you are good at.

The downside is you need to pay for the components - currently £219 + VAT, but in my view, it is well worth it as it includes

- All the components to build your marketing, application or e-commerce sites
- Lifetime membership - free updates forever
- Unlimited projects - no need to purchase for each project
- Pre-made templates using Tailwind CSS ready to use - this is something they have just recently added.

I've spent much more than that over the years on templates that I've never quite managed to get working, whilst my first attempt at a project using Tailwind (https://passwordangel.co) had the front-end up and running inside an hour.

You can see all the available components and templates on the Tailwind UI site - https://tailwindui.com/

So without further ado, let's get stuck into getting Tailwind CSS up and running in your Symfony project.

## Setup

#### Install Symfony
In this example, I'm going to set up a webapp symfony project because I want all the typical components for a web application (twig, routing, etc)

```bash
symfony new --webapp symfony-tailwind-demo
cd symfony-tailwind-demo
composer update
```

I'm also going to need the Symfony Webpack Encore bundle to provide the frontend integration.

```bash
composer require symfony/webpack-encore-bundle
```

#### Install node modules
These are the node modules that are required by the Encore bundle to provider the frontend functionality and the tailwind module to help build the CSS require for the templates that you build.

```bash
yarn add --dev \
    @hotwired/stimulus core-js \
    @symfony/stimulus-bridge \
    @symfony/webpack-encore \
    autoprefixer \
    postcss \
    postcss-loader \
    tailwindcss \
    webpack-notifier@^1.6.0 
```

And now initialise tailwind so it creates your `tailwind.config.js` and `postcss.config.js` files

```bash
yarn tailwindcss init -p
```

#### Configuration

We need to specify which files to watch for changes in the `/tailwind.config.js` file.  In our case,  we want to watch for changes to any of the twig template files 

```javascript
// tailwind.config.js
module.exports = {
  content: [
      "./templates/**/*.twig"
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

We also need to enable the post CSS loader in the `webpack.config.js` so it can resolve the tailwind CSS directives (we will get to that in a minute) into the desired CSS.

```javascript
// webpack.config.js
Encore
    // directory where compiled assets will be stored
    .setOutputPath('public/build/')

   // ... rest of the default configuration ...

    // Add this line to enable the post CSS loader
    .enablePostCssLoader()
;

module.exports = Encore.getWebpackConfig();
```

## Creating our first page using Tailwind CSS

Now that we have got the setup done and out the way, we can start to build our first page.  Lets start by adding the tailwind CSS directives to our CSS file

```css
/* /assets/styles/app.css */

@tailwind base;
@tailwind components;
@tailwind utilities;
```

and then adding the `encore_entry_link_tags` and `encore_entry_script_tags` twig functions to our base template so encore can load in the CSS and javascript

```twig
{# templates/base.html.twig #}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">

        {% block stylesheets %}
            {{ encore_entry_link_tags('app') }}
        {% endblock %}

        {% block javascripts %}
            {{ encore_entry_script_tags('app') }}
        {% endblock %}
    </head>
    <body>
        {% block body %}{% endblock %}
    </body>
</html>

```

Next, we want to add a routing file so we've got an entry point into the application

```yaml
# config/routes.yaml
index:
    path: /
    controller: App\Controller\DefaultController::index

```

and then the corresponding controller

```php
<?php

// src/Controller/DefaultController.php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class DefaultController extends AbstractController
{
    /**
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function index()
    {
        return $this->render('default/index.html.twig', []);
    }
}
```

And now the view template.  Lets take a component from the preview section from https://tailwindui.com/preview.  In this case I'm going to use "Ecommerce -> Components -> Promo Sections -> With image tiles"

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

{% block body %}
  <!-- This example requires Tailwind CSS v2.0+ -->
  <div class="relative bg-white overflow-hidden">
    <div class="pt-16 pb-80 sm:pt-24 sm:pb-40 lg:pt-40 lg:pb-48">
      <div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 sm:static">
        <div class="sm:max-w-lg">
          <h1 class="text-4xl font font-extrabold tracking-tight text-gray-900 sm:text-6xl">Summer styles are finally here</h1>
          <p class="mt-4 text-xl text-gray-500">This year, our new summer collection will shelter you from the harsh elements of a world that doesn't care if you live or die.</p>
        </div>
        <div>
          <div class="mt-10">
            <!-- Decorative image grid -->
            <div aria-hidden="true" class="pointer-events-none lg:absolute lg:inset-y-0 lg:max-w-7xl lg:mx-auto lg:w-full">
              <div class="absolute transform sm:left-1/2 sm:top-0 sm:translate-x-8 lg:left-1/2 lg:top-1/2 lg:-translate-y-1/2 lg:translate-x-8">
                <div class="flex items-center space-x-6 lg:space-x-8">
                  <div class="flex-shrink-0 grid grid-cols-1 gap-y-6 lg:gap-y-8">
                    <div class="w-44 h-64 rounded-lg overflow-hidden sm:opacity-0 lg:opacity-100">
                      <img src="https://tailwindui.com/img/ecommerce-images/home-page-03-hero-image-tile-01.jpg" alt="" class="w-full h-full object-center object-cover">
                    </div>
                    <div class="w-44 h-64 rounded-lg overflow-hidden">
                      <img src="https://tailwindui.com/img/ecommerce-images/home-page-03-hero-image-tile-02.jpg" alt="" class="w-full h-full object-center object-cover">
                    </div>
                  </div>
                  <div class="flex-shrink-0 grid grid-cols-1 gap-y-6 lg:gap-y-8">
                    <div class="w-44 h-64 rounded-lg overflow-hidden">
                      <img src="https://tailwindui.com/img/ecommerce-images/home-page-03-hero-image-tile-03.jpg" alt="" class="w-full h-full object-center object-cover">
                    </div>
                    <div class="w-44 h-64 rounded-lg overflow-hidden">
                      <img src="https://tailwindui.com/img/ecommerce-images/home-page-03-hero-image-tile-04.jpg" alt="" class="w-full h-full object-center object-cover">
                    </div>
                    <div class="w-44 h-64 rounded-lg overflow-hidden">
                      <img src="https://tailwindui.com/img/ecommerce-images/home-page-03-hero-image-tile-05.jpg" alt="" class="w-full h-full object-center object-cover">
                    </div>
                  </div>
                  <div class="flex-shrink-0 grid grid-cols-1 gap-y-6 lg:gap-y-8">
                    <div class="w-44 h-64 rounded-lg overflow-hidden">
                      <img src="https://tailwindui.com/img/ecommerce-images/home-page-03-hero-image-tile-06.jpg" alt="" class="w-full h-full object-center object-cover">
                    </div>
                    <div class="w-44 h-64 rounded-lg overflow-hidden">
                      <img src="https://tailwindui.com/img/ecommerce-images/home-page-03-hero-image-tile-07.jpg" alt="" class="w-full h-full object-center object-cover">
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <a href="#" class="inline-block text-center bg-indigo-600 border border-transparent rounded-md py-3 px-8 font-medium text-white hover:bg-indigo-700">Shop Collection</a>
          </div>
        </div>
      </div>
    </div>
  </div>
{% endblock %}
```
Everything should now be in place and you can set encore running and watching for changes by running this in a terminal window.

```bash
yarn encore dev --watch
```

While this is running, you can modify any of the CSS classes in the above template i.e. change `text-4xl` to `text-6xl` and you should see notifications on the CSS being rebuilt in the terminal window.

## Viewing your first page
We need to actually see the page to verify it is working as we expect.  For simplicity, I'm going to use PHP's built-in webserver in this example so we can run, in another terminal window

```bash
cd public
php -S localhost:8080
```

And now we can open our favorite browser and go to `http://localhost:8080` and see the result.  It should look something like this

![Symfony project using TailwindCSS ](https://chrisshennan.com/uploads/blog/tailwind-and-symfony.png)

## Try before you buy
So you can see this in action and experiment for yourself, I've created a git repository with the step of this blog post already completed so you can simply `git clone` and install the dependencies and away you go.  

Git repository: https://github.com/chrisshennan/symfony-and-tailwindcss-example

## References
- Get started with Tailwind CSS - Installation - https://tailwindcss.com/docs/installation
- Install Tailwind CSS with Laravel - https://tailwindcss.com/docs/guides/laravel
- Tailwind UI - Official Tailwind CSS Components & Templates - https://tailwindui.com/

Originally published at [https://chrisshennan.com/blog/using-tailwindcss-with-symfony-encore](https://chrisshennan.com/blog/using-tailwindcss-with-symfony-encore)