Introduction to Payload CMS & Video Goal
hello and welcome to the channel. As you can see, back again we are going to go through another quick Payload CMS video. I have a couple that I've created the last couple of days, but just a quick refresher, Payload's an open source Next.js backend. Basically what it is, it's a full stack backend built on Next.js that is a CMS, but it also has the ability to build applications on top of it. It packages up your database, it has ways for you to create authentication, security against API calls in a database. All of this stuff is integrated, very little coding required to kind of get it going. Clearly you do need to understand React, some Next, but I think it's a pretty powerful platform. I'm kind of going through and learning things along the way and and finding some interesting things to do.
And so this is going to be a video on another interesting thing that I have stumbled into. So the idea here what we want to do in this video is quickly show how you can create a new screen or basically extend the admin UI to have a screen to create a new user. Right now the way the system works is that when the system starts up there's one admin. That admin creates an account and the admin is in. There's no other way to create a user unless you are the admin and the admin goes in and creates a user for you. I'm going to create a UI that will allow you to create a user inside the system and then be allowed to log in. All right?
Project Setup and Initial State
Let's just start quickly. Also, please make sure to like and subscribe, share with your friends. If there's other things you'd like to see being done with Payload, please drop a comment and I'll see what I can do. Thanks.
Okay, we're going to call this create-user-app and we'll use a blank template. We will select sqlite and we'll just use that as a connection string.
Oh okay, so our app finished creating. We switched directories and now we've opened up our app in Cursor. So let's go to Cursor. Um, actually let's just run this so that folks who aren't familiar can kind of see what we get when we first get started.
Okay, now let's go to localhost:3000. Okay, so this is what you get. If you see up at the top, it says Create First User. I'll create my first user and then now I'm in. Now the only other way to create a user once you get here is to click that and then click Create User. What we want is we want the user to be able to come to a URL up here and get to create a user.
Configuring a Custom Root View in payload.config.ts
So what we're going to do is we're going to follow this Root Views. What do we got this? Customizing Views, Create individual pages on the admin panel. We're going to focus specifically on our root view and this is the approach we're going to take. So let's open up our code and go to payload config because that's kind of where all the magic starts. And then we'll, we'll just follow the pattern that they have here. You can see that what they've done is they've added this component views underneath the admin. So we're going to come to admin and underneath here, components, and then views, and then here we will add our view.
For those who like to read, I have created a companion blog post that kind of walks through this whole thing. So this will get posted along with the video for you to kind of be able to check it out. And this is kind of what I'm also going to use as my reference since I've already did it once. I don't, you know, I can quickly just pull some code here, paste it and kind of document it. So we're here on The View configuration and what we need to do is we need to add this additional information underneath our views. So what we want is we're going to create a path called create-account that you're going to go to to create the account. And what we're going to do is we're going to do it with this component called CreateAccountView component. You need to specify the path of where the actual component is. Normally what I do is I usually either create a separate components directory or put it in with the collection that I'm working on. For now, just to keep things simple, actually no, I'll follow my same pattern. So source, source and we'll create a file here, components.
Creating the Basic View Component
Components. All right. So we have our file. We're following along with the pattern, this pattern here. And so you can see here, custom reviews option can use one of the templates. It provides a default template, provides a basic layout of navigation. So we're just going to use this because we're just trying to get the basic understanding of how it works.
So I'll just drop this in as my component. And let's see what do we got? Export. So remember if we go back to our config, that this is the name of my component. So I'm just gonna, just to stay consistent, I'm just going to copy this over, say export const, we'll just do this, and then we'll go down here, export default. All right. Oh, my bad. I have to name this... tsx. Okay, so we have our basic component in Create Account component. It's just going to say "custom default view" and then we're exporting it here and we go back to our payload config and you see I have the full path here. Um, let's see if this is working. So the path is create-account. So I'll go up here, go to admin... Okay and we get some errors. Oh let's see, let's just try a rebuild. Okay, so now we have our custom view showing right.
So the next thing is that because this is a server component and I'm going to do some UI stuff, I'm going to move, I'm going to put another component in here that'll handle all the UI stuff. So first let's put a header here, Create Account. So what we're going to do next is we're going to create our form here. So CreateAccountForm. And then just to keep our lives easy, we'll put it in the exact same directory. And in here, since it's, it's just a regular client component, so we're going to say use client. Let's just use a regular form now to show that it's working. So, div, create account form. And go back to localhost. Oh did I not import it? Let's import it. And so we have our form.
All right. The next thing that we want to do is we want to try and leverage Payload's UI. So we're going to say const... so we're going to get the TextInput and the Button from Payload and this needs to be changed to path, value and then onChange this value will be email and we're going to set our useState up here. So we want email and const password. We won't do a confirm password. We'll just leave that. TextInput, password, our event. And then we're going to do our setEmail and then we're going to do the same thing down here. We'll get our event and we're going to do setPassword. Let's get our imports. So let's update these imports appropriately to get our errors to go away. Let's add our import for useState and now let's see what our UI looks like. All right, so we have our email field and our password field. That's looking good so far.
Except the problem is our password is showing our password. So this is one of the things that caused me great pain and I had to hunt and peck. Like I would assume that on here there would be a PasswordInput but there is not. The PasswordInput was hidden and I had to search through the docs to find it. So hold on while I dig that up.
So this is where I found it and for someone who might know Payload better than me and can explain why, and explain why I have to go through this to get access to the password input, I'm very happy to learn because for me this is all just about learning stuff and I want to know like is there another way that I should be doing this? A lot of this for me is I'm putting this content out there. Hopefully someone who knows better than me can respond and say, "Hey Aaron, this is the way to do it," so I can learn and and move on from it.
Okay, so now let's take a look at our app again and we have our fields. Got some data, our password is hidden, and I got my button. All right.
Implementing the Create Account Logic
So what we're going to do is we're just going to handle, do an on click event, createAccountHandler. And so what we need to do here is we can just call the API endpoint to create the user and that'll just be a simple fetch. Let's just console log email and password to make sure we got them. We're going to do a fetch. Obviously it's not create-account, Cursor is trying to be helpful, but it's not being that helpful because it's not /api/create-account, it's /api/users and it's a post. And then we're going to stringify the body, send our response. We want to JSON our... jsonify, JSON our response to return it. But what we really want to do here is we want to say if response is okay, then we'll do it, otherwise fail to create an account. Actually let's just throw an alert, "failed to create an account".
If my account was successfully created, not only do I want to console log data, I want to navigate to the admin page because now I'm logged in. So to do that, I believe I need my useRouter. Yes, from next/navigation. And we will use our router up here at the top. And then down here I'm going to push to the default page and that should take me to the main console for the admin. Actually let's just say /admin/users, just take us to the admin users page. Okay, let's see if this was all it took and I actually have an account created. So let's close this out.
Debugging the API Call: Permissions and Headers
Let's, well my this Aaron account is already created. Let's add a new one. aaron100. Failed to create an account. Let's see what it said. Um, not read properties updatedAt. That's a new one. Let's take a look at our users console and see what's going on.
The first thing I'm I'm realizing I forgot to do, I forgot to allow us to create accounts. Because you need to set the access on here. So access, you just set access to create to true so that I actually can create an account. This is not the most secure approach. There's definitely a much better way to do it. I'm just doing this application for demonstration purposes to show you how to integrate new views inside your application. So let's go back. I'm still logged in as, clearly... native... Okay, so everything's good. This bug, I have no idea what it's talking about. I'm missing... dummy mistake. I didn't put my headers application/json There we go. See if that resolves everything.
Final Touches, Testing, and Conclusion
It's okay. Sorry, there's nothing to respond to your request. That's interesting. So it looks like it did create a user. Back to dashboard... Admin. Uh, I see. So it added my user. Here's my new user. I had the wrong path. It should be /admin/collection/users. So let's fix this. /admin/collection/users. Also see now I'm logged in, I'm still logged in as the other user which is interesting. Let's try that. So let me log out. All right, so I'm logged out and I'm going to go to /admin/create-account and we're going to say, aaron.new, and create account.
All right. So it created my account, but it didn't log me in. I could probably add that code to log in the user if successful. But if I put aaron+new... nope, I think it was aaron+new. And I've logged in. So aaron+new, that's new. Kind of created. Like I said, this is meant to be a short one, so it is short. I will include all the source code for you to kind of take a look and poke around and try this yourself. As I said, there is a, where is it? Here's a blog post that I created. Now that I've gone through the process, I'll review what I wrote to make sure it matches. But this will be available too. Blog post, video, source code. Hopefully you found this enjoyable. We will see you next time and drop a link if there's anything interesting that you'd like to see with Payload CMS. Thanks. Bye now.