This episode is for members only

Sign up to access "Crop and Upload Profile Photos with Livewire" right now.

Get started
Already a member? Sign in to continue
05. Setting up Cropper.js


Now that we have our modal open with our image,
we want to initialize some sort of cropping library that we can use to crop our image. And for this, we're going to go ahead and use cropper.js. It's probably the best option at the moment to do this
and get the feedback that we need, like the region that's been cropped. So we can pass that through to our back end, crop it, and store it.
OK, so let's go ahead and get cropper installed. Let's go over to our code and just pull this in with npm. So let's do an npm install on cropper.js and just wait for that to finish.
And now that's done, let's come over to our app.js file and we'll go ahead and pull this in. So let's import cropper from cropper.js. Let's go and import the CSS for this as well
so we actually get the styling. This can go directly into our JavaScript file and be built up. So this is in cropper.js source,
and then of course, CSS, and it is cropper.js.css, and we are done. Now, the next thing we want to do is go ahead and add this to our window object
so we can access it really easily, and that is pretty much it. We now have cropper on the page ready to go. Now, it looks like there's an error here,
so let's just have a look at what we've got. And I think it's just cropper.css. Yeah, there we go, great. So cropper's on the page.
Let's go and actually initialize this within our modal component. Now, for this, we're going to go ahead and use alpine.js, which is already bundled in with Livewire.
So we're going to go ahead and initialize this component with xdata, and we're going to store an instance of that cropper inside of xdata, but when we initialize this component,
we're going to go ahead and set it up. So let's go ahead and set cropper here to a new cropper instance, and we need to figure out where this image actually lives now.
So this is going to be the element that we want to target and crop. At the moment, we just have an image in here, which is absolutely fine.
I'm going to go ahead and wrap this in a div. I think that's required for cropper.js, and in here, we're going to set this to a ref and give it a name.
So let's just call this image. What that means is that up here, when we initialize this to target the element, we can just say refs and image.
That will go ahead and target this, and it will turn that into a cropper instance. Great. The next thing we want to do is pass in a bunch of options.
So we're going to set the autocrop area to one. You can check the documentation for these. We're going to set the view mode to one, just all pretty standard config,
and we're going to set the aspect ratio here to one, one, just so it's a nice square, but of course, feel free to play around with these and check the documentation out.
Okay, let's go ahead and run this and see what happens. So let's go and bring up our consult just in case we have any issues, and we're going to go ahead and choose that photo,
launch that modal, and let's just try that one more time because we've got a refresh, and okay, great. So unexpected, yeah, let's just have a look here, and yeah, I've put this in an object,
and that doesn't need to be. It's just a initialization script. Let's try that again, and there we go. So we have our cropper up and running,
but it looks a little bit strange at the moment. Now, the way that cropper.js works is it takes the size to determine where this needs to actually insert it. Now, the problem we've got at the moment
is that our modal is opening, and we're initializing this immediately, and that means that the sizing is a little bit off. So to counteract this, what we're going to do
is use next tick within Alpine to wait for the next render, and then go ahead and initialize our cropper. So let's go down here and put all of this inside of next tick and just wait for everything to be rendered
before we go ahead and initialize this, and then cropper will know which space it needs to contain. While we're here, we'll also go ahead and set the width of the image to full
to make sure it pulls the entire width, and we'll set a max width of full as well. Okay, let's go over and just try this again. So let's choose a photo, and there we go.
That looks a lot better. So just go ahead and close off our console, and you can see that we can just about, we'll change the padding in a minute,
just about go ahead and grab that and start to crop this, brilliant. Okay, so let's go ahead and just finish up by styling out the outer container of this
just to make it fit a little bit better, and for this, I think I'll just put a padding of 10 in there. It doesn't really matter what we do. Okay, let's go ahead and choose another photo here,
and yeah, there we go. We've got a little bit of padding, and now it's super easy to crop. So that's cropper.js installed,
getting around a couple of the render issues with Nextick. Now what we can do is listen to the crop event to determine what size we need to pass back to our profile photo field.
10 episodes 43 mins


Using Livewire, Alpine and Cropper.js (or any cropping library), we’ll create an embeddable form field for users (or any other model) to upload profile photos.

The form element will launch a modal, where users can crop and adjust their profile photo, before being able to preview and save the cropped image — or clear everything out and start again.

You’ll learn:

  • How to launch modals in Livewire
  • How to use Cropper.js with Alpine
  • How to resize images on the backend with the spatie/image package
  • How to pass data between Livewire components
Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!


No comments, yet. Be the first to leave a comment.