In this guide, we'll walk through Collections in Payload, how to use them to structure your project’s data, workflows, and scale efficiently.
In Payload, a Collection is a group of documents that share a common structure. You can have as many collections as you need for a project, and each collection you create will take up its own space in your admin dashboard.
Each document you create is stored in your database using the fields you define.
What you define in each collection automatically generates Local, REST, and GraphQL APIs for you to query your database and render data on your frontend. These APIs are represented as JSON in the API window in each of your individual collection item’s view.
It's best practice to create your collections in a separate file and then import them into your config.
To define a collection, first, create a new file for your collection. I typically store these collection files in a collections
directory, but you don’t need to do that. If I want to create a new Posts collection to store my blog posts, I create a new directory inside /collections/
called Posts
and then add a TypeScript file called config.ts
.
The structure would look as follows:
There are a few things you need to do to get your collection going.
First, you need to import the CollectionConfig
type from Payload. This ensures you're working within the structure Payload expects.
Next, export a constant named after the collection, in this case, Posts, and assign it the CollectionConfig
type.
The slug
can be whatever you want, but it's recommended to keep it the same as the collection name to prevent confusion.
Once you've created the collection, you can import it into your Payload configuration:
Collections, just like fields, have various ways to configure how they appear in the admin panel.
The group
option allows you to organize collections in the sidebar by grouping related collections together.
You can also set group: false
to hide it from the navigation while still making it accessible via the API.
The useAsTitle
option determines which field should be used as the title for each document in the admin panel. For example, useAsTitle: 'name'
.
If useAsTitle
is not set, Payload defaults to displaying the document's id.
The description
option allows you to provide extra context under the collection label in the admin panel.
You can fine-tune access control to specify who can read, create, update, or delete documents.
To define how documents should be sorted in the admin panel by default, use defaultSort
:
If you want to display a different name in the admin panel than the slug, use Labels.
A great use case for this is with our Posts
example.
If we want to query this collection using our posts
slug but we want to call these Blogs
in your admin dashboard, we can do that by setting the label
option to an object with a plural and singular option.
These are case sensitive, so be sure that you type these in exactly like you want to see them in the dashboard.
If you want your collection to support file uploads, you'll need to include either upload: true
or set upload with an object with some more options. This is extremely flexible and can be used to convert files on upload, restrict accepted MIME types, and allows you to handle how thumbnails are presented.
In the Media collection, you'll see that upload
is set to true
. If you want more control than that, you can just open up an empty object and start with formatOptions
. When you upload files, you can use format options to automatically convert files into other formats.
If you want all of your images to be converted to webp, for example, you can do that by including format: 'webp'
and it will convert anything that you upload to webp by default.
For MIME types, you can set mimeTypes
option and specify what types of documents your upload field allows. This expects an array of strings that acts as a whitelist of available types. For example, if you want to only include images, you can use mimeTypes: ['image/*']
which would allw the user to upload any type of image.
If you only want webp and PNG images allowed, you would use mimeTypes: ['image/png', 'image/webp' ]
.
This is not limited to images either. You can set restrictions to allow PDFs or other documents—all by just setting what MIME types to accept.
You can also customize how images appear as thumbnails in the admin panel.
You can either use a string to tell your collection how to handle the thumbnail, or set it as a function.
When you use a string, you can use something like, adminThumbnail: 'small'
but will only work if you include the imageSizes
.
I prefer to use a function, which takes the document as an argument. You could use your own media bucket and programmatically create a path to the file to then be used in your admin dashboard.
What this does is doing is reviewing the document, which in this case is a media file, and it's going to take the file name and apply it to the end of the string of whatever file path you're using.
We don't have a media bucket set up for this example, so the current path won't return anything for us.
By default, relationship and upload fields return the entire document, but you can limit this using defaultPopulate
.
For example, if you only want to send the slug
and name
field from the users
collection, you can set defaultPopulate
to include slug and name as true.
And then we would add a relationship field.
This will ensure that only those fields are populated when using that relationships with another collection.
Collections are the foundation of any Payload project. Whether you’re creating pages, blog posts, media uploads, user authentication, or any other content structure, understanding collection configuration is essential.
When creating a collection, keep your final design in mind so you know exactly which fields and options you need.
These configurations allow you to fully customize how your data is structured and displayed in Payload.