What is Alpine.js?
Hey there gang and welcome to your very first Alpine JS tutorial. Okay then my friends, so first of all, I wanted to make this crash course about Alpine because I'm going to be using it in some of the future courses I will be making. And I want this course to serve as an entry point for developers completely new to Alpine JS before I make those other courses. Also, Alpine is actually kind of fun to use so regardless of whether you take those other courses in the future or not, I think you're going to enjoy this one.
So then what is Alpine JS and what makes it different from the 5,000 other JavaScript libraries and Frameworks already out there? Well to begin with, let's answer that first question, what is Alpine JS? And at its core, Alpine is a lightweight front-end library for building interactive and reactive interfaces, and it works directly within HTML files by adding simple declarative attributes to elements. For example, we could use the xon attribute to attach an event handler to an element like a click event, or we could use the x-model attribute to bind user input values to a variable so we can track them. So you can see a list of all of these different attributes on the Alpine homepage. There's only 15 in total, so it's pretty lean, but they all pretty much cover most kinds of interactions and reactivity you might need.
It actually says up here at the top that it's like jQuery for the modern web, which may split opinion because a lot of developers shudder at the word jQuery. But to me, Alpine feels much more like a really stripped-back and lightweight version of something like Vue.js that we can just drop directly into any HTML page without any kind of build setup. And that is the main difference between Alpine and other front-end libraries like React, View, and Svelte. It's much easier and simpler to get started. We just drop in the Alpine script tag and we're good to go. And with that in mind, Alpine's probably something you might consider using for smaller projects when you don't need all the overhead that comes with other libraries and Frameworks. But that's not to say you wouldn't use it on larger projects as well.
So then that's a very broad view of what Alpine is, and we'll obviously dive much deeper as we progress through the course.
Course Project Preview
And during this course, we're going to be using Alpine to make an interactive web form like this one right here. And within this form, we use Alpine to add a few different features, like the character counter for the username field, which goes red when you're nearing the maximum length, the password field where you can toggle between hiding and showing the password. We also use Alpine to validate the input fields when we submit the form and to dynamically inject errors into the template when there are some. And there's a few other things that we'll be using it for as well, like showing a modal and working with transitions.
Setup and Installation
But to begin with, let's head back to the Alpine site and see how we can get up and running with it. So let's click on this button to get started and then if we go to installation, we're going to see how we can do this. Now there's two ways to do it. We can use just a script tag or if you want to use npm and use Alpine as a module, you can do. We're going to do it the easy way and stick with the script tag right here. So this is the script we need, so just grab that and you want to copy it. And notice this thing right here, it says 3.x.x. Now when we use that, it will pull the latest version of Alpine version 3. Now for stability in production, it's recommended that you hard code the latest version in the CDN link like this. Now we're just going to grab the latest version because we're not in production, this is just a tutorial. So just grab this script right here and you want to copy that.
Now before we go to the code, there's one more thing I want to mention and that is that I've created course files for every single lesson in this series, and they're all on this GitHub repo right here: Alpine crash course. I will leave this link down below the video so if you want to see the lesson code for a specific lesson, you just need to select that lesson from the branch dropdown, for example, lesson seven, and you can see all the different files right here. So you can browse them or you can download a zip folder of this lesson by going to code and then downloading a zip.
Okay then, so I've already made an empty HTML page and all I need to do is paste that script tag into the head right here and we can start using Alpine in this document right away. That's how simple it is. Now before we go any further, I just want to mention that I've also hooked this page up to a CSS file called styles.css and that's so later in the course when we make a web form, it's going to look just a little bit nicer in the browser. But there's nothing special going on in there, it's just standard vanilla CSS.
First Example: Defining State and Outputting Data
Anyway, let's start with the most basic and simple example that we could possibly use: a counter, just to explain and explore the syntax and methodology behind Alpine. So then, I'm going to make a div tag right here and then inside that div tag, I'm going to make a paragraph tag which says something like, The current value of the count is: and then we need a colon at the end. And I want the count itself to be a dynamic value, right, that could potentially change over time or in reactions or something. And to do that, we can come to this div tag and we could use the Alpine directive called x-data and then we set it equal to something.
Now, when we use an Alpine directive like this one, the value itself can be a dynamic expression. In other words, it could be an object, a boolean, a number, a string, or even a function. And in contrast, when we use a regular HTML attribute, the value is always static. So for the value of this x-data directive, I can use an object. And inside this object, I can add key-value pairs. For example, I'm going to add a count property and I'm going to set that equal to 0 to begin with. And what this x-data directive does is allow us to use this defined data anywhere within this div tag now. So you can think of this as like a piece of state for this section of the HTML, or for this component if you like.
Now if I want to output this data within this bit of template, then I can do so by using another different Alpine directive, this time called x-text. So let me make a span tag at the end of this paragraph and I'm going to add on the x-text directive and I want to set this equal to whatever text I want to output within this span tag. In this case, that's the count property which we defined in the data directive. And again, this directive value is a dynamic expression right here. It's not the string 'count' that I'm outputting right here, but instead it refers to the count property that we created. If we wanted to output the string 'count', then we'd have to wrap this with single quotes to tell Alpine explicitly that this is the string value count that we want to output as the text. But we don't want to do that. We want to output the count property value instead. So then, because the count value is zero, that's what we should see output to the browser inside this span tag. So let's try it out. I'm going to right-click this file and choose "open with live server", which I can do because I've got the live server package installed in VS Code. All right, and now inside a browser I can see this value zero right here. Awesome. So that's working. That's how we can dynamically output some data to the browser.
Handling User Events with x-on
All right, so that's good, it's all working. But at the moment, nothing special is happening. We're just outputting a number to the browser. But when we use Alpine and the x-data directive like this to make some state, if you like, we can actually update that data in reaction to user events in the browser. For example, I want to make a button which when a user clicks it, increases the count value by one. So let's make that button first of all, and then inside that button we'll say something like 'Increase count by one'.
And now we need a way to react to a user clicking that button, which is really easy to do in Alpine. We can just use the x-on directive. And the x-on directive allows us to react to different browser events like a click event or a mouseover event or a keyup event or something else. The event we want to react to on this element is a click event, so we can add a colon after this and then type 'click'. Then we can set this equal to some function or expression that we want to run in reaction to the click event. In our case, we want to increase the count value by one, so we can just say count++ to do that.
And now whenever a user clicks on this button, it's going to update this count value defined in the x-data directive. And when that happens, Alpine also updates anywhere in the template that uses that value, so right here in the span tag in our case. And by the way, this x-on directive only works when it's nested somewhere within a parent element that uses the x-data directive. It doesn't need to be a direct parent, but it does need to be up there somewhere. All right, so then let's save this and give it a whirl. All right, so let's try this out. I'm going to click on this button right here, and yeah, we can see that count is going up every time we click on this. Awesome.
Expanding Component State
All right, so we've seen how to define and output data using this x-data directive and this x-text directive. And we've also seen how to react to user events using the x-on directive. And right now, we've already added a fair amount of interactivity and reactivity just by using a few different attributes, which is really cool. But this is still a very basic example and a lot of the time you might need to define more complex data or multiple properties. And you can do that pretty easily by just adding them up here and comma-separating them inside this object. For example, I could add a name property and I could set that equal to 'Mario', for example, and I could output that name value in the template now by just using the x-text directive like we did for the count. So let's quickly do that.
Let's add an h1 first of all that says 'Hi,' and then a comma. And then after that we'll also add another span tag for the name. So on that span tag we need to use the x-text directive to dynamically output some text and just set it equal to the name property. And now this whole title would say 'Hi, Mario'.
So we could follow this pattern for any additional data by just adding more and more properties to the data object right up here. Also we could add functions to the object too and then call those functions in reaction to events like the click event. However, if we carried on doing that, then this element is going to get really bloated and messy in the HTML. So for just a simple UI component like a counter, this approach is pretty good, but for more complex UI components that need a lot more data properties and possibly some functions as well, then there is a different approach that we can use that is, in my opinion, a little nicer.
And that is to define those data values in a custom script somewhere else and then just reference that custom data inside this x-data directive. So what I'm going to do is make a new JavaScript file over here called index.js and I'm just going to define the data within that file. We also need to link to this JavaScript file from the HTML file, below where we register the script for Alpine itself. So let me just do that right here first of all.
Now, the first thing we need to do inside this new JavaScript file is attach an event listener to the document object to make sure that Alpine is ready before we try to run any code. And to do that, we can say document.addEventListener right to attach an event listener to the document. And then the event name is called alpine:init. And this Alpine event fires as soon as Alpine is fully loaded and ready to start working. All right, so then we just need a callback function to run some code when this event occurs.
So inside this callback function, we can just register some Alpine data and we can do that by using the Alpine object, which we know is ready to use at this point. And then on that object we can use a method called data which we want to invoke. Now as a first argument to this method, we give this particular set of data a name. For example, I could call this counter. And this name is what we'd reference from the x-data directive in the HTML, which we're going to see later on. Anyway, we also need to pass a function as a second argument which returns an object. Now I'm placing the object inside parentheses because otherwise the curly braces would be the start and end of the function code block, not the object itself. But by wrapping them in parentheses we're saying we want to return an object from this function. And this object is now the same kind of object as we passed directly into the x-data directive before, and we can register key-value pairs inside it. So I'm going to make the count property and I'll set that equal to zero just like before. And I'm also going to make the name property as well, and I will set that equal to 'Mario' again, like before.
Okay, so now we've got the same two properties as we previously defined inside the object in the HTML file, but this time we've defined them away from the HTML in its own script. And now instead of keeping this data defined on the div tag, we can just reference the data we made using the name we gave to it, which was counter. All right, and that means when Alpine looks at this, it's going to search for a data object called counter, which it finds, and then it grabs all the data values from there instead. So this should now all work the same as it did before.
Adding Methods to Component Data
So then we can see the name, good, and we can see the count initial value is zero. And if we try to increase that, yep, everything still works. Awesome.
Now, just really quickly, I want to show you how we can also define functions inside this data object which we can invoke directly from within the template. So let's create a function called logCount inside the object. And the job of this function is just to log the count value to the console. So let's do that. I'm just going to say console.log and then we're going to log this.count. Now we need to say this to refer to the data object itself, and then we just use the count property on that. So now we've got this function, we can head back to the template and make another button which says something like, I don't know, 'Log the count' or something like that inside it. And then we'll attach a click event to this button using x-on, then a colon, and then click. And then we can set that equal to something.
Now this time, we're going to reference the function we just made, which is logCount, and we don't need to invoke that, we just reference the function name. And now when we click this button, Alpine looks for that function within the counter data object, and it finds it and it invokes it. So let's try this in the browser. I'm going to click on the first button a few times to increase the count first of all, and then I'm going to click on the second button which logs the current count value to the console. Awesome.
All right, so hopefully now you can see how easy it is to get up and running with Alpine, to define some data, and also how to change that data in reaction to things like click events.
Now in the next lesson, we're going to start to work on the course project by making a web form and hooking that up to a new data object. By the way, if you want instant access to the whole course now without YouTube adverts, you can do. You can get it from the netninja.dev website. I will leave this link down below. And it's just $2 to buy or if you want, you can sign up for a Net Ninja Pro subscription and that is $9 a month. Your first month is half price with this promo code right here and for that you get access to my entire course library including all the premium and masterclass courses as well. So again, I will leave this link down below the video and I'll see you in the very next one.
Outro
[Music] [Music] [Music]