I recently needed to add a simple tag editor to a form input. I initially thought that Vue might help with this. That was a big mistake! Vue is seemingly pretty hopeless for this kind of thing – you can’t really use it for “sprinkling” JS elements, and progressive enhancement is a complete non-starter; that’s really more the domain of old-school jQuery, though I hear good things about alpine.js for this kind of enhancement. I learned a lot about Vue that I hadn’t planned on doing, but the overall impression was that it was simply the wrong tool for the job. I am not interested in building an SPA, and I’m certainly not out to rebuild my entire site just for sake of a single widget! My analogy for Laravel and Vue is like oil and vinegar in a salad dressing; they will happily coexist in the same bottle and taste great together, but they really like to be separate.
So, back to jQuery I go. jQuery was disabled by default in Laravel 6, but it’s just commented out in resources/js/bootstrap.js
. It’s already included in the npm packages.json
config file, so running npm install
loads it into node_modules
. I was really unclear about how additional JS modules should be added to Laravel using Mix. This was also a bit confusing because there isn’t really much you can point at and say “that’s mix”; it really comes down to what you put in webpack.mix
.js in the project root and the npm run dev
script that builds assets. However, the main thing that this does is load app.js
, but then I found that things like this should be added in bootstrap.js
(which is loaded by app.js
) rather than adding them to the the mix config.
So the aim of the exercise was to add a tagging UI widget that takes a standard text input full of comma-delimited terms, and turns it into a pretty clickable tag element. Out of many worthy options, I settled on Tagify. After adding it with npm i @yaireo/tagify --save
I had trouble figuring out where to actually load it from, but eventually I got it working by adding:
require('@yaireo/tagify/dist/jQuery.tagify.min.js');
to my bootstrap.js
file, and evidently this looks in node_modules/
to find the file without any additional help. After this I created a script in public/js/editthing.js
(because inline scripts are worth avoiding if you’re serious about your CSP) that turned the standard input into a tag widget:
$('#tags').tagify();
and this script was loaded from blade using Laravel’s asset
helper, which creates appropriate base URLs for public resources:
<script src="{{ asset('js/editthing.js') }}"></script>
I sometimes find Laravel docs and articles infuriating – there is often both too much and too little information at the same time, or they say things like “just add it to mix”. Many articles on simple subjects like this subvert Laravel’s features to shortcut to “working” (but ultimately counterproductive) solutions, and I wanted to approach this “the Laravel way”. For that reason I thought I’d make detailed notes for these very simple steps that I couldn’t find written down together elsewhere!
HTH