From f8b7e3eb146055bf07cbf9d76710eb05499199b3 Mon Sep 17 00:00:00 2001 From: Patrik Date: Tue, 26 Nov 2024 16:59:16 -0500 Subject: [PATCH] chore(examples): removes external draft-preview examples (#9545) In an effort to keep the Examples Directory as easy to navigate as possible, and to keep the Payload Monorepo only as verbose as it needs to be, we need to remove all alternatives from the Examples Directory. This includes setups that interact with Payload from a standalone server, keeping only the Payload recommended "combined" Next.js + Payload setups. --- examples/draft-preview/.env.example | 8 + .../draft-preview/{payload => }/.eslintrc.cjs | 0 .../draft-preview/{payload => }/.gitignore | 0 examples/draft-preview/{payload => }/.swcrc | 0 .../draft-preview/{payload => }/README.md | 41 +- examples/draft-preview/next-app/.env.example | 3 - examples/draft-preview/next-app/.eslintrc.cjs | 7 - examples/draft-preview/next-app/.gitignore | 6 - examples/draft-preview/next-app/README.md | 43 - .../next-app/app/[slug]/page.tsx | 51 - .../next-app/app/_api/fetchPage.ts | 39 - .../next-app/app/_api/fetchPages.ts | 11 - .../app/_components/AdminBar/index.client.tsx | 44 - .../app/_components/AdminBar/index.tsx | 16 - .../next-app/app/_components/Button/index.tsx | 74 - .../app/_components/CMSLink/index.tsx | 72 - .../next-app/app/_components/Gutter/index.tsx | 34 - .../next-app/app/_components/Header/index.tsx | 49 - .../app/_components/RichText/index.tsx | 19 - .../app/_components/RichText/serialize.tsx | 92 - .../next-app/app/api/preview/route.ts | 49 - .../next-app/app/api/revalidate/route.ts | 35 - .../draft-preview/next-app/app/layout.tsx | 32 - .../draft-preview/next-app/next.config.js | 8 - examples/draft-preview/next-app/package.json | 40 - .../draft-preview/next-app/payload-types.ts | 265 -- .../draft-preview/next-app/pnpm-lock.yaml | 3495 ----------------- .../draft-preview/next-app/public/favicon.ico | Bin 17223 -> 0 bytes .../draft-preview/next-app/public/favicon.svg | 15 - examples/draft-preview/next-app/tsconfig.json | 32 - .../{next-app => }/next-env.d.ts | 0 .../draft-preview/next-pages/.editorconfig | 10 - .../draft-preview/next-pages/.env.example | 2 - .../draft-preview/next-pages/.eslintrc.cjs | 4 - examples/draft-preview/next-pages/.gitignore | 6 - examples/draft-preview/next-pages/README.md | 43 - .../draft-preview/next-pages/next-env.d.ts | 5 - .../draft-preview/next-pages/next.config.js | 8 - .../draft-preview/next-pages/package.json | 40 - .../draft-preview/next-pages/pnpm-lock.yaml | 3064 --------------- .../next-pages/public/favicon.ico | Bin 17223 -> 0 bytes .../next-pages/public/favicon.svg | 15 - .../src/components/AdminBar/index.module.scss | 51 - .../src/components/AdminBar/index.tsx | 42 - .../src/components/Button/index.module.scss | 55 - .../src/components/Button/index.tsx | 74 - .../src/components/CMSLink/index.tsx | 66 - .../src/components/Gutter/index.module.scss | 13 - .../src/components/Gutter/index.tsx | 34 - .../src/components/Header/index.module.scss | 32 - .../src/components/Header/index.tsx | 71 - .../src/components/RichText/index.module.scss | 9 - .../src/components/RichText/index.tsx | 19 - .../src/components/RichText/serialize.tsx | 92 - .../next-pages/src/pages/[slug].module.scss | 3 - .../next-pages/src/pages/[slug].tsx | 132 - .../next-pages/src/pages/_app.tsx | 84 - .../next-pages/src/pages/api/exit-preview.ts | 9 - .../next-pages/src/pages/api/preview.ts | 44 - .../next-pages/src/pages/api/revalidate.ts | 23 - .../next-pages/src/pages/app.scss | 236 -- .../next-pages/src/pages/index.tsx | 11 - .../next-pages/src/payload-types.ts | 265 -- .../draft-preview/next-pages/tsconfig.json | 31 - .../{payload => }/next.config.mjs | 0 .../draft-preview/{payload => }/package.json | 0 examples/draft-preview/payload/.env.example | 16 - examples/draft-preview/payload/next-env.d.ts | 5 - .../src/app/(app)/[slug]/index.module.scss | 3 - .../payload/src/app/(app)/app.scss | 118 - .../src/app/(app)/next/exit-preview/route.ts | 7 - .../payload/src/app/(app)/page.tsx | 3 - .../collections/Pages/hooks/revalidatePage.ts | 63 - .../src/components/AdminBar/index.module.scss | 51 - .../src/components/Button/index.module.scss | 55 - .../src/components/Gutter/index.module.scss | 13 - .../src/components/Header/index.module.scss | 32 - .../src/components/RichText/index.module.scss | 9 - .../{payload => }/pnpm-lock.yaml | 60 +- .../app/(app)}/[slug]/index.module.scss | 0 .../src/app/(app)/[slug]/page.tsx | 0 .../{next-app/app => src/app/(app)}/app.scss | 0 .../{payload => }/src/app/(app)/layout.tsx | 0 .../src/app/(app)/next/exit-preview/GET.ts | 0 .../app/(app)/next}/exit-preview/route.ts | 0 .../src/app/(app)/next/preview/route.ts | 0 .../{next-app/app => src/app/(app)}/page.tsx | 0 .../admin/[[...segments]]/not-found.tsx | 0 .../(payload)/admin/[[...segments]]/page.tsx | 0 .../src/app/(payload)/admin/importMap.js | 0 .../src/app/(payload)/api/[...slug]/route.ts | 0 .../(payload)/api/graphql-playground/route.ts | 0 .../src/app/(payload)/api/graphql/route.ts | 0 .../src/app/(payload)/custom.scss | 0 .../src/app/(payload)/layout.tsx | 0 .../src/collections/Pages/access/loggedIn.ts | 0 .../Pages/access/publishedOrLoggedIn.ts | 0 .../src/collections/Pages/hooks/formatSlug.ts | 0 .../collections/Pages/hooks/revalidatePage.ts | 25 + .../src/collections/Pages/index.ts | 25 +- .../{payload => }/src/collections/Users.ts | 0 .../components}/AdminBar/index.module.scss | 0 .../src/components/AdminBar/index.tsx | 0 .../components}/Button/index.module.scss | 0 .../src/components/Button/index.tsx | 0 .../src/components/CMSLink/index.tsx | 0 .../components}/Gutter/index.module.scss | 0 .../src/components/Gutter/index.tsx | 0 .../components}/Header/index.module.scss | 0 .../src/components/Header/index.tsx | 0 .../components}/RichText/index.module.scss | 0 .../src/components/RichText/index.tsx | 0 .../src/components/RichText/serialize.tsx | 0 .../{payload => }/src/fields/link.ts | 0 .../src/fields/richText/elements.ts | 0 .../src/fields/richText/index.ts | 0 .../src/fields/richText/leaves.ts | 0 .../MainMenu/hooks/revalidateMainMenu.ts | 0 .../src/globals/MainMenu/index.ts | 0 .../{payload => }/src/migrations/seed.ts | 0 .../{payload => }/src/payload-types.ts | 0 .../{payload => }/src/payload.config.ts | 10 +- .../{payload => }/src/seed/home.ts | 0 .../{payload => }/src/seed/page.ts | 0 .../{payload => }/src/seed/pageDraft.ts | 0 .../{payload => }/src/utilities/deepMerge.ts | 0 .../src/utilities/generatePreviewPath.ts | 0 .../{payload => }/src/utilities/getGlobals.ts | 0 .../draft-preview/{payload => }/tsconfig.json | 0 129 files changed, 74 insertions(+), 9594 deletions(-) create mode 100644 examples/draft-preview/.env.example rename examples/draft-preview/{payload => }/.eslintrc.cjs (100%) rename examples/draft-preview/{payload => }/.gitignore (100%) rename examples/draft-preview/{payload => }/.swcrc (100%) rename examples/draft-preview/{payload => }/README.md (75%) delete mode 100644 examples/draft-preview/next-app/.env.example delete mode 100644 examples/draft-preview/next-app/.eslintrc.cjs delete mode 100644 examples/draft-preview/next-app/.gitignore delete mode 100644 examples/draft-preview/next-app/README.md delete mode 100644 examples/draft-preview/next-app/app/[slug]/page.tsx delete mode 100644 examples/draft-preview/next-app/app/_api/fetchPage.ts delete mode 100644 examples/draft-preview/next-app/app/_api/fetchPages.ts delete mode 100644 examples/draft-preview/next-app/app/_components/AdminBar/index.client.tsx delete mode 100644 examples/draft-preview/next-app/app/_components/AdminBar/index.tsx delete mode 100644 examples/draft-preview/next-app/app/_components/Button/index.tsx delete mode 100644 examples/draft-preview/next-app/app/_components/CMSLink/index.tsx delete mode 100644 examples/draft-preview/next-app/app/_components/Gutter/index.tsx delete mode 100644 examples/draft-preview/next-app/app/_components/Header/index.tsx delete mode 100644 examples/draft-preview/next-app/app/_components/RichText/index.tsx delete mode 100644 examples/draft-preview/next-app/app/_components/RichText/serialize.tsx delete mode 100644 examples/draft-preview/next-app/app/api/preview/route.ts delete mode 100644 examples/draft-preview/next-app/app/api/revalidate/route.ts delete mode 100644 examples/draft-preview/next-app/app/layout.tsx delete mode 100644 examples/draft-preview/next-app/next.config.js delete mode 100644 examples/draft-preview/next-app/package.json delete mode 100644 examples/draft-preview/next-app/payload-types.ts delete mode 100644 examples/draft-preview/next-app/pnpm-lock.yaml delete mode 100644 examples/draft-preview/next-app/public/favicon.ico delete mode 100644 examples/draft-preview/next-app/public/favicon.svg delete mode 100644 examples/draft-preview/next-app/tsconfig.json rename examples/draft-preview/{next-app => }/next-env.d.ts (100%) delete mode 100644 examples/draft-preview/next-pages/.editorconfig delete mode 100644 examples/draft-preview/next-pages/.env.example delete mode 100644 examples/draft-preview/next-pages/.eslintrc.cjs delete mode 100644 examples/draft-preview/next-pages/.gitignore delete mode 100644 examples/draft-preview/next-pages/README.md delete mode 100644 examples/draft-preview/next-pages/next-env.d.ts delete mode 100644 examples/draft-preview/next-pages/next.config.js delete mode 100644 examples/draft-preview/next-pages/package.json delete mode 100644 examples/draft-preview/next-pages/pnpm-lock.yaml delete mode 100644 examples/draft-preview/next-pages/public/favicon.ico delete mode 100644 examples/draft-preview/next-pages/public/favicon.svg delete mode 100644 examples/draft-preview/next-pages/src/components/AdminBar/index.module.scss delete mode 100644 examples/draft-preview/next-pages/src/components/AdminBar/index.tsx delete mode 100644 examples/draft-preview/next-pages/src/components/Button/index.module.scss delete mode 100644 examples/draft-preview/next-pages/src/components/Button/index.tsx delete mode 100644 examples/draft-preview/next-pages/src/components/CMSLink/index.tsx delete mode 100644 examples/draft-preview/next-pages/src/components/Gutter/index.module.scss delete mode 100644 examples/draft-preview/next-pages/src/components/Gutter/index.tsx delete mode 100644 examples/draft-preview/next-pages/src/components/Header/index.module.scss delete mode 100644 examples/draft-preview/next-pages/src/components/Header/index.tsx delete mode 100644 examples/draft-preview/next-pages/src/components/RichText/index.module.scss delete mode 100644 examples/draft-preview/next-pages/src/components/RichText/index.tsx delete mode 100644 examples/draft-preview/next-pages/src/components/RichText/serialize.tsx delete mode 100644 examples/draft-preview/next-pages/src/pages/[slug].module.scss delete mode 100644 examples/draft-preview/next-pages/src/pages/[slug].tsx delete mode 100644 examples/draft-preview/next-pages/src/pages/_app.tsx delete mode 100644 examples/draft-preview/next-pages/src/pages/api/exit-preview.ts delete mode 100644 examples/draft-preview/next-pages/src/pages/api/preview.ts delete mode 100644 examples/draft-preview/next-pages/src/pages/api/revalidate.ts delete mode 100644 examples/draft-preview/next-pages/src/pages/app.scss delete mode 100644 examples/draft-preview/next-pages/src/pages/index.tsx delete mode 100644 examples/draft-preview/next-pages/src/payload-types.ts delete mode 100644 examples/draft-preview/next-pages/tsconfig.json rename examples/draft-preview/{payload => }/next.config.mjs (100%) rename examples/draft-preview/{payload => }/package.json (100%) delete mode 100644 examples/draft-preview/payload/.env.example delete mode 100644 examples/draft-preview/payload/next-env.d.ts delete mode 100644 examples/draft-preview/payload/src/app/(app)/[slug]/index.module.scss delete mode 100644 examples/draft-preview/payload/src/app/(app)/app.scss delete mode 100644 examples/draft-preview/payload/src/app/(app)/next/exit-preview/route.ts delete mode 100644 examples/draft-preview/payload/src/app/(app)/page.tsx delete mode 100644 examples/draft-preview/payload/src/collections/Pages/hooks/revalidatePage.ts delete mode 100644 examples/draft-preview/payload/src/components/AdminBar/index.module.scss delete mode 100644 examples/draft-preview/payload/src/components/Button/index.module.scss delete mode 100644 examples/draft-preview/payload/src/components/Gutter/index.module.scss delete mode 100644 examples/draft-preview/payload/src/components/Header/index.module.scss delete mode 100644 examples/draft-preview/payload/src/components/RichText/index.module.scss rename examples/draft-preview/{payload => }/pnpm-lock.yaml (99%) rename examples/draft-preview/{next-app/app => src/app/(app)}/[slug]/index.module.scss (100%) rename examples/draft-preview/{payload => }/src/app/(app)/[slug]/page.tsx (100%) rename examples/draft-preview/{next-app/app => src/app/(app)}/app.scss (100%) rename examples/draft-preview/{payload => }/src/app/(app)/layout.tsx (100%) rename examples/draft-preview/{payload => }/src/app/(app)/next/exit-preview/GET.ts (100%) rename examples/draft-preview/{next-app/app/api => src/app/(app)/next}/exit-preview/route.ts (100%) rename examples/draft-preview/{payload => }/src/app/(app)/next/preview/route.ts (100%) rename examples/draft-preview/{next-app/app => src/app/(app)}/page.tsx (100%) rename examples/draft-preview/{payload => }/src/app/(payload)/admin/[[...segments]]/not-found.tsx (100%) rename examples/draft-preview/{payload => }/src/app/(payload)/admin/[[...segments]]/page.tsx (100%) rename examples/draft-preview/{payload => }/src/app/(payload)/admin/importMap.js (100%) rename examples/draft-preview/{payload => }/src/app/(payload)/api/[...slug]/route.ts (100%) rename examples/draft-preview/{payload => }/src/app/(payload)/api/graphql-playground/route.ts (100%) rename examples/draft-preview/{payload => }/src/app/(payload)/api/graphql/route.ts (100%) rename examples/draft-preview/{payload => }/src/app/(payload)/custom.scss (100%) rename examples/draft-preview/{payload => }/src/app/(payload)/layout.tsx (100%) rename examples/draft-preview/{payload => }/src/collections/Pages/access/loggedIn.ts (100%) rename examples/draft-preview/{payload => }/src/collections/Pages/access/publishedOrLoggedIn.ts (100%) rename examples/draft-preview/{payload => }/src/collections/Pages/hooks/formatSlug.ts (100%) create mode 100644 examples/draft-preview/src/collections/Pages/hooks/revalidatePage.ts rename examples/draft-preview/{payload => }/src/collections/Pages/index.ts (50%) rename examples/draft-preview/{payload => }/src/collections/Users.ts (100%) rename examples/draft-preview/{next-app/app/_components => src/components}/AdminBar/index.module.scss (100%) rename examples/draft-preview/{payload => }/src/components/AdminBar/index.tsx (100%) rename examples/draft-preview/{next-app/app/_components => src/components}/Button/index.module.scss (100%) rename examples/draft-preview/{payload => }/src/components/Button/index.tsx (100%) rename examples/draft-preview/{payload => }/src/components/CMSLink/index.tsx (100%) rename examples/draft-preview/{next-app/app/_components => src/components}/Gutter/index.module.scss (100%) rename examples/draft-preview/{payload => }/src/components/Gutter/index.tsx (100%) rename examples/draft-preview/{next-app/app/_components => src/components}/Header/index.module.scss (100%) rename examples/draft-preview/{payload => }/src/components/Header/index.tsx (100%) rename examples/draft-preview/{next-app/app/_components => src/components}/RichText/index.module.scss (100%) rename examples/draft-preview/{payload => }/src/components/RichText/index.tsx (100%) rename examples/draft-preview/{payload => }/src/components/RichText/serialize.tsx (100%) rename examples/draft-preview/{payload => }/src/fields/link.ts (100%) rename examples/draft-preview/{payload => }/src/fields/richText/elements.ts (100%) rename examples/draft-preview/{payload => }/src/fields/richText/index.ts (100%) rename examples/draft-preview/{payload => }/src/fields/richText/leaves.ts (100%) rename examples/draft-preview/{payload => }/src/globals/MainMenu/hooks/revalidateMainMenu.ts (100%) rename examples/draft-preview/{payload => }/src/globals/MainMenu/index.ts (100%) rename examples/draft-preview/{payload => }/src/migrations/seed.ts (100%) rename examples/draft-preview/{payload => }/src/payload-types.ts (100%) rename examples/draft-preview/{payload => }/src/payload.config.ts (79%) rename examples/draft-preview/{payload => }/src/seed/home.ts (100%) rename examples/draft-preview/{payload => }/src/seed/page.ts (100%) rename examples/draft-preview/{payload => }/src/seed/pageDraft.ts (100%) rename examples/draft-preview/{payload => }/src/utilities/deepMerge.ts (100%) rename examples/draft-preview/{payload => }/src/utilities/generatePreviewPath.ts (100%) rename examples/draft-preview/{payload => }/src/utilities/getGlobals.ts (100%) rename examples/draft-preview/{payload => }/tsconfig.json (100%) diff --git a/examples/draft-preview/.env.example b/examples/draft-preview/.env.example new file mode 100644 index 0000000000..b12aa7dd41 --- /dev/null +++ b/examples/draft-preview/.env.example @@ -0,0 +1,8 @@ +# Database connection string +DATABASE_URI=mongodb://127.0.0.1/payload-draft-preview-example + +# Used to encrypt JWT tokens +PAYLOAD_SECRET=YOUR_SECRET_HERE + +# Used to configure CORS, format links and more. No trailing slash +NEXT_PUBLIC_SERVER_URL=http://localhost:3000 diff --git a/examples/draft-preview/payload/.eslintrc.cjs b/examples/draft-preview/.eslintrc.cjs similarity index 100% rename from examples/draft-preview/payload/.eslintrc.cjs rename to examples/draft-preview/.eslintrc.cjs diff --git a/examples/draft-preview/payload/.gitignore b/examples/draft-preview/.gitignore similarity index 100% rename from examples/draft-preview/payload/.gitignore rename to examples/draft-preview/.gitignore diff --git a/examples/draft-preview/payload/.swcrc b/examples/draft-preview/.swcrc similarity index 100% rename from examples/draft-preview/payload/.swcrc rename to examples/draft-preview/.swcrc diff --git a/examples/draft-preview/payload/README.md b/examples/draft-preview/README.md similarity index 75% rename from examples/draft-preview/payload/README.md rename to examples/draft-preview/README.md index 36fd597636..0025a92a1d 100644 --- a/examples/draft-preview/payload/README.md +++ b/examples/draft-preview/README.md @@ -1,11 +1,6 @@ # Payload Draft Preview Example -The [Payload Draft Preview Example](https://github.com/payloadcms/payload/tree/main/examples/draft-preview/payload) demonstrates how to implement draft preview in [Payload](https://github.com/payloadcms/payload) using [Versions](https://payloadcms.com/docs/versions/overview) and [Drafts](https://payloadcms.com/docs/versions/drafts). Draft preview allows you to see content on your front-end before it is published. There are various fully working front-ends made explicitly for this example, including: - -- [Next.js App Router](../next-app) -- [Next.js Pages Router](../next-pages) - -Follow the instructions in each respective README to get started. If you are setting up draft preview for another front-end, please consider contributing to this repo with your own example! +The [Payload Draft Preview Example](https://github.com/payloadcms/payload/tree/main/examples/draft-preview/payload) demonstrates how to implement draft preview in [Payload](https://github.com/payloadcms/payload) using [Versions](https://payloadcms.com/docs/versions/overview) and [Drafts](https://payloadcms.com/docs/versions/drafts). Draft preview allows you to see content on your front-end before it is published. ## Quick Start @@ -17,9 +12,6 @@ To spin up this example locally, follow these steps: > \*If you are running using pnpm within the Payload Monorepo, the `--ignore-workspace` flag is needed so that pnpm generates a lockfile in this example's directory despite the fact that one exists in root. 3. `cp .env.example .env` to copy the example environment variables - - > Adjust `PAYLOAD_PUBLIC_SITE_URL` in the `.env` if your front-end is running on a separate domain or port. - 4. `pnpm dev`, `yarn dev` or `npm run dev` to start the server 5. `open http://localhost:3000/admin` to access the admin panel 6. Login with email `demo@payloadcms.com` and password `demo` @@ -30,33 +22,6 @@ That's it! Changes made in `./src` will be reflected in your app. See the [Devel Draft preview works by sending the user to your front-end with a `secret` along with their http-only cookies. Your front-end catches the request, verifies the authenticity, then enters into it's own preview mode. Once in preview mode, your front-end can begin securely requesting draft documents from Payload. See [Preview Mode](#preview-mode) for more details. -### Environment Variables - -Depending on how you run this example, you need different environment variables: - -- #### Running Payload and the Front-End Together - - When the Payload server and front-end run on the same domain and port: - - ```ts - DATABASE_URI=mongodb://127.0.0.1/payload-draft-preview-example - PAYLOAD_SECRET=YOUR_SECRET_HERE - NEXT_PUBLIC_SERVER_URL=http://localhost:3000 - ``` - -- #### Running Payload and the Front-End Separately - - When running Payload on one domain (e.g., `localhost:3000`) and the front-end on another (e.g., `localhost:3001`): - - ```ts - DATABASE_URI=mongodb://127.0.0.1/payload-draft-preview-example - PAYLOAD_SECRET=YOUR_SECRET_HERE - NEXT_PUBLIC_SERVER_URL=http://localhost:3000 - PAYLOAD_PUBLIC_SITE_URL=http://localhost:3001 - REVALIDATION_KEY=EXAMPLE_REVALIDATION_KEY - PAYLOAD_PUBLIC_DRAFT_SECRET=EXAMPLE_DRAFT_SECRET - ``` - ### Collections See the [Collections](https://payloadcms.com/docs/configuration/collections) docs for details on how to extend any of this functionality. @@ -94,13 +59,13 @@ See the [Collections](https://payloadcms.com/docs/configuration/collections) doc To preview draft documents, the user first needs to have at least one draft document saved. When they click the "preview" button from the Payload admin panel, a custom [preview function](https://payloadcms.com/docs/admin/collections#preview) routes them to your front-end with a `secret` along with their http-only cookies. An API route on your front-end will verify the secret and token before entering into it's own preview mode. Once in preview mode, it can begin requesting drafts from Payload using the `Authorization` header. See [Pages](#pages) for more details. -> "Preview mode" looks differently for every front-end framework. For instance, check out the differences between Next.js [Preview Mode](https://nextjs.org/docs/pages/building-your-application/configuring/preview-mode) in the Pages Router and [Draft Mode](https://nextjs.org/docs/pages/building-your-application/configuring/draft-mode) in the App Router. In Next.js, methods are provided that set cookies in your browser, but this may not be the case for all frameworks. +> "Preview mode" can vary between frameworks. In the Next.js App Router, [Draft Mode](https://nextjs.org/docs/pages/building-your-application/configuring/draft-mode) enables you to work with previewable content. It provides methods to set cookies in your browser, ensuring content is displayed as a draft, but this behavior might differ in other frameworks. ### On-demand Revalidation If your front-end is statically generated then you may also want to regenerate the HTML for each page individually as they are published, referred to as On-demand Revalidation. This will prevent your static site from having to fully rebuild every page in order to deploy content changes. To do this, we add an `afterChange` hook to the collection that fires a request to your front-end in the background each time the document is updated. You can handle this request on your front-end to revalidate the HTML for your page. -> On-demand revalidation looks differently for every front-end framework. For instance, check out the differences between Next.js on-demand revalidation in the [Pages Router](https://nextjs.org/docs/pages/building-your-application/data-fetching/incremental-static-regeneration) and the [App Router](https://nextjs.org/docs/app/building-your-application/data-fetching/revalidating#on-demand-revalidation). In Next.js, methods are provided that regenerate the HTML for each page, but this may not be the case for all frameworks. +> On-demand revalidation can vary between frameworks. In the Next.js [App Router](https://nextjs.org/docs/app/building-your-application/data-fetching/revalidating#on-demand-revalidation), on-demand revalidation allows you to regenerate the HTML for specific pages as needed. However, this behavior may differ in other frameworks. ### Admin Bar diff --git a/examples/draft-preview/next-app/.env.example b/examples/draft-preview/next-app/.env.example deleted file mode 100644 index a66274c71f..0000000000 --- a/examples/draft-preview/next-app/.env.example +++ /dev/null @@ -1,3 +0,0 @@ -NEXT_PUBLIC_PAYLOAD_URL=http://localhost:3000 -NEXT_PRIVATE_DRAFT_SECRET=EXAMPLE_DRAFT_SECRET -NEXT_PRIVATE_REVALIDATION_KEY=EXAMPLE_REVALIDATION_KEY diff --git a/examples/draft-preview/next-app/.eslintrc.cjs b/examples/draft-preview/next-app/.eslintrc.cjs deleted file mode 100644 index b22424b3ed..0000000000 --- a/examples/draft-preview/next-app/.eslintrc.cjs +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - root: true, - extends: ['plugin:@next/next/recommended', '@payloadcms'], - rules: { - 'import/extensions': 'off', - }, -} diff --git a/examples/draft-preview/next-app/.gitignore b/examples/draft-preview/next-app/.gitignore deleted file mode 100644 index 233d5a4d02..0000000000 --- a/examples/draft-preview/next-app/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.next -dist -build -node_modules -.env -package-lock.json diff --git a/examples/draft-preview/next-app/README.md b/examples/draft-preview/next-app/README.md deleted file mode 100644 index 5a8f850387..0000000000 --- a/examples/draft-preview/next-app/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Payload Draft Preview Example Front-End - -This is a [Next.js](https://nextjs.org) app using the [App Router](https://nextjs.org/docs/app). It was made explicitly for Payload's [Draft Preview Example](https://github.com/payloadcms/payload/tree/main/examples/draft-preview/payload). - -> This example uses the App Router, the latest API of Next.js. If your app is using the legacy [Pages Router](https://nextjs.org/docs/pages), check out the official [Pages Router Example](https://github.com/payloadcms/payload/tree/main/examples/draft-preview/next-pages). - -## Getting Started - -### Payload - -First you'll need a running Payload app. There is one made explicitly for this example and [can be found here](https://github.com/payloadcms/payload/tree/main/examples/draft-preview/payload). If you have not done so already, clone it down and follow the setup instructions there. This will provide all the necessary APIs that your Next.js app requires for authentication. - -### Next.js - -1. Clone this repo -2. `cd` into this directory and run `pnpm i --ignore-workspace`\*, `yarn`, or `npm install` - - > \*If you are running using pnpm within the Payload Monorepo, the `--ignore-workspace` flag is needed so that pnpm generates a lockfile in this example's directory despite the fact that one exists in root. - -3. `cp .env.example .env` to copy the example environment variables - - > Adjust `PAYLOAD_PUBLIC_SITE_URL` in the `.env` if your front-end is running on a separate domain or port. - -4. `pnpm dev`, `yarn dev` or `npm run dev` to start the server -5. `open http://localhost:3001` to see the result - -Once running you will find a couple seeded pages on your local environment with some basic instructions. You can also start editing the pages by modifying the documents within Payload. See the [Draft Preview Example](https://github.com/payloadcms/payload/tree/main/examples/draft-preview/payload) for full details. - -## Learn More - -To learn more about Payload and Next.js, take a look at the following resources: - -- [Payload Documentation](https://payloadcms.com/docs) - learn about Payload features and API. -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Payload GitHub repository](https://github.com/payloadcms/payload) as well as [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! - -## Deployment - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new) from the creators of Next.js. You could also combine this app into a [single Express server](https://github.com/payloadcms/payload/tree/main/examples/custom-server) and deploy in to [Payload Cloud](https://payloadcms.com/new/import). - -Check out our [Payload deployment documentation](https://payloadcms.com/docs/production/deployment) or the [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/examples/draft-preview/next-app/app/[slug]/page.tsx b/examples/draft-preview/next-app/app/[slug]/page.tsx deleted file mode 100644 index 337f72c676..0000000000 --- a/examples/draft-preview/next-app/app/[slug]/page.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { draftMode } from 'next/headers' -import { notFound } from 'next/navigation' - -import type { Page as PageType } from '../../payload-types' -import { fetchPage } from '../_api/fetchPage' -import { fetchPages } from '../_api/fetchPages' -import { Gutter } from '../_components/Gutter' -import RichText from '../_components/RichText' - -import classes from './index.module.scss' - -interface PageParams { - params: Promise<{ - slug?: string - }> -} - -export const PageTemplate: React.FC<{ page: null | PageType | undefined }> = ({ page }) => ( -
- -

{page?.title}

- -
-
-) - -export default async function Page({ params }: PageParams) { - const { slug = 'home' } = await params - - const { isEnabled: isDraftMode } = await draftMode() - - const page = await fetchPage(slug, isDraftMode) - - if (page === null) { - return notFound() - } - - return -} - -export async function generateStaticParams() { - const pages = await fetchPages() - - return pages.map(({ slug }) => - slug !== 'home' - ? { - slug, - } - : {}, - ) // eslint-disable-line function-paren-newline -} diff --git a/examples/draft-preview/next-app/app/_api/fetchPage.ts b/examples/draft-preview/next-app/app/_api/fetchPage.ts deleted file mode 100644 index d7ea40b273..0000000000 --- a/examples/draft-preview/next-app/app/_api/fetchPage.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { RequestCookie } from 'next/dist/compiled/@edge-runtime/cookies' - -import type { Page } from '../../payload-types' - -export const fetchPage = async ( - slug: string, - draft?: boolean, -): Promise => { - let payloadToken: RequestCookie | undefined - - if (draft) { - const { cookies } = await import('next/headers') - payloadToken = (await cookies()).get('payload-token') - } - - const pageRes: { - docs: Page[] - } = await fetch( - `${process.env.NEXT_PUBLIC_PAYLOAD_URL}/api/pages?where[slug][equals]=${slug}${ - draft && payloadToken ? '&draft=true' : '' - }`, - { - method: 'GET', - // this is the key we'll use to on-demand revalidate pages that use this data - // we do this by calling `revalidateTag()` using the same key - // see `app/api/revalidate.ts` for more info - next: { tags: [`pages_${slug}`] }, - ...(draft && payloadToken - ? { - headers: { - Authorization: `JWT ${payloadToken?.value}`, - }, - } - : {}), - }, - ).then((res) => res.json()) - - return pageRes?.docs?.[0] ?? null -} diff --git a/examples/draft-preview/next-app/app/_api/fetchPages.ts b/examples/draft-preview/next-app/app/_api/fetchPages.ts deleted file mode 100644 index 9d7a2cea5a..0000000000 --- a/examples/draft-preview/next-app/app/_api/fetchPages.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { Page } from '../../payload-types' - -export const fetchPages = async (): Promise => { - const pageRes: { - docs: Page[] - } = await fetch(`${process.env.NEXT_PUBLIC_PAYLOAD_URL}/api/pages?depth=0&limit=100`).then( - (res) => res.json(), - ) // eslint-disable-line function-paren-newline - - return pageRes?.docs ?? [] -} diff --git a/examples/draft-preview/next-app/app/_components/AdminBar/index.client.tsx b/examples/draft-preview/next-app/app/_components/AdminBar/index.client.tsx deleted file mode 100644 index 2a8041babf..0000000000 --- a/examples/draft-preview/next-app/app/_components/AdminBar/index.client.tsx +++ /dev/null @@ -1,44 +0,0 @@ -'use client' - -import React, { useState } from 'react' -import type { PayloadAdminBarProps, PayloadMeUser } from 'payload-admin-bar' -import { PayloadAdminBar } from 'payload-admin-bar' - -import { Gutter } from '../Gutter' - -import classes from './index.module.scss' - -const Title: React.FC = () => Dashboard - -export const AdminBarClient: React.FC = (props) => { - const [user, setUser] = useState() - - return ( -
- - } - onAuthChange={setUser} - onPreviewExit={async () => { - await fetch(`/api/exit-preview`) - window.location.reload() - }} - style={{ - backgroundColor: 'transparent', - padding: 0, - position: 'relative', - zIndex: 'unset', - }} - /> - -
- ) -} diff --git a/examples/draft-preview/next-app/app/_components/AdminBar/index.tsx b/examples/draft-preview/next-app/app/_components/AdminBar/index.tsx deleted file mode 100644 index 237257aed4..0000000000 --- a/examples/draft-preview/next-app/app/_components/AdminBar/index.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react' -import { draftMode } from 'next/headers' - -import { AdminBarClient } from './index.client' - -export async function AdminBar() { - const { isEnabled: isPreviewMode } = await draftMode() - - return ( - - ) -} diff --git a/examples/draft-preview/next-app/app/_components/Button/index.tsx b/examples/draft-preview/next-app/app/_components/Button/index.tsx deleted file mode 100644 index a224b86c97..0000000000 --- a/examples/draft-preview/next-app/app/_components/Button/index.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import type { ElementType } from 'react' -import React from 'react' -import Link from 'next/link' - -import classes from './index.module.scss' - -export type Props = { - appearance?: 'default' | 'primary' | 'secondary' - className?: string - disabled?: boolean - el?: 'a' | 'button' | 'link' - href?: string - label?: string - newTab?: boolean | null - onClick?: () => void - type?: 'button' | 'submit' -} - -export const Button: React.FC = ({ - type = 'button', - appearance, - className: classNameFromProps, - disabled, - el: elFromProps = 'link', - href, - label, - newTab, - onClick, -}) => { - let el = elFromProps - const newTabProps = newTab ? { rel: 'noopener noreferrer', target: '_blank' } : {} - const className = [ - classes.button, - classNameFromProps, - classes[`appearance--${appearance}`], - classes.button, - ] - .filter(Boolean) - .join(' ') - - const content = ( -
- {/* */} - {label} -
- ) - - if (onClick || type === 'submit') { - el = 'button' - } - - if (el === 'link') { - return ( - - {content} - - ) - } - - const Element: ElementType = el - - return ( - - {content} - - ) -} diff --git a/examples/draft-preview/next-app/app/_components/CMSLink/index.tsx b/examples/draft-preview/next-app/app/_components/CMSLink/index.tsx deleted file mode 100644 index c0f05037a8..0000000000 --- a/examples/draft-preview/next-app/app/_components/CMSLink/index.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react' -import Link from 'next/link' - -import type { Page } from '../../../payload-types' -import { Button } from '../Button' - -export type CMSLinkType = { - appearance?: 'default' | 'primary' | 'secondary' - children?: React.ReactNode - className?: string - label?: string - newTab?: boolean | null - reference?: { - relationTo: 'pages' - value: number | Page | string - } | null - type?: 'custom' | 'reference' | null - url?: null | string -} - -export const CMSLink: React.FC = ({ - type, - appearance, - children, - className, - label, - newTab, - reference, - url, -}) => { - const href = - type === 'reference' && typeof reference?.value === 'object' && reference.value.slug - ? `${reference?.relationTo !== 'pages' ? `/${reference?.relationTo}` : ''}/${ - reference.value.slug - }` - : url - - if (!href) { - return null - } - - if (!appearance) { - const newTabProps = newTab ? { rel: 'noopener noreferrer', target: '_blank' } : {} - - if (type === 'custom') { - return ( - - {label && label} - {children ? <>{children} : null} - - ) - } - - if (href) { - return ( - - {label && label} - {children ? <>{children} : null} - - ) - } - } - - const buttonProps = { - appearance, - href, - label, - newTab, - } - - return