Creating a Statamic site helper for Laravel Mix

July 31st, 2019

Laravel Mix isn’t provided by default in Statamic v2, in this short post I’ll show you how to create a quick site helper to read the mix-manifest.json and output versioned assets.

First things first: add Laravel Mix to your Statamic project

We’ll start off by creating a webpack.mix.js file in the root of our project. This post assumes you’re using Statamic’s default config of having all its files in the webroot.

const mix = require('laravel-mix');

mix
  .js('resources/js/site.js', 'assets/js')
  .postCss('resources/css/site.css', 'assets/css')

To keep it simple, we use the Laravel Mix convention of storing our pre-compiled assets in a resources folder, we’re compiling to an assets folder in the root of our project. Make sure you’ve followed the necessary installation instructions of Laravel Mix.

Add a Tags helper for your site

Run php please make:tags-helper to add a Tags.php file to your project. Next we’ll add the necessary mix function to generate versioned asset links. The code should be pretty self-explanatory.

<?php

namespace Statamic\SiteHelpers;

use Exception;
use Illuminate\Support\Str;
use Statamic\Extend\Tags as AbstractTags;

class Tags extends AbstractTags
{
    public function mix()
    {
        $manifest = STATAMIC_ROOT.'/mix-manifest.json'; // Where the manifest is stored

        if (! file_exists($manifest)) {
            throw new Exception("Could not find {$manifest}");
        }

        $path = $this->getParam('url'); // Which asset file we're trying to find
        if (!Str::startsWith($path, '/')) {
            $path = "/{$path}"; // Make sure there's a leading slash
        }

        $manifest = json_decode(file_get_contents($manifest), true); // Get the manifest contents

        if (! isset($manifest[$path])) {
            throw new Exception("{$path} not found in mix-manifest.");
        }

        return $manifest[$path]; // Return the versioned url
    }
}

If your manifest file is stored somewhere else, you can always just edit the first line to make sure the tag finds the correct file.

Once this Tag helper is created, you can use it in your templates with the following code:

<link rel="stylesheet" href="{{ site:mix url="/assets/css/site.css" }}">
<script src="{{ site:mix url="/assets/js/site.js" }}" defer></script>

And the helper will output the versioned asset links.

If you would rather use an add-on, which is easier to reuse on every project, the Statamic marketplace has both Laravel Mix and Statamic Mix to solve this problem for you.

MENU