diff --git a/src/content/docs/en/guides/cms/payload.mdx b/src/content/docs/en/guides/cms/payload.mdx index 773714e9d4bc4..08f01f4b5412e 100644 --- a/src/content/docs/en/guides/cms/payload.mdx +++ b/src/content/docs/en/guides/cms/payload.mdx @@ -7,7 +7,215 @@ service: Payload CMS i18nReady: false --- -[Payload](https://payloadcms.com/) is a headless CMS and application framework. +[PayloadCMS](https://payloadcms.com/) is a headless open-source content management system that can be used to provide content for your Astro project. + +## Integrating with Astro + +### Prerequisites + + +1. **An Astro project** - If you don't have an Astro project yet, our [Installation guide](/en/install/auto/) will get you up and running in no time. +2. **A MongoDB database** - PayloadCMS will ask you for a MongoDB connection string when creating a new project. You can set one up locally or use [MongoDBAtlas](https://www.mongodb.com/) to host a database on the web for free. +3. **A PayloadCMS REST API** - Create a [PayloadCMS](https://payloadcms.com/) project and connect it to your MongoDB database during the setup. + +:::note[Choosing a template] +During the PayloadCMS installation, you will be asked if you want to use a template. + +Choosing any of the available templates at this step (such as 'blog') automatically generates additional collections for you to use. Otherwise, you will need to manually create your PayloadCMS collections. +::: + +### Configuring Astro for your PayloadCMS collection + +Your Payload project template will contain a file called Posts.ts in `src/collections/`. If you did not choose a template during installation that created a content collection for you, you can create a new Payload CMS Collection by adding this configuration file manually. The example below shows this file for a collection called `posts` that requires `title`, `content`, and `slug` fields: + + +```astro title="src/collections/Posts.ts" +import { CollectionConfig } from "payload/types"; + +const Posts: CollectionConfig = { + slug: "posts", + admin: { + useAsTitle: "title", + }, + access: { + read: () => true, + }, + + fields: [ + { + name: "title", + type: "text", + required: true, + }, + { + name: "content", + type: "text", + required: true, + }, + { + name: "slug", + type: "text", + required: true, + }, + ], +}; + +export default Posts; +``` + +1. Import and add both `Users` (available in all PayloadCMS projects) and any other collections (e.g. `Posts`) to the available collections in the `payload.config.ts` file. + +```astro title="src/payload.config.ts" ins={4, 5, 12} +import { buildConfig } from "payload/config"; +import path from "path"; + +import Users from "./collections/Users"; +import Posts from "./collections/Posts"; + +export default buildConfig({ + serverURL: "http://localhost:3000", + admin: { + user: Users.slug, + }, + collections: [Users, Posts], + typescript: { + outputFile: path.resolve(__dirname, "payload-types.ts"), + }, + graphQL: { + schemaOutputFile: path.resolve(__dirname, "generated-schema.graphql"), + }, +}); +``` + +This will make a new collection called "Posts" appear in your PayloadCMS Dashboard next to the "Users" collection. + +2. Enter the "Posts" collection and create a new post. After saving it, you will notice the API URL appear in the bottom right corner. + +3. With the dev server running, open `http://localhost:3000/api/posts` in your browser. You should see a JSON file containing the post you have created as an object. + +```json +{ + "docs":[ + { + "id":"64098b16483b0f06a7e20ed4", + "title":"Astro & PayloadCMS Title 🚀", + "content":"Astro & PayloadCMS Content", + "slug":"astro-payloadcms-slug", + "createdAt":"2023-03-09T07:30:30.837Z", + "updatedAt":"2023-03-09T07:30:30.837Z" + } + ], + "totalDocs":1, + "limit":10, + "totalPages":1, + "page":1, + "pagingCounter":1, + "hasPrevPage":false, + "hasNextPage":false, + "prevPage":null, + "nextPage":null +} +``` + +:::tip +By default, both Astro and PayloadCMS will use port 3000. You might want to change the PayloadCMS port in the `src/server.ts` file. Don't forget to update the `serverURL` in `src/payload.config.ts` as well. +::: + +### Fetching Data + +Fetch your PayloadCMS data through your site's unique REST API URL and the route for your content. (By default, PayloadCMS will mount all routes through `/api`.) Then, you can render your data properties using Astro's `set:html=""` directive. + +Together with your post, PayloadCMS will return some top-level metadata. The actual documents are nested within the `docs` array. + +For example, to display a list of post titles and their content: + +```astro title="src/pages/index.astro" +--- +import HomeLayout from "../layouts/HomeLayout.astro"; + +const res = await fetch("https://localhost:5000/api/posts") // https://localhost:3000/api/posts by default +const posts = await res.json() +--- + + + { + posts.docs.map((post) => ( +

+

+ )) + } + +``` + +## Building a blog with PayloadCMS and Astro + +Create a blog index page `src/pages/index.astro` to list each of your posts with a link to its own page. + +Fetching via the API returns an array of objects (posts) that include, among others, the following properties: + +- `title` +- `content` +- `slug` + +```astro title="src/pages/index.astro" +--- +import HomeLayout from "../layouts/HomeLayout.astro"; + +const res = await fetch("http://localhost:5000/api/posts") // https://localhost:3000/api/posts by default +const posts = await res.json() +--- + + +

Astro + PayloadCMS 🚀

+

Blog posts list:

+ +
+``` + +### Using the PayloadCMS API to generate pages + +Create a page `src/pages/posts/[slug].astro` to [dynamically generate a page](/en/core-concepts/routing/#dynamic-routes) for each post. + +```astro title="src/pages/posts/[slug].astro" +--- +import PostLayout from "../../layouts/PostLayout.astro" + +const {title, content} = Astro.props + +// The getStaticPaths() is required for static Astro sites. +// If using SSR, you will not need this function. +export async function getStaticPaths() { + let data = await fetch("http://localhost:5000/api/posts") + let posts = await data.json() + + return posts.docs.map((post) => { + return { + params: {slug: post.slug}, + props: {title: post.title, content: post.content}, + }; + }); +} +--- + +
+

+

+

+
+``` + +### Publishing your site + +To deploy your site visit our [deployment guide](/en/guides/deploy/) and follow the instructions for your preferred hosting provider. + ## Community Resources