Laravel 8 + Jetstream 2 + Livewire + Mix + NPM + Datatables

A post for Google’s crawler as this took me far too long to get working and the many many many Google hits on the topic all proved mostly unhelpful.

On a simple Laravel + Jetstream (Livewire version) installation, I needed DataTables to work. This also means jQuery needs to be installed.

What follows are the various changes to the default files to make this work:

package.json (versions as at Jan 2022, run npm install after updating file):

    "devDependencies": {
        ...
        "datatables.net-dt": "^1.11.3",
        "jquery": "^3.4.1",
        ...

webpack.mix.js – Alpine.js has an idiosyncrasy which causes issues for jQuery – it is loaded via <script src="" defer> – emphasis on the defer. This means that jQuery won’t be available for your scripts within the Blade templates and, specifically, $(document).ready() will throw an exception because the jQuery function, $, will not be defined as yet. To solve this, we create a second new js file by adding the following line:

mix.js( "resources/js/alpine.js", "public/js" )

resources/js/app.js – we need to remove the Alpine.js lines from here and place them in a new file, resources/js/alpine.js. Specifically – move the following lines:

import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.start();

resources/js/bootstrap.js – I added the following bolded lines:

window._ = require('lodash');

/**
 * We'll load jQuery and the Bootstrap jQuery plugin which provides
 * support for JavaScript based Bootstrap features such as modals 
 * and tabs. This code may be modified to fit the specific needs of
 * your application.
 */

window.$ = window.jQuery = require('jquery');


// Datatables
window.DataTable = require('datatables.net-dt');

...

Lastly, edit the template to not defer app.js and to load your new alpine.js file. In resources/views/layouts/app.blade.php, remove the script line for app.js and replace it with the following two lines:

<script src="{{ mix('js/app.js') }}"></script>
<script src="{{ mix('js/alpine.js') }}" defer></script>

I think the biggest confusion here was that there were no changes required to webpack.mix.js specifically for DataTables despite many online resources making changes there. Perhaps it was earlier versions of Mix? The second confusing issue was Alpine.js and the effects of ‘defer’ring app.js.

With the above, DataTables (and jQuery) are now available as usual in your Blade templates:

<script>
    $(document).ready(function () {
        $('#clients-table').DataTable();
    });
</script>