Pretty Laravel x Tailwind emails

14 Dec 2023

Hello again. This tutorial will guide you through creating visually appealing emails for Laravel applications using Tailwind. This work is based on the insightful post by Ralph J. Smit (https://ralphjsmit.com/laravel-emails-tailwind-css), which has been immensely helpful. In this post, I aim to provide a comprehensive guide on how to use Tailwind with Laravel emails. I’ll address two challenges that I encountered: using Vite instead of Webpack, and working with non-SMTP transports, such as Resend.

The process includes the following steps:

  • Create the necessary Tailwind and Vite configurations
  • Build our email views and classes
  • Use an updated CSS inliner that is compatible with all transports

Tailwind Configurations

First, create a separate Tailwind configuration file. For instance, you can name it mailwind.css. Place this file in the root of your Laravel repository.

const defaultTheme = require("tailwindcss/defaultTheme");

module.exports = {
    content: ["./resources/views/emails/**/*.blade.php"],
    theme: {
        screens: {
            xxs: "375px",
            xs: "475px",
        fontFamily: {
            sans: ['"DM Sans"', "system-ui"],
            filament: ["DM Sans", ...defaultTheme.fontFamily.sans],
            serif: ["Georgia", "ui-serif"],
            display: ['"PP Eiko"', "system-ui"],
            mono: ["JetBrains Mono", "monospace"],

Next, create a new CSS file for our emails. Place it at resources/css/mail.css:

@config "../../mailwind.config.js";

@tailwind utilities;

Two important points to note: Firstly, we’re using the @config directive to direct Tailwind to our new configuration. Secondly, we’re only using the utilities to generate our utility classes. We don’t need the base and components typically found in a Tailwind CSS file, as the inliner we’ll use later can struggle to handle them.

Finally, update your vite.config.js to inform it about our new CSS file:

import { defineConfig } from "vite";
import laravel, { refreshPaths } from "laravel-vite-plugin";

export default defineConfig({
    plugins: [
            input: [
            refresh: [...refreshPaths, "app/Livewire/**"],

Laravel Email

With Artisan, we can create a new email and assign its content to a new view that we’ll create.

php artisan make:mail MyEmail
// app/Mail/MyEmail.php

public function content(): Content
    return new Content(
        view: 'emails.my-email',

Create the view in resources/views/emails/my-email.blade.php. You’re welcome to use regular Blade features here, including layouts which are particularly useful when handling multiple emails.

use Illuminate\Support\Facades\Vite;

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        {!! Vite::content('resources/css/mail.css') !!}

    @if($subject = $attributes->get('subject'))
    <title>{{ $subject }}</title>

    <div class="w-full h-full p-4 m-4 border">


The {!! Vite::content('resources/css/mail.css') !!} is used for outputting our compiled CSS into the style tag that will be inlined next.


Due to the varied behavior of email clients compared to web browsers, we need to inline styles. For instance, w-full should be replaced with width: 100% for each element that uses it. Don’t fret, it’s simpler than it sounds with the help of laravel-mail-css-inliner. However, as of writing, this doesn’t work with every transport. For instance, it wouldn’t work in production when used with Resend. But there’s no need to worry, you can use my fork of the project which resolves this issue.

Begin by adding the following to your composer.json file:

"repositories": [
        "type": "vcs",
        "url": "https://github.com/jamiedavenport/laravel-mail-css-inliner.git"

To download and install the package, run the command composer require "fedeisas/laravel-mail-css-inliner @dev".


That’s all for now, but not quite everything. You still need to set up and send your emails. For those steps, I suggest referring to the Laravel documentation. Once you’ve done that, your emails will be beautifully formatted with Tailwind.

Follow up reading:

Until next time ✌️