Skip to content

Commit

Permalink
CMS Strapi Example (vercel#12701)
Browse files Browse the repository at this point in the history
* Strapi Example

* Fix og image URL

* Remove next.config.js

* Apply updates

* Remove API_URL

* Bugfixes

* Finish Strapi README

* Deploy Strapi

* Add strapi examples

* now →  vercel [ch1796]

* Use npx

* Minor readme update

* Prettier fix

Co-authored-by: Luis Alvarez <[email protected]>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Jun 1, 2020
1 parent 9ce4655 commit d60fada
Show file tree
Hide file tree
Showing 56 changed files with 1,090 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/advanced-features/preview-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ description: Next.js has the preview mode for statically generated pages. You ca
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-sanity">Sanity Example</a> (<a href="https://next-blog-sanity.now.sh/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-prismic">Prismic Example</a> (<a href="https://next-blog-prismic.now.sh/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-contentful">Contentful Example</a> (<a href="https://next-blog-contentful.now.sh/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-strapi">Strapi Example</a> (<a href="https://next-blog-strapi.now.sh/">Demo</a>)</li>
</ul>
</details>

Expand Down
1 change: 1 addition & 0 deletions docs/basic-features/data-fetching.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ description: 'Next.js has 2 pre-rendering modes: Static Generation and Server-si
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-prismic">Prismic Example</a> (<a href="https://next-blog-prismic.now.sh/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-contentful">Contentful Example</a> (<a href="https://next-blog-contentful.now.sh/">Demo</a>)</li>
<li><a href="https://static-tweet.now.sh/">Static Tweet Demo</a></li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-strapi">Strapi Example</a> (<a href="https://next-blog-strapi.now.sh/">Demo</a>)</li>
</ul>
</details>

Expand Down
1 change: 1 addition & 0 deletions docs/basic-features/pages.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Finally, you can always use **Client-side Rendering** along with Static Generati
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-sanity">Sanity Example</a> (<a href="https://next-blog-sanity.now.sh/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-prismic">Prismic Example</a> (<a href="https://next-blog-prismic.now.sh/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-contentful">Contentful Example</a> (<a href="https://next-blog-contentful.now.sh/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-strapi">Strapi Example</a> (<a href="https://next-blog-strapi.now.sh/">Demo</a>)</li>
<li><a href="https://static-tweet.now.sh/">Static Tweet Demo</a></li>
</ul>
</details>
Expand Down
1 change: 1 addition & 0 deletions examples/blog-starter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ To create the blog posts we use [`remark`](https://github.com/remarkjs/remark) a
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)

## How to use

Expand Down
1 change: 1 addition & 0 deletions examples/cms-contentful/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This example showcases Next.js's [Static Generation](/docs/basic-features/pages.
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Strapi](/examples/cms-strapi)
- [Blog Starter](/examples/blog-starter)

## How to use
Expand Down
1 change: 1 addition & 0 deletions examples/cms-datocms/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This example showcases Next.js's [Static Generation](https://nextjs.org/docs/bas
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Blog Starter](/examples/blog-starter)

## How to use
Expand Down
1 change: 1 addition & 0 deletions examples/cms-prismic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This example showcases Next.js's [Static Generation](/docs/basic-features/pages.
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Blog Starter](/examples/blog-starter)

## How to use
Expand Down
1 change: 1 addition & 0 deletions examples/cms-sanity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This example showcases Next.js's [Static Generation](https://nextjs.org/docs/bas
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Blog Starter](/examples/blog-starter)

## How to use
Expand Down
2 changes: 2 additions & 0 deletions examples/cms-strapi/.env.local.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
NEXT_EXAMPLE_CMS_STRAPI_PREVIEW_SECRET=
NEXT_PUBLIC_API_URL=http://localhost:1337
2 changes: 2 additions & 0 deletions examples/cms-strapi/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.now
.vercel
194 changes: 194 additions & 0 deletions examples/cms-strapi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
# A statically generated blog example using Next.js and Strapi

This example showcases Next.js's [Static Generation](https://nextjs.org/docs/basic-features/pages) feature using [Strapi](https://strapi.io/) as the data source.

## Demo

[https://next-blog-strapi.now.sh/](https://next-blog-strapi.now.sh/)

### Related examples

- [Blog Starter](/examples/blog-starter)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)

## How to use

### Using `create-next-app`

Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:

```bash
npx create-next-app --example cms-strapi cms-strapi-app
# or
yarn create next-app --example cms-strapi cms-strapi-app
```

### Download manually

Download the example:

```bash
curl https://codeload.github.com/vercel/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/cms-strapi
cd cms-strapi
```

## Configuration

### Step 1. Set up Strapi locally

[Follow the instructions on this page](https://strapi.io/documentation/v3.x/installation/cli.html) to create a Strapi project locally.

```bash
npx create-strapi-app my-project --quickstart
npm run develop # or: yarn develop
```

This will open http://localhost:1337/ and prompt you to create an admin user.

### Step 2. Install GraphQL for Strapi

Inside the Strapi directory, stop the server, [install GraphQL](https://strapi.io/documentation/v3.x/plugins/graphql.html), and restart the server:

```bash
# If using Yarn: yarn strapi install graphql
npm run strapi install graphql

npm run dev # or: yarn develop
```

### Step 3. Create an `Author` collection

From **Content-Types Builder**, **create a new collection type**.

- The display name should be `Author`.

Next, add these fields (you don't have to modify the settings):

- **Text** field called **`name`** (**Short text**)
- **Media** field called **`picture`** (**Single media**)

Then click **Save**.

### Step 4. Create a `Post` collection

From **Content-Types Builder**, **create a new collection type**.

- The display name should be `Post`.

Next, add these fields (you don't have to modify the settings unless specified):

- **Text** field called **`title`** (**Short text**)
- **Rich Text** field called **`content`** (**Multiple-paragraph Text**)
- **Text** field called **`excerpt`** (**Long text**)
- **Media** field called **`coverImage`** (**Single media**)
- **Date** field called **`date`** (type should be **date**)
- **UID** field called **`slug`** (attached field should be **title**)
- **Relation** field called **`author`** (Post **has one** Author)
- **Enumeration** field `status` (the values should be **published** and **draft**)

### Step 5. Set permissions

From **Roles & Permissions**, edit the **Public** role.

Then select: `count`, `find`, and `findone` permissions for both **Author** and **Post**. Click **Save**.

### Step 6. Populate Content

Select **Author** and click **Add New Author**.

- You just need **1 Author entry**.
- Use dummy data for the name.
- For the image, you can download one from [Unsplash](https://unsplash.com/).

Next, select **Posts** and click **Add New Post**.

- We recommend creating at least **2 Post records**.
- Use dummy data for the text.
- You can write markdown for the **content** field.
- For the images, you can download ones from [Unsplash](https://unsplash.com/).
- Pick the **Author** you created earlier.
- Set the **status** field to be **published**.

### Step 7. Set up environment variables

While the Strapi server is running, open a new terminal and `cd` into the Next.js app directory you created earlier.

```
cd cms-strapi-app
```

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
```

Then set each variable on `.env.local`:

- `NEXT_EXAMPLE_CMS_STRAPI_PREVIEW_SECRET` can be any random string (but avoid spaces), like `MY_SECRET` - this is used for [Preview Mode](https://nextjs.org/docs/advanced-features/preview-mode).
- `NEXT_PUBLIC_API_URL` should be set as `http://localhost:1337` (no trailing slash).

### Step 8. Run Next.js in development mode

Make sure that the local Strapi server is still running at http://localhost:1337. Inside the Next.js app directory, run:

```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)! You should see the two posts you’ve created. If it doesn't work, make sure that:

- You’ve installed GraphQL to Strapi on Step 2.
- You’ve set the Roles & Permissions in Step 5.
- You’ve set the `status` of each post to be `published` in Step 6.

The best place to debug is inside the `fetchAPI` function in `lib/api.js`. If you still need help, you can post on [GitHub discussions](https://github.com/vercel/next.js/discussions).

### Step 9. Try preview mode

To try preview mode, create another post like before, but:

- Set the **title** as `Draft Post Test`
- Set the **status** as `draft`.

Now, if you go to the post page on localhost, you won't see this post because it’s not published. However, if you use the **Preview Mode**, you'll be able to see the change ([Documentation](https://nextjs.org/docs/advanced-features/preview-mode)).

To enable the Preview Mode, go to this URL:

```
http://localhost:3000/api/preview?secret=<secret>&slug=draft-post-test
```

- `<secret>` should be the string you entered for `NEXT_EXAMPLE_CMS_STRAPI_PREVIEW_SECRET`.
- `<slug>` should be the post's `slug` attribute.

You should now be able to see the draft post. To exit the preview mode, you can click **Click here to exit preview mode** at the top.

### Step 10. Deploy Strapi

To deploy to production, you must first deploy your Strapi app. The Strapi app for our demo at https://next-blog-strapi.now.sh/ is deployed to Heroku ([here’s the documentation](https://strapi.io/documentation/v3.x/deployment/heroku.html)) and uses Cloudinary for image hosting ([see this file](https://github.com/strapi/strapi-starter-next-blog/blob/master/backend/extensions/upload/config/settings.js)).

### Step 11. Deploy on Vercel

After deploying Strapi, you can deploy this Next.js app to the cloud with [Vercel](https://vercel.com/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).

To deploy on Vercel, you need to set the environment variables with **Vercel Secrets** using [Vercel CLI](https://vercel.com/download) ([Documentation](https://vercel.com/docs/vercel-cli#commands/secrets)).

Install [Vercel CLI](https://vercel.com/download), log in to your account from the CLI, and run the following commands to add the environment variables. Replace `<NEXT_PUBLIC_API_URL>` and `<NEXT_EXAMPLE_CMS_STRAPI_PREVIEW_SECRET>` with the corresponding strings in `.env`.

```
vercel secrets add next_example_cms_strapi_api_url <NEXT_PUBLIC_API_URL>
vercel secrets add next_example_cms_strapi_preview_secret <NEXT_EXAMPLE_CMS_STRAPI_PREVIEW_SECRET>
```

Then push the project to GitHub/GitLab/Bitbucket and [import to Vercel](https://vercel.com/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) to deploy.
42 changes: 42 additions & 0 deletions examples/cms-strapi/components/alert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Container from './container'
import cn from 'classnames'
import { EXAMPLE_PATH } from '@/lib/constants'

export default function Alert({ preview }) {
return (
<div
className={cn('border-b', {
'bg-accent-7 border-accent-7 text-white': preview,
'bg-accent-1 border-accent-2': !preview,
})}
>
<Container>
<div className="py-2 text-center text-sm">
{preview ? (
<>
This is page is a preview.{' '}
<a
href="/api/exit-preview"
className="underline hover:text-cyan duration-200 transition-colors"
>
Click here
</a>{' '}
to exit preview mode.
</>
) : (
<>
The source code for this blog is{' '}
<a
href={`https://github.com/zeit/next.js/tree/canary/examples/${EXAMPLE_PATH}`}
className="underline hover:text-success duration-200 transition-colors"
>
available on GitHub
</a>
.
</>
)}
</div>
</Container>
</div>
)
}
14 changes: 14 additions & 0 deletions examples/cms-strapi/components/avatar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default function Avatar({ name, picture }) {
return (
<div className="flex items-center">
<img
src={`${
picture.url.startsWith('/') ? process.env.NEXT_PUBLIC_API_URL : ''
}${picture.url}`}
className="w-12 h-12 rounded-full mr-4 grayscale"
alt={name}
/>
<div className="text-xl font-bold">{name}</div>
</div>
)
}
3 changes: 3 additions & 0 deletions examples/cms-strapi/components/container.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Container({ children }) {
return <div className="container mx-auto px-5">{children}</div>
}
20 changes: 20 additions & 0 deletions examples/cms-strapi/components/cover-image.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Link from 'next/link'

export default function CoverImage({ title, url, slug }) {
const imageUrl = `${
url.startsWith('/') ? process.env.NEXT_PUBLIC_API_URL : ''
}${url}`
return (
<div className="-mx-5 sm:mx-0">
{slug ? (
<Link as={`/posts/${slug}`} href="/posts/[slug]">
<a aria-label={title}>
<img src={imageUrl} alt={title} />
</a>
</Link>
) : (
<img src={imageUrl} alt={title} />
)}
</div>
)
}
6 changes: 6 additions & 0 deletions examples/cms-strapi/components/date.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
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>
}
30 changes: 30 additions & 0 deletions examples/cms-strapi/components/footer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Container from './container'
import { EXAMPLE_PATH } from '@/lib/constants'

export default function Footer() {
return (
<footer className="bg-accent-1 border-t border-accent-2">
<Container>
<div className="py-28 flex flex-col lg:flex-row items-center">
<h3 className="text-4xl lg:text-5xl font-bold tracking-tighter leading-tight text-center lg:text-left mb-10 lg:mb-0 lg:pr-4 lg:w-1/2">
Statically Generated with Next.js.
</h3>
<div className="flex flex-col lg:flex-row justify-center items-center lg:pl-4 lg:w-1/2">
<a
href="https://nextjs.org/docs/basic-features/pages"
className="mx-3 bg-black hover:bg-white hover:text-black border border-black text-white font-bold py-3 px-12 lg:px-8 duration-200 transition-colors mb-6 lg:mb-0"
>
Read Documentation
</a>
<a
href={`https://github.com/zeit/next.js/tree/canary/examples/${EXAMPLE_PATH}`}
className="mx-3 font-bold hover:underline"
>
View on GitHub
</a>
</div>
</div>
</Container>
</footer>
)
}
Loading

0 comments on commit d60fada

Please sign in to comment.