Introduction: Why Use Supabase with Payload?
Hey there! In today's video, I will show you how you can set a payload in combination with Supabase. Now, why would you want to use Supabase?
So, Payload in order to run in every case needs a database. At least in most cases, you will also need a place to store your files because Payload in and of itself can store files on your local driver, but if you deploy it anywhere, this is not very convenient and will often not work, especially if you're in a serverless environment.
So Supabase provides you with both a Postgres database and multiple S3 storage buckets that you can set up. And it also has a great free plan. So you're basically getting a 500 megabyte Postgres database and 1 GB of S3 storage, which should be enough for most small projects to get started.
Creating a New Payload Project
You just need to open up your terminal, and as soon as you're in the folder where you want to create your project, you say npx create-payload-app@beta because Payload version 3 is currently still in beta. Now if I hit enter, it will ask me to give the project a name. Superbase Payload. I can also choose a project template. For now, there are only two templates: blank and plugin. Since we're not building a plugin, we're going to choose blank. And for a database, we're going to select Postgres.
Now, for now, I'm just going with this local connection string. I will replace it in a minute. So this will now install all necessary dependencies. As soon as that is done, I'm going to CD into my project. So I'm going to say cd superbase-payload and I'm opening up VS Code in here.
Setting Up Supabase and Connecting to Payload
And as you can see, yeah, trust the authors, this is the connection string that we need to replace with our Supabase database. So for that, I'm going to superbase.com. And if you don't already have an account, you can just click on 'Sign Up'. Otherwise, I'm just going to my dashboard here, which is currently empty. Now I just click on 'create new project'. I'm going to call it Superbase Payload. And now I have to set a database password, or I can just generate it automatically and copy it.
What I'm going to do here is I'm just going to paste it in our environment variables down below so that I have it for later. And remember to not hit autocomplete here because that will actually mess up your password. As soon as that is done, I can choose my region. I'm going to go for Frankfurt, but you can choose the closest area. And I'm going to create a new project. To set up your project, Supabase will take a couple of minutes, so we just need to wait until the setup has been completed.
And as soon as that is done, we're taken to a new screen where we can just click on 'Connect' in the upper right corner. This will give us our Postgres connection string that we're just going to copy and paste into our environment variables. So I'm going to replace our local connection string here with that one. And obviously, I still have to fill in my password, which I'm going to get from here and replace this section.
Verifying the Database Connection
To check if everything works as expected, I'm going to open up a terminal and start our development server by running npm run dev. And now I should open up our Payload project on localhost:3000. If you're getting this 404 page here, this is normal because we haven't created any index page. The only thing that we can currently access is the admin panel by calling /admin.
When you start up the development server and initially access the admin panel, it might take a couple of seconds to load, but as soon as that is done, we should be seeing the welcome page where we can create our first user, which I'm going to do. And then I'm just going to click on 'Create'.
And now we are in our admin panel. Let's create another user. Let's say [email protected], 12345. And let's check our database if the users have actually been saved. So Supabase... let's just easily just check our table. Sorry, not the table editor, we have to go to Database, and here we can see our database tables, 'users', and we have two rows here.
Warning: The Danger of Postgres in Development
There's one important thing that you need to keep in mind if you're using a Postgres database. Do never use your production database in your local development environment. Now, you shouldn't do this anyways, but it's extremely dangerous with Postgres because if we're changing our schema here in Payload locally, it might actually override the schema in our database and might delete an entire table. We get warned about this, but things can still happen.
So you should either use a local database in development. What you could do as well, for example, is if you go to your home dashboard, you could create a second project, just call it the 'test project'. That's what we used to do back in the days when we were working with Firebase. And that way, you will have two separated environments: one for testing or development, one for production. And that makes sure you never touch your production database in your local development.
So let me demonstrate you the issue.
Demonstrating Destructive Schema Changes
Let's go back to our project and create just a demo collection. Let's call it documents.js or .ts, doesn't matter. Export const documents and it's not a collection, we give it a slug 'documents'. We're going to leave out the labels, just say fields, we're just going to give it a name for, sorry, for demonstration. So name, type: text, label: name, and it's required.
To add this to our Payload config, if you're using JavaScript you will have to adjust your TS config file to also include JavaScript files. If you're using TypeScript, this is not an issue, you can just skip this step. So I'm going to add JS and JSX files here. In our Payload config, we can now just import 'documents' as a collection. And as soon as we... yeah, we don't even need to refresh the page. But as you can see, our documents collection appeared here. Now let's create just two documents. Test one and then also test two. And we should be able to see them in our Postgres database immediately. Yeah, here they show up. Documents. It currently says one, but should be two actually, but it might have some delay. As we can see, we have two documents here.
Now, what happens if I just, let's just say I comment this out temporarily to do whatever. Payload is actually going to warn me: You're about to delete the 'documents' table. This is because the database schema needs to be pushed, the new database schema, and this will override the new one, uh, the old one. So I can abort this here, right? But if I don't do it for whatever reason and I say yes, okay, within seconds I have basically just deleted my entire documents collection. Okay, so if I comment my documents back in, the documents appear here, but it's empty now. So I lost all my data. This is why you need to take extra care if you're working with Postgres. If you're working with MongoDB, for example, you won't have that issue because even if you comment out your collection temporarily, if you comment it back in, the data will still be there.
Setting Up S3 File Storage
Let me now show you how you can set up S3 file storage with Payload and Supabase. For that, the first thing that I have to do is install a plugin which is called @payloadcms/storage-s3. This is the new S3 plugin. There's also an older plugin called 'cloud storage', which works as well, or it should work as well, but it's more work to set up. This is really super simple.
If you're using npm, and we're still in beta, like I said in version 3, you might run into an issue with the peer dependencies. This can be fixed by either using another package manager, but in this case, if we want to use npm, we can just use the --legacy-peer-deps flag or alternatively, and that will also fix any install issues on, for example, the deployment if you deploy it, we can create an .npmrc file and just specify legacy-peer-deps = true.
Now you should be able to remove this as soon as we're out of beta. That's just current issues. So now if I try again to install the plugin, it should work without any errors. Yeah, as you can see, added packages.
Configuring the S3 Storage Plugin
The next step that you have to do is just add the plugin into your payload config. I'm just going to make this editor larger. So the only thing that we have to do here is say plugins, which is an array. And here I'm just going to paste a code snippet that you will find in the description below or somewhere. This is the S3 storage plugin that we can just import here. And what we need to give it is a configuration object for the collections that we want to use it on. I'm going to use it on the 'media' collection, which I still have to create. I'm going to do that in a second.
We also have to give it a bucket name and a config with the credentials: access key, region, and endpoint. One very important thing that you have to do if you're using it with Supabase is to force the path styles, otherwise you will run into issues. So let's just create our media collection real quick. Media. Export const media. Slug will just be media. And I'm just going to say upload: true and fields is an empty array.
Getting Supabase Storage Credentials
I'm going to add it to our Payload configuration. And if we restart our server, we should see our media collection pop up in the backend right here. Now, this won't work because we're still missing our credentials, obviously. I'm going to put them into the environment variables, which makes sense. So I'm just going to paste this blank template in here. And now we need to go back to Supabase and actually get our credentials.
To do this, I'm going in my project, I'm going to go to Storage. And in storage, I can just click on 'New bucket'. I'm going to name it the same as the project. You can name it whatever you want: superbase-payload. And the cool thing is I can also specify if it's a public bucket or a private one. So what you could do in theory is you could create one private bucket and another public bucket. And you could put the data that is in public collections, so for example, your images for your website, you can put them in a public bucket and you could disable the payload access control and serve them from the bucket directly because that will be way faster than if the files flow through the payload server.
So in this case, I'm just going with a private bucket. I'm going to click on 'Save'. Now I have an empty bucket. And to get my credentials, I need to go to settings, scroll down a bit, and first I need to copy my endpoint here. So just copy and paste it in the endpoint variable. Going back, the region, same thing. The bucket is the bucket name, so it's going to be superbase-payload. And the only thing is missing is my access key, which I can create down here. Going to click on 'new access key', so 'test key' whatever. And now it's going to show me my access key ID and also my secret access key. All right, now I'm done.
Testing the S3 File Upload
All I need to do now is restart the development server and then we're just going to upload an image and see if it works. So in our media collection, I will create a new document. Let's select the file. I just got a demo image from Unsplash. I'm going to click 'Open' and I'm going to click on 'Save'. Now this creates the image. If we click on the link, we can see it, it loads. And let's check our storage in Supabase to see if the image arrived here. As you can see, media, and in here is our image.
Final Tip and Conclusion
One important thing that I forgot to mention, in the plugin, you can configure a prefix. You can also do it without, but it just makes your files more organized if you give the stored files a prefix, which is basically a folder for the collection that you're storing. So if you would have multiple collections in here that would all have their prefix, you could see, you know, media, documents, templates, whatever.
This will be it for today's video. If you do have any questions about it or if you're facing any issues, feel free to let us know in the comments. And apart from that, take care and see you in the next video.