examples: Update Example Prepr CMS (#49224)

Co-authored-by: Kevintjuhz <kevin@kqcreations.com>
Co-authored-by: Kevintjuhz <k.quaedvlieg@outlook.com>
Co-authored-by: Lee Robinson <me@leerob.io>
This commit is contained in:
Tim 2023-08-14 14:13:50 +02:00 committed by GitHub
parent 4ee4458d46
commit fa88095f44
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 844 additions and 903 deletions

View file

@ -17,24 +17,28 @@ Once you have access to [the environment variables you'll need](#step-15-set-up-
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Cosmic](/examples/cms-cosmic)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Ghost](/examples/cms-ghost)
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
- [Blog Starter](/examples/blog-starter)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [WordPress](/examples/cms-wordpress)
- [Blog Starter](/examples/blog-starter)
## How to use

View file

@ -83,19 +83,25 @@ Alternatively, you can deploy using our template by clicking on the Deploy butto
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [Strapi](/examples/cms-strapi)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Ghost](/examples/cms-ghost)
- [Blog Starter](/examples/blog-starter)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [WordPress](/examples/cms-wordpress)
- [Blog Starter](/examples/blog-starter)

View file

@ -18,24 +18,28 @@ Once you have access to your Butter API token, you can deploy your Butterized pr
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [Strapi](/examples/cms-strapi)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Ghost](/examples/cms-ghost)
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
- [Blog Starter](/examples/blog-starter)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## How to use

View file

@ -14,24 +14,28 @@ Using the Deploy Button below, you'll deploy the Next.js project as well as conn
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Ghost](/examples/cms-ghost)
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
- [Blog Starter](/examples/blog-starter)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## How to use

View file

@ -14,24 +14,28 @@ Once you have access to [the environment variables you'll need](#step-3-set-up-e
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Ghost](/examples/cms-ghost)
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
- [Blog Starter](/examples/blog-starter)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## How to use

View file

@ -8,24 +8,28 @@ This example showcases Next.js's [Static Generation](https://nextjs.org/docs/bas
### Related examples
- [WordPress](/examples/cms-wordpress)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Ghost](/examples/cms-ghost)
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
- [Blog Starter](/examples/blog-starter)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## Deploy your own

View file

@ -14,21 +14,28 @@ Using the Deploy Button below, you'll deploy the Next.js project.
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Ghost](/examples/cms-ghost)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## How to use

View file

@ -14,23 +14,28 @@ Once you have [configured the Next.js module for Drupal](https://next-drupal.org
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [Kontent](/examples/cms-kontent)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [DotCMS](/examples/cms-dotcms)
- [Enterspeed](/examples/cms-enterspeed)
- [WordPress](/examples/cms-wordpress)
## How to use

View file

@ -14,22 +14,28 @@ Once you have access to [the environment variables you'll need](#step-3-set-up-e
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Ghost](/examples/cms-ghost)
- [Blog Starter](/examples/blog-starter)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## How to use

View file

@ -13,23 +13,28 @@ Once you have access to [the environment variables you'll need](#step-2-set-up-e
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
- [Blog Starter](/examples/blog-starter)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## How to use

View file

@ -14,24 +14,28 @@ Once you have access to [the environment variables you'll need](#step-3-set-up-e
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Ghost](/examples/cms-ghost)
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
- [Blog Starter](/examples/blog-starter)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## How to use

View file

@ -1,4 +1,4 @@
PREPRIO_API=https://graphql.prepr.io/graphql
PREPRIO_PRODUCTION_TOKEN=
PREPRIO_PREVIEW_TOKEN=
PREPRIO_PREVIEW_KEY=
PREPRIO_PREVIEW_SECRET=YOURSECRET

View file

@ -18,6 +18,7 @@
# misc
.DS_Store
*.pem
.env
# debug
npm-debug.log*

View file

@ -4,12 +4,146 @@ This example showcases Next.js's [Static Generation](https://nextjs.org/docs/bas
## Demo
Check out our Blog page example:
- **Live**: [https://next-blog-prepr.vercel.app/](https://next-blog-prepr.vercel.app/)
- **Preview Mode**: [https://next-blog-prepr.vercel.app/api/preview...](https://next-blog-prepr.vercel.app/api/preview?secret=237864ihasdhj283768&slug=discover-enjoy-amsterdam)
- **Preview**: [https://next-blog-prepr.vercel.app/api/preview...](https://next-blog-prepr.vercel.app/api/preview?secret=237864ihasdhj283768&slug=blueberry-cheesecake)
### [https://next-blog-prepr.vercel.app/](https://next-blog-prepr.vercel.app/)
## How to use
### Related examples
Run one of the following [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) commands using [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to create a new Next.js app and connect it to Prepr:
```bash
npx create-next-app --example cms-prepr cms-prepr-app
```
```bash
yarn create next-app --example cms-prepr cms-prepr-app
```
```bash
pnpm create next-app --example cms-prepr cms-prepr-app
```
## Configuration
### Step 1. Set up Prepr
**1.1** First, [sign up for a Prepr account](https://signup.prepr.io/).
**1.2** After you sign up, create a new environment in Prepr. For more details, [check out the environment docs](https://docs.prepr.io/developing-with-prepr/set-up-environments).
![Create Prepr environment](https://assets-site.prepr.io//1bynxkn1084r-create-enviroment.png)
**1.3** Once youve created the environment, choose to **Load demo data**. With that, Prepr will automatically upload sample models, content items, and other data you can use for your example Next.js app.
![Load Prepr demo data](https://assets-site.prepr.io//2xrbs9aquhij-import-demo-data.png)
### Step 2. Set up environment variables
Once youve set up your Prepr environment, you can define environment variables for your project. Please proceed with the steps below.
**2.1** Run the following command to copy and rename the `.env.local.example` file as follows:
```bash
cp .env.local.example .env.local
```
The `.env.local` file will be ignored by Git.
**2.2** In your environment, navigate to **Settings > Access Tokens**. You will see the automatically generated access tokens for your Prepr environment.
![Access tokens](https://assets-site.prepr.io//6jouln4xi3wp-default-access-tokens.png)
Copy the _GraphQL Production_ access token and paste it as the `PREPRIO_PRODUCTION_TOKEN` variable in `.env.local`. Then copy and paste the _GraphQL Preview_ access token as the `PREPRIO_PREVIEW_TOKEN` variable.
Alternatively, you can create access tokens yourself by clicking **Add access token**. If so, make sure to [choose the right GraphQL permissions](https://docs.prepr.io/reference/graphql/v1/authorization) for the access tokens.
**2.3** Set a custom value with no spaces as the `PREPRIO_PREVIEW_SECRET` variable, for example, a UUID. This value will be used to enable [preview mode](https://nextjs.org/docs/advanced-features/preview-mode).
Once done, your `.env.local` file should look like this:
```bash
PREPRIO_API=https://graphql.prepr.io/graphql
PREPRIO_PRODUCTION_TOKEN='your Production access token'
PREPRIO_PREVIEW_TOKEN='your Preview access token'
PREPRIO_PREVIEW_SECRET='your secret id'
```
### Step 3. Run Next.js in development mode
Now that you've finished preparing the project, you may proceed to run it.
**3.1** Execute one of the following commands to install the packages listed in the `package.json` file:
```bash
npm install
```
```bash
yarn install
```
**3.2** Execute one of the following commands to run the dev script defined in the `package.json` file:
```bash
npm run dev
```
```bash
yarn dev
```
Your example Blog website should be up and running on [http://localhost:3000](http://localhost:3000). If it doesn't work, please post on [GitHub discussions](https://github.com/vercel/next.js/discussions).
### Step 4. Optional: Try Preview mode
Great progress has been made! You are just a few steps away from getting your example website live.
Before proceeding, you can test how the content preview works in Prepr. This step is optional. Proceed to Step 5 if you dont want to use preview mode.
To try preview mode, follow these steps:
**4.1** In Prepr, go to one of the content items of the _Article model_ and update the item title. For example, you can add _[PREVIEW]_ in front of the title. After you edit the content item, save it with the _Review status_.
**4.2** To preview the content item, transform its URL to the following format:
`http://localhost:3000/api/preview?secret=<PREPRIO_PREVIEW_SECRET>&slug=<SLUG_TO_PREVIEW>`,
where:
- `<PREPRIO_PREVIEW_SECRET>` is the same preview secret you defined in the `.env.local` file;
- `<SLUG_TO_PREVIEW>` is the slug of the content item you want to preview.
**Note:** To exit the preview mode, you must click on **Click here to exit preview mode** at the top of the page.
![Preview content item](https://assets-site.prepr.io//4hd7vgoyke24-web-page.png)
### Step 5. Deploy on Vercel
To make your Next.js app available online, deploy it to the cloud using [Vercel](https://vercel.com/?utm_source=github&utm_medium=readme&utm_campaign=next-example). Vercel provides a user-friendly platform for deploying and managing web applications. For more information, please [refer to the Next.js documentation](https://nextjs.org/docs/deployment).
You can go for one of the following options:
- **Deploy your local project**</br>
To deploy your local project to Vercel, push it to GitHub/GitLab/Bitbucket and [import it to Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example).
**Important:** When you import your project on Vercel, make sure to click on **Environment Variables** and set them to match your `.env.local` file.
- **Deploy from our template**</br>
Alternatively, you can deploy using our template by clicking on the **Deploy** button below.
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/vercel/next.js/tree/canary/examples/cms-prepr&project-name=cms-prepr&repository-name=cms-prepr&env=PREPRIO_API,PREPRIO_PRODUCTION_TOKEN,PREPRIO_PREVIEW_TOKEN,PREPRIO_PREVIEW_SECRET&envDescription=Required%20to%20connect%20the%20app%20with%20Prepr&envLink=https://vercel.link/cms-prepr-env)
## Next steps
For more advanced topics, please refer to the Preprs documentation:
- [A/B testing](https://docs.prepr.io/optimization-and-personalization/ab-testing)
- [Personalization](https://docs.prepr.io/optimization-and-personalization/personalized-stack)
- [Recommendations](https://docs.prepr.io/optimization-and-personalization/recommendations)
If you have questions, please [get in touch](https://prepr.io/get-in-touch) with one of our specialists or [join our Slack community](https://slack.prepr.io/).
## Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
@ -28,110 +162,3 @@ This example showcases Next.js's [Static Generation](https://nextjs.org/docs/bas
- [Blog Starter](/examples/blog-starter)
- [DotCMS](/examples/cms-dotcms)
- [Enterspeed](/examples/cms-enterspeed)
## Getting Started
Once you have access to [the environment variables you'll need](#step-3-set-up-environment-variables), deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/vercel/next.js/tree/canary/examples/cms-prepr&project-name=cms-prepr&repository-name=cms-prepr&env=PREPRIO_API,PREPRIO_PRODUCTION_TOKEN,PREPRIO_PREVIEW_TOKEN,PREPRIO_PREVIEW_KEY&envDescription=Required%20to%20connect%20the%20app%20with%20Prepr&envLink=https://vercel.link/cms-prepr-env)
## How to use
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example:
```bash
npx create-next-app --example cms-prepr cms-prepr-app
```
```bash
yarn create next-app --example cms-prepr cms-prepr-app
```
```bash
pnpm create next-app --example cms-prepr cms-prepr-app
```
## Configuration
### Step 1. Create an account and a environment in Prepr
First, [create an account in Prepr](https://prepr.io).
### Step 2. Create Author model
From your Prepr dashboard, click **Settings** -> **Models**
Click on the arrow next to **Add model** and select **Import**.
Import the [`models/author.json`](models/author.json) file.
After that
Import the [`models/post.json`](models/post.json) file.
### Step 3. Set up environment variables (for production)
Copy the `.env.local.example` file in this directory to `.env.local` (which will be ignored by Git):
```bash
cp .env.local.example .env.local
```
Inside your environment, navigate to **Settings > Development > Access Tokens**.
Click **Add access token**, enter the name `Next.js Production` and add the scope `graphql_published` and click **Save**.
Copy the generated access token and set the variable `PREPRIO_PRODUCTION_TOKEN` in `.env.local`.
### Step 3.1 Set up environment variables (for preview)
Go back to the Access token overview and click **Add access token**.
Click **Add access token**, enter the name `Next.js Preview` and add the scope `graphql_preview` and click **Save**.
Copy the generated access token and set the variable `PREPRIO_PREVIEW_TOKEN` in `.env.local`.
The `PREPRIO_PREVIEW_KEY` can be any random string (but avoid spaces), like a UUID`, this is used
for [Preview Mode](https://nextjs.org/docs/advanced-features/preview-mode).
### Step 4. Run Next.js in development mode
```bash
npm install
npm run dev
# or
yarn install
yarn dev
```
Your blog should be up and running on [http://localhost:3000](http://localhost:3000)! If it doesn't work, post on [GitHub discussions](https://github.com/vercel/next.js/discussions).
### Step 5. Try preview mode
In Prepr, go to one of the posts in your environment and:
- **Update the title**. For example, you can add `[REVIEW]` in front of the title.
- After you edit the publication save the post with a review state.
To view the preview, transform the url to the following format: `http://localhost:3000/api/preview?secret=<YOUR_SECRET_TOKEN>&slug=<SLUG_TO_PREVIEW>` where `<YOUR_SECRET_TOKEN>` is
the same secret you defined in the `.env.local` file and `<SLUG_TO_PREVIEW>` is the slug of one of the posts you want to preview.
You should now be able to see post that are in Review and Done state. To exit the preview mode, you can click on _"Click here to exit preview mode"_ at the top.
### Step 6. Deploy on Vercel
You can deploy this app to the cloud with [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
#### Deploy Your Local Project
To deploy your local project to Vercel, push it to GitHub/GitLab/Bitbucket and [import to Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example).
**Important**: When you import your project on Vercel, make sure to click on **Environment Variables** and set them to match your `.env.local` file.
#### Deploy from Our Template
Alternatively, you can deploy using our template by clicking on the Deploy button below.
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/vercel/next.js/tree/canary/examples/cms-prepr&project-name=cms-prepr&repository-name=cms-prepr&env=PREPRIO_API,PREPRIO_PRODUCTION_TOKEN,PREPRIO_PREVIEW_TOKEN,PREPRIO_PREVIEW_KEY&envDescription=Required%20to%20connect%20the%20app%20with%20Prepr&envLink=https://vercel.link/cms-prepr-env)

View file

@ -1,6 +1,6 @@
import Container from './container'
import cn from 'classnames'
import { EXAMPLE_PATH } from '../lib/constants'
import { EXAMPLE_PATH } from '@/lib/constants'
export default function Alert({ preview }) {
return (
@ -14,7 +14,7 @@ export default function Alert({ preview }) {
<div className="py-2 text-center text-sm">
{preview ? (
<>
This page is a preview.{' '}
This is page is a preview.{' '}
<a
href="/api/exit-preview"
className="underline hover:text-cyan duration-200 transition-colors"

View file

@ -1,6 +1,6 @@
import cn from 'classnames'
import Image from 'next/image'
import Link from 'next/link'
import cn from 'classnames'
export default function CoverImage({ title, url, slug }) {
const image = (
@ -8,13 +8,12 @@ export default function CoverImage({ title, url, slug }) {
width={2000}
height={1000}
alt={`Cover Image for ${title}`}
src={url}
className={cn('shadow-small', {
'hover:shadow-medium transition-shadow duration-200': slug,
})}
src={url}
/>
)
return (
<div className="sm:mx-0">
{slug ? (

View file

@ -1,6 +1,5 @@
import { parseISO, format } from 'date-fns'
export default function Date({ dateString }) {
const date = parseISO(dateString)
return <time dateTime={dateString}>{format(date, 'LLLL d, yyyy')}</time>
return <time dateTime={date}>{format(date, 'LLLL d, yyyy')}</time>
}

View file

@ -1,5 +1,5 @@
import Container from './container'
import { EXAMPLE_PATH } from '../lib/constants'
import { EXAMPLE_PATH } from '@/lib/constants'
export default function Footer() {
return (

View file

@ -1,6 +1,6 @@
import Avatar from '../components/avatar'
import Date from '../components/date'
import CoverImage from '../components/cover-image'
import Avatar from './avatar'
import Date from './date'
import CoverImage from './cover-image'
import Link from 'next/link'
export default function HeroPost({
@ -14,25 +14,27 @@ export default function HeroPost({
return (
<section>
<div className="mb-8 md:mb-16">
<CoverImage slug={slug} title={title} url={coverImage} />
<CoverImage title={title} url={coverImage} slug={slug} />
</div>
<div className="mb-20 md:grid md:grid-cols-2 md:gap-x-16 lg:gap-x-8 md:mb-28">
<div className="md:grid md:grid-cols-2 md:gap-x-16 lg:gap-x-8 mb-20 md:mb-28">
<div>
<h3 className="mb-4 text-4xl leading-tight lg:text-6xl">
<h3 className="mb-4 text-4xl lg:text-6xl leading-tight">
<Link href={`/posts/${slug}`} className="hover:underline">
{title}
</Link>
</h3>
<div className="mb-4 text-lg md:mb-0">
<Date dateString={date} />
</div>
{date && (
<div className="mb-4 md:mb-0 text-lg">
<Date dateString={date} />
</div>
)}
</div>
<div>
<p className="mb-4 text-lg leading-relaxed">{excerpt}</p>
<Avatar
name={author.name}
picture={author.cover[0].cdn_files[0].url}
/>
<div
className="text-lg leading-relaxed mb-4"
dangerouslySetInnerHTML={{ __html: excerpt }}
></div>
<Avatar name={author.full_name} picture={author.profile_pic[0].url} />
</div>
</div>
</section>

View file

@ -1,4 +1,4 @@
import { CMS_NAME, CMS_URL } from '../lib/constants'
import { CMS_NAME, CMS_URL } from '@/lib/constants'
export default function Intro() {
return (

View file

@ -1,6 +1,6 @@
import Alert from '../components/alert'
import Footer from '../components/footer'
import Meta from '../components/meta'
import Alert from './alert'
import Footer from './footer'
import Meta from './meta'
export default function Layout({ preview, children }) {
return (

View file

@ -0,0 +1,18 @@
.markdown {
@apply text-lg leading-relaxed;
}
.markdown p,
.markdown ul,
.markdown ol,
.markdown blockquote {
@apply my-6;
}
.markdown h2 {
@apply text-3xl mt-12 mb-4 leading-snug;
}
.markdown h3 {
@apply text-2xl mt-8 mb-4 leading-snug;
}

View file

@ -1,5 +1,5 @@
import Head from 'next/head'
import { CMS_NAME, HOME_OG_IMAGE_URL } from '../lib/constants'
import { CMS_NAME, HOME_OG_IMAGE_URL } from '@/lib/constants'
export default function Meta() {
return (

View file

@ -1,4 +1,4 @@
import PostPreview from '../components/post-preview'
import PostPreview from './post-preview'
export default function MoreStories({ posts }) {
return (
@ -11,11 +11,11 @@ export default function MoreStories({ posts }) {
<PostPreview
key={post._slug}
title={post.title}
coverImage={post.cover[0].cdn_files[0].url}
date={post.date}
author={post.author[0]}
coverImage={post.cover[0].url}
date={post._publish_on}
author={post.authors[0]}
slug={post._slug}
excerpt={post.summary}
excerpt={post.excerpt}
/>
))}
</div>

View file

@ -1,10 +1,15 @@
import postStyles from './post-styles.module.css'
import Image from 'next/image'
export default function PostBody({ content }) {
return (
<div
className={`max-w-2xl mx-auto post ${postStyles.post}`}
dangerouslySetInnerHTML={{ __html: content }}
/>
)
const renderedContent = content.map((item) => {
if (item.__typename === 'Text') {
return <div dangerouslySetInnerHTML={{ __html: item.html }}></div>
} else if (item.__typename === 'Image') {
return <Image src={item.url} alt="image" width={1000} height={500} />
} else {
return null
}
})
return <div className="max-w-2xl mx-auto article">{renderedContent}</div>
}

View file

@ -8,21 +8,20 @@ export default function PostHeader({ title, coverImage, date, author }) {
<>
<PostTitle>{title}</PostTitle>
<div className="hidden md:block md:mb-12">
<Avatar name={author.name} picture={author.cover[0].cdn_files[0].url} />
<Avatar name={author.full_name} picture={author.profile_pic[0].url} />
</div>
<div className="mb-8 -mx-5 md:mb-16 sm:mx-0">
<div className="mb-8 md:mb-16 sm:mx-0">
<CoverImage title={title} url={coverImage} />
</div>
<div className="max-w-2xl mx-auto">
<div className="block mb-6 md:hidden">
<Avatar
name={author.name}
picture={author.cover[0].cdn_files[0].url}
/>
</div>
<div className="mb-6 text-lg">
<Date dateString={date} />
<div className="block md:hidden mb-6">
<Avatar name={author.full_name} picture={author.profile_pic[0].url} />
</div>
{date && (
<div className="mb-6 text-lg">
<Date dateString={date} />
</div>
)}
</div>
</>
)

View file

@ -1,5 +1,5 @@
import Avatar from '../components/avatar'
import Date from '../components/date'
import Avatar from './avatar'
import Date from './date'
import CoverImage from './cover-image'
import Link from 'next/link'
@ -16,16 +16,21 @@ export default function PostPreview({
<div className="mb-5">
<CoverImage slug={slug} title={title} url={coverImage} />
</div>
<h3 className="mb-3 text-3xl leading-snug">
<h3 className="text-3xl mb-3 leading-snug">
<Link href={`/posts/${slug}`} className="hover:underline">
{title}
</Link>
</h3>
<div className="mb-4 text-lg">
<Date dateString={date} />
</div>
<p className="mb-4 text-lg leading-relaxed">{excerpt}</p>
<Avatar name={author.name} picture={author.cover[0].cdn_files[0].url} />
{date && (
<div className="text-lg mb-4">
<Date dateString={date} />
</div>
)}
<div
className="text-lg leading-relaxed mb-4"
dangerouslySetInnerHTML={{ __html: excerpt }}
></div>
<Avatar name={author.full_name} picture={author.profile_pic[0].url} />
</div>
)
}

View file

@ -1,22 +0,0 @@
.post {
@apply text-lg leading-relaxed;
}
.post p,
.post ul,
.post ol,
.post blockquote {
@apply my-6;
}
.post h1 {
@apply mt-12 mb-4 text-4xl leading-snug;
}
.post h2 {
@apply mt-12 mb-4 text-3xl leading-snug;
}
.post h3 {
@apply mt-8 mb-4 text-2xl leading-snug;
}

View file

@ -1,5 +1,10 @@
{
"compilerOptions": {
"baseUrl": "."
"baseUrl": ".",
"paths": {
"@/components/*": ["components/*"],
"@/lib/*": ["lib/*"],
"@/styles/*": ["styles/*"]
}
}
}

View file

@ -0,0 +1,165 @@
async function fetchAPI(query, { variables, preview } = {}) {
const response = await fetch(process.env.PREPRIO_API, {
method: 'POST',
headers: {
Authorization:
'Bearer ' +
(preview
? process.env.PREPRIO_PREVIEW_TOKEN
: process.env.PREPRIO_PRODUCTION_TOKEN),
},
body: JSON.stringify({
query,
variables,
}),
})
const result = await response.json()
return result
}
export async function getPreviewPostBySlug(slug) {
const { data } = await fetchAPI(
`
query ArticleBySlug($slug: String!) {
Article(slug: $slug) {
_slug
}
}
`,
{
preview: true,
variables: {
slug,
},
}
)
return data.Article
}
export async function getAllPostsWithSlug() {
const { data } = await fetchAPI(
`
{
Articles {
items {
_slug
}
}
}
`,
{ preview: true }
)
return data?.Articles.items
}
export async function getAllPostsForHome(preview) {
const { data } = await fetchAPI(
`
{
Articles(sort: publish_on_DESC) {
items {
_id
_slug
_publish_on
title
excerpt
content {
...on Text {
html
text
}
}
authors {
full_name
profile_pic {
url
}
}
cover {
url(preset: "square")
}
}
}
}
`,
{ preview }
)
return data?.Articles.items
}
export async function getPostAndMorePosts(slug, preview) {
const { data } = await fetchAPI(
`
query ArticlesBySlug($slug: String!) {
Article(slug: $slug) {
_id
_slug
_publish_on
title
excerpt
content {
__typename
... on Text {
html
text
}
... on Assets {
items {
url
}
}
}
authors {
full_name
profile_pic {
url
}
}
cover {
url(preset: "square")
}
}
MoreArticles: Articles(limit: 3, sort: publish_on_DESC) {
items {
_id
_slug
_publish_on
title
excerpt
cover {
url(preset: "square")
}
content {
... on Text {
html
text
}
}
authors {
full_name
profile_pic {
url
}
}
}
}
}
`,
{
preview,
variables: {
slug,
},
}
)
return {
post: data?.Article,
morePosts: (data?.MoreArticles?.items || [])
.filter((item) => item._slug !== slug)
.slice(0, 2),
}
}

View file

@ -1,156 +0,0 @@
import { createPreprClient } from '@preprio/nodejs-sdk'
const prepr = createPreprClient({
token: process.env.PREPRIO_PRODUCTION_TOKEN,
timeout: 4000,
baseUrl: process.env.PREPRIO_API,
})
export { prepr }
export async function getAllPostsForHome(preview) {
// Query publications
const data =
(await prepr
.graphqlQuery(
`
query {
Posts {
items {
_id,
_slug,
date: _publish_on
title,
summary,
author {
name
cover {
cdn_files {
url(width: 100, height:100)
}
}
}
cover {
cdn_files {
url(width:2000, height:1000)
}
}
}
}
}`
)
.token(
preview
? process.env.PREPRIO_PREVIEW_TOKEN
: process.env.PREPRIO_PRODUCTION_TOKEN
)
.fetch()) || []
return data.data.Posts.items
}
export async function getAllPostsWithSlug() {
// Query publications
const data =
(await prepr
.graphqlQuery(
`
query {
Posts {
items {
slug : _slug,
}
}
}`
)
.fetch()) || []
return data.data.Posts.items
}
export async function getPostAndMorePosts(slug, preview) {
// Query publications
const data =
(await prepr
.graphqlQuery(
`
query slugPost($slug: String!) {
Post ( slug : $slug) {
_id,
_slug,
date: _publish_on
title,
summary,
content,
author {
name
cover {
cdn_files {
url(width: 100, height:100)
}
}
}
cover {
cdn_files {
url(width:2000, height:1000)
}
}
}
morePosts : Posts(where : { _slug_nany : [$slug] }) {
items {
_id,
_slug,
date: _publish_on
title,
summary,
author {
name
cover {
cdn_files {
url(width: 100, height:100)
}
}
}
cover {
cdn_files {
url(width:2000, height:1000)
}
}
}
}
}`
)
.graphqlVariables({
slug: slug,
})
.token(
preview
? process.env.PREPRIO_PREVIEW_TOKEN
: process.env.PREPRIO_PRODUCTION_TOKEN
)
.fetch()) || []
return data.data
}
export async function getPreviewPostBySlug(slug) {
// Query publications
const data =
(await prepr
.graphqlQuery(
`
query preview($slug: String!) {
Post ( slug : $slug) {
_id,
slug : _slug
}
}`
)
.token(process.env.PREPRIO_PREVIEW_TOKEN)
.graphqlVariables({
slug: slug,
})
.fetch()) || []
return data.data.Post
}

View file

@ -1,67 +0,0 @@
{
"id": "f7153965-7bc9-4b9b-b964-49129b34c5e8",
"created_on": "2021-03-04T12:03:46+00:00",
"changed_on": "2021-03-04T12:03:46+00:00",
"body": "Author",
"description": null,
"label": "PublicationModel",
"status": "published",
"stories": false,
"timelines": false,
"allow_stories": false,
"channels": false,
"allow_channels": false,
"container_required": false,
"channels_required": false,
"seo_score": false,
"ab_testing": false,
"versioning": false,
"slug": null,
"for": null,
"fields": [
{
"type": "Text",
"required": false,
"preview": true,
"body": "Name",
"view": "single_line",
"localized": true,
"id": "fd7f062f-84e4-4362-9e15-61c1a26a4078",
"api_id": "name",
"created_on": "2021-03-04T12:03:55+00:00",
"changed_on": "2021-03-04T12:03:55+00:00",
"label": "PublicationModelField",
"title": false,
"seo_title": false,
"seo_description": false,
"description": null,
"disable_editing": false,
"appearance": "single_line",
"accept_restrictions": null,
"no_html": false
},
{
"accept": ["photo"],
"max": "1",
"preview": true,
"type": "Asset",
"min": "1",
"required": true,
"body": "Cover Image",
"localized": true,
"id": "fd81a8e2-2f59-44b7-b3b2-873a27958db1",
"api_id": "cover",
"created_on": "2021-03-04T12:04:13+00:00",
"changed_on": "2021-03-04T12:04:13+00:00",
"label": "PublicationModelField",
"title": false,
"seo_title": false,
"seo_description": false,
"description": null,
"disable_editing": false,
"appearance": null,
"accept_restrictions": null,
"presets_change_required": false
}
]
}

View file

@ -1,167 +0,0 @@
{
"id": "4da8ca3d-86c2-40ba-84c0-5ea949293b9b",
"created_on": "2021-03-04T12:02:44+00:00",
"changed_on": "2021-03-04T12:10:37+00:00",
"body": "Post",
"description": null,
"label": "PublicationModel",
"status": "published",
"stories": false,
"timelines": false,
"allow_stories": false,
"channels": false,
"allow_channels": false,
"container_required": false,
"channels_required": false,
"seo_score": false,
"ab_testing": false,
"versioning": false,
"slug": "{title}",
"for": null,
"fields": [
{
"type": "Text",
"required": false,
"preview": true,
"body": "Title",
"view": "single_line",
"localized": true,
"id": "7aa96451-d3b5-41e9-b012-77f66dd2213b",
"api_id": "title",
"created_on": "2021-03-04T12:02:49+00:00",
"changed_on": "2021-03-04T12:02:49+00:00",
"label": "PublicationModelField",
"title": false,
"seo_title": false,
"seo_description": false,
"description": null,
"disable_editing": false,
"appearance": "single_line",
"accept_restrictions": null,
"no_html": false
},
{
"type": "Text",
"required": false,
"preview": true,
"body": "Summary",
"view": "textarea",
"localized": true,
"id": "ea6a35ca-5a39-4786-9cf7-15e917a0dcf4",
"api_id": "summary",
"created_on": "2021-03-04T12:02:59+00:00",
"changed_on": "2021-03-04T12:02:59+00:00",
"label": "PublicationModelField",
"title": false,
"seo_title": false,
"seo_description": false,
"description": null,
"disable_editing": false,
"appearance": "textarea",
"accept_restrictions": null,
"no_html": false
},
{
"accept": [
"bold",
"italic",
"underline",
"unordered-list",
"ordered-list",
"link",
"table"
],
"preview": true,
"view": "html_editor",
"type": "Text",
"required": false,
"body": "Content",
"localized": true,
"id": "cd31e930-a08c-4740-903e-5c41fcd1c555",
"api_id": "content",
"created_on": "2021-03-04T12:04:36+00:00",
"changed_on": "2021-03-04T12:04:36+00:00",
"label": "PublicationModelField",
"title": false,
"seo_title": false,
"seo_description": false,
"description": null,
"disable_editing": false,
"appearance": "html_editor",
"accept_restrictions": null,
"no_html": false
},
{
"accept": ["photo"],
"max": "1",
"preview": true,
"type": "Asset",
"min": "1",
"required": true,
"body": "Cover Image",
"localized": true,
"id": "cfca83f3-5a73-4567-bde1-4adeb57915d0",
"api_id": "cover",
"created_on": "2021-03-04T12:03:17+00:00",
"changed_on": "2021-03-04T12:03:17+00:00",
"label": "PublicationModelField",
"title": false,
"seo_title": false,
"seo_description": false,
"description": null,
"disable_editing": false,
"appearance": null,
"accept_restrictions": null,
"presets_change_required": false
},
{
"type": "Publication",
"min": "1",
"required": true,
"max": "1",
"preview": false,
"body": "Author",
"localized": true,
"id": "8308380f-af0a-40e7-ae30-33b2f7ce93d9",
"api_id": "author",
"created_on": "2021-03-04T12:04:51+00:00",
"changed_on": "2021-03-04T12:04:51+00:00",
"label": "PublicationModelField",
"title": false,
"seo_title": false,
"seo_description": false,
"description": null,
"disable_editing": false,
"appearance": null,
"accept_restrictions": null,
"publication_models": {
"items": [
{
"id": "7214e365-1b4c-4de3-8412-e311250fb4da",
"body": "Author"
}
],
"total": 1
}
},
{
"type": "Slug",
"description": "The slug is generated automatically. You can change the slug, as long as it is unique.",
"body": "Slug",
"id": "7214e365-1b4c-4de3-8412-e311250fb4da",
"api_id": null,
"created_on": "2021-03-04T12:03:32+00:00",
"changed_on": "2021-03-04T12:03:32+00:00",
"label": "PublicationModelField",
"title": false,
"seo_title": false,
"seo_description": false,
"required": false,
"localized": false,
"preview": false,
"disable_editing": false,
"appearance": null,
"accept_restrictions": null
}
]
}

View file

@ -1,6 +1,10 @@
/** @type {import('next').NextConfig} */
module.exports = {
images: {
domains: ['b-cdn.net'],
domains: [
'b-cdn.net',
'prepr-example-content-demo-patterns.stream.prepr.io',
'demo-site-patterns.stream.prepr.io',
],
},
}

View file

@ -6,7 +6,6 @@
"start": "next start"
},
"dependencies": {
"@preprio/nodejs-sdk": "^1.1.0",
"classnames": "2.3.1",
"date-fns": "2.28.0",
"next": "latest",

View file

@ -1,4 +1,4 @@
import '../styles/index.css'
import '@/styles/index.css'
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />

View file

@ -1,9 +1,13 @@
import { getPreviewPostBySlug } from '../../lib/preprio'
import { getPreviewPostBySlug } from '../../lib/api'
export default async function handler(req, res) {
// Check the secret and next parameters
// This secret should only be known to this API route and the CMS
if (req.query.secret !== process.env.PREPRIO_PREVIEW_KEY || !req.query.slug) {
if (
req.query.secret !== process.env.PREPRIO_PREVIEW_SECRET ||
!req.query.slug
) {
return res.status(401).json({ message: 'Invalid token' })
}
@ -20,6 +24,6 @@ export default async function handler(req, res) {
// Redirect to the path from the fetched post
// We don't redirect to req.query.slug as that might lead to open redirect vulnerabilities
res.writeHead(307, { Location: `/posts/${post.slug}` })
res.writeHead(307, { Location: `/posts/${post._slug}` })
res.end()
}

View file

@ -1,15 +1,16 @@
import Container from '../components/container'
import MoreStories from '../components/more-stories'
import HeroPost from '../components/hero-post'
import Intro from '../components/intro'
import Layout from '../components/layout'
import { getAllPostsForHome } from '../lib/preprio'
import Container from '@/components/container'
import MoreStories from '@/components/more-stories'
import HeroPost from '@/components/hero-post'
import Intro from '@/components/intro'
import Layout from '@/components/layout'
import { getAllPostsForHome } from '@/lib/api'
import Head from 'next/head'
import { CMS_NAME } from '../lib/constants'
import { CMS_NAME } from '@/lib/constants'
export default function Index({ posts, preview }) {
const heroPost = posts[0]
const morePosts = posts.slice(1)
export default function Index({ allPosts, preview }) {
const heroPost = allPosts[0]
const morePosts = allPosts.slice(1)
return (
<>
<Layout preview={preview}>
@ -21,11 +22,11 @@ export default function Index({ posts, preview }) {
{heroPost && (
<HeroPost
title={heroPost.title}
coverImage={heroPost.cover[0].cdn_files[0].url}
date={heroPost.date}
author={heroPost.author[0]}
coverImage={heroPost.cover[0].url}
date={heroPost._publish_on}
author={heroPost.authors[0]}
slug={heroPost._slug}
excerpt={heroPost.summary}
excerpt={heroPost.excerpt}
/>
)}
{morePosts.length > 0 && <MoreStories posts={morePosts} />}
@ -35,10 +36,9 @@ export default function Index({ posts, preview }) {
)
}
export async function getStaticProps({ preview = false }) {
const posts = (await getAllPostsForHome(preview)) || []
export async function getStaticProps({ preview = null }) {
const allPosts = (await getAllPostsForHome(preview)) || []
return {
props: { posts, preview },
props: { allPosts, preview },
}
}

View file

@ -1,24 +1,22 @@
import { useRouter } from 'next/router'
import ErrorPage from 'next/error'
import Container from 'components/container'
import PostBody from 'components/post-body'
import MoreStories from 'components/more-stories'
import Header from 'components/header'
import PostHeader from 'components/post-header'
import SectionSeparator from 'components/section-separator'
import Layout from 'components/layout'
import { getAllPostsWithSlug, getPostAndMorePosts } from 'lib/preprio'
import PostTitle from 'components/post-title'
import Container from '@/components/container'
import PostBody from '@/components/post-body'
import MoreStories from '@/components/more-stories'
import Header from '@/components/header'
import PostHeader from '@/components/post-header'
import SectionSeparator from '@/components/section-separator'
import Layout from '@/components/layout'
import { getAllPostsWithSlug, getPostAndMorePosts } from '@/lib/api'
import PostTitle from '@/components/post-title'
import Head from 'next/head'
import { CMS_NAME } from 'lib/constants'
import { CMS_NAME } from '@/lib/constants'
export default function Post({ post, morePosts, preview }) {
const router = useRouter()
if (!router.isFallback && !post?._slug) {
return <ErrorPage statusCode={404} />
}
return (
<Layout preview={preview}>
<Container>
@ -30,15 +28,15 @@ export default function Post({ post, morePosts, preview }) {
<article>
<Head>
<title>
{`${post.title} | Next.js Blog Example with ${CMS_NAME}`}
{post.title} | Next.js Blog Example with {CMS_NAME}
</title>
{/* <meta property="og:image" content={post.ogImage.url} /> */}
<meta property="og:image" content={post.cover[0].url} />
</Head>
<PostHeader
title={post.title}
coverImage={post.cover[0].cdn_files[0].url}
date={post.date}
author={post.author[0]}
coverImage={post.cover[0].url}
date={post._publish_on}
author={post.authors[0]}
/>
<PostBody content={post.content} />
</article>
@ -52,24 +50,26 @@ export default function Post({ post, morePosts, preview }) {
}
export async function getStaticProps({ params, preview = false }) {
const data = await getPostAndMorePosts(params.slug, preview)
const { post, morePosts } = await getPostAndMorePosts(params.slug, preview)
return {
props: {
preview,
post: data.Post,
morePosts: data.morePosts.items || [],
post,
morePosts,
},
}
}
export async function getStaticPaths() {
const posts = await getAllPostsWithSlug()
const allPosts = await getAllPostsWithSlug()
const paths = allPosts.map((post) => ({
params: { slug: post._slug },
}))
return {
paths: posts.map(({ slug }) => ({
params: { slug },
})),
paths,
fallback: true,
}
}

View file

@ -1,5 +1,31 @@
/* purgecss start ignore */
@tailwind base;
@tailwind components;
/* purgecss end ignore */
@tailwind utilities;
@layer components {
.article h2 {
@apply mb-5 text-4xl font-bold leading-tight;
}
.article p,
.article ul,
.article ol {
@apply mb-5;
}
.article ol {
@apply ml-5 list-decimal list-outside;
}
.article ul {
@apply ml-5 list-disc list-outside;
}
.article a {
@apply underline;
}
.article ol li {
@apply mb-4;
}
}

View file

@ -14,23 +14,28 @@ Once you have access to [the environment variables you'll need](#step-5-set-up-e
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [Kontent](/examples/cms-kontent)
- [Ghost](/examples/cms-ghost)
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
- [Blog Starter](/examples/blog-starter)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## How to use

View file

@ -15,24 +15,28 @@ You'll get:
## Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Ghost](/examples/cms-ghost)
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
- [Blog Starter](/examples/blog-starter)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
# Configuration

View file

@ -15,22 +15,28 @@ Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_mediu
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [TinaCMS](/examples/cms-tina/)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## How to use

View file

@ -14,24 +14,28 @@ Once you have access to [the environment variables you'll need](#step-6-set-up-e
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [Strapi](/examples/cms-strapi)
- [ButterCMS](/examples/cms-buttercms)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Ghost](/examples/cms-ghost)
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
- [Blog Starter](/examples/blog-starter)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## How to use

View file

@ -14,23 +14,28 @@ Once you have access to [the environment variables you'll need](#step-5-set-up-e
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Ghost](/examples/cms-ghost)
- [Blog Starter](/examples/blog-starter)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## How to use

View file

@ -15,23 +15,28 @@ Once you have access to [the environment variables you'll need](#step-3-set-up-e
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Ghost](/examples/cms-ghost)
- [Blog Starter](/examples/blog-starter)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## How to use

View file

@ -14,21 +14,28 @@ Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_mediu
### Related examples
- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## How to use

View file

@ -14,22 +14,28 @@ Once you have access to [the environment variables you'll need](#step-3-set-up-e
### Related examples
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Ghost](/examples/cms-ghost)
- [Blog Starter](/examples/blog-starter)
- [AgilityCMS](/examples/cms-agilitycms)
- [Builder.io](/examples/cms-builder-io)
- [ButterCMS](/examples/cms-buttercms)
- [Contentful](/examples/cms-contentful)
- [Cosmic](/examples/cms-cosmic)
- [DatoCMS](/examples/cms-datocms)
- [DotCMS](/examples/cms-dotcms)
- [Drupal](/examples/cms-drupal)
- [Enterspeed](/examples/cms-enterspeed)
- [Ghost](/examples/cms-ghost)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent-ai)
- [Prepr](/examples/cms-prepr)
- [Prismic](/examples/cms-prismic)
- [Sanity](/examples/cms-sanity)
- [Sitefinity](/examples/cms-sitefinity)
- [Storyblok](/examples/cms-storyblok)
- [TakeShape](/examples/cms-takeshape)
- [Umbraco heartcore](/examples/cms-umbraco-heartcore)
- [Webiny](/examples/cms-webiny)
- [Blog Starter](/examples/blog-starter)
- [WordPress](/examples/cms-wordpress)
## How to use