forked from vercel/next.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Storyblok CMS Example (vercel#13993)
[ch2842] - Demo: https://next-blog-storyblok.now.sh/ - Preview Mode: https://next-blog-storyblok.now.sh/api/preview?secret=5nnybHTKlbzkOa6r&slug=draft-post-test
- Loading branch information
Showing
57 changed files
with
1,046 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Copy this file as .env.local | ||
NEXT_EXAMPLE_CMS_STORYBLOK_API_KEY= | ||
NEXT_EXAMPLE_CMS_STORYBLOK_PREVIEW_SECRET= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
# A statically generated blog example using Next.js and Storyblok | ||
|
||
This example showcases Next.js's [Static Generation](https://nextjs.org/docs/basic-features/pages) feature using [Storyblok](https://www.storyblok.com/) as the data source. | ||
|
||
## Demo | ||
|
||
[https://next-blog-storyblok.now.sh/](https://next-blog-storyblok.now.sh/) | ||
|
||
### 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) | ||
- [Blog Starter](/examples/blog-starter) | ||
|
||
## 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-storyblok cms-storyblok-app | ||
# or | ||
yarn create next-app --example cms-storyblok cms-storyblok-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-storyblok | ||
cd cms-storyblok | ||
``` | ||
|
||
## Configuration | ||
|
||
### Step 1. Create an account on Storyblok | ||
|
||
[Create an account on Storyblok](https://app.storyblok.com/). | ||
|
||
When signing up, select **Create a new space**. Its name can be anything. | ||
|
||
### Step 2. Create the `Authors` folder | ||
|
||
From the dashboard, create a new folder called `Authors`. | ||
|
||
- For **Default content type**, select **Add new**. | ||
- Name of content type should be `author`. | ||
- Choose **Blank** as the content type blueprint. | ||
|
||
### Step 3. Create an `author` entry | ||
|
||
In the `Authors` folder, create a new entry. | ||
|
||
- **Name** can be anything, such as `Test Author`. | ||
|
||
After creating the entry, click **Define schema**. | ||
|
||
- Add a key called `picture`. Then click `picture` and set the **Type** as **Asset** and select **Images**. | ||
|
||
Then upload an image to `picture`. You can use an [image from Unsplash](https://unsplash.com/). | ||
|
||
Finally, after uploading, click **Publish**. | ||
|
||
### Step 4. Create the `Posts` folder | ||
|
||
After publishing the author, go back to the dashboard by clicking **Content** on the sidebar. | ||
|
||
This time, create a new folder called `Posts`. | ||
|
||
- For **Default content type**, select **Add new**. | ||
- Name of content type should be `post`. | ||
- Choose **Post** as the content type blueprint. | ||
|
||
### Step 5. Create a `post` entry | ||
|
||
In the `Posts` folder, create a new entry. | ||
|
||
- **Name** can be anything. | ||
|
||
Now, populate each field. | ||
|
||
- **Title** can be any text. | ||
- **Image** can be an [image from Unsplash](https://unsplash.com/). | ||
- **Intro** can be any text. | ||
- **Long Text** can be any text. | ||
- **Author** should be the author created earlier. | ||
|
||
Finally, click **Publish**. | ||
|
||
You can create more posts under the `Posts` folder. Make sure to publish each one. | ||
|
||
### Step 6. Set up environment variables | ||
|
||
Go to the **Settings** menu for your space, and click **API-Keys**. | ||
|
||
Then copy the **preview** token on the page. | ||
|
||
Next, 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`: | ||
|
||
- `NEXT_EXAMPLE_CMS_STORYBLOK_API_KEY` should be the API key you just copied. | ||
- `NEXT_EXAMPLE_CMS_STORYBLOK_PREVIEW_SECRET` can be any random string (but avoid spaces), like `MY_SECRET` - this is used for [the Preview Mode](https://nextjs.org/docs/advanced-features/preview-mode). | ||
|
||
### Step 7. 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, you can post on [GitHub discussions](https://github.com/vercel/next.js/discussions). | ||
|
||
### Step 8. Try preview mode | ||
|
||
To try preview mode, create another post like before (you can try duplicating), but **do not publish it - just save it**: | ||
|
||
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=<slug> | ||
``` | ||
|
||
- `<secret>` should be the string you entered for `NEXT_EXAMPLE_CMS_STORYBLOK_PREVIEW_SECRET`. | ||
- `<slug>` should be the post's `slug` (which can be seen on the **Config** section). | ||
|
||
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 9. Deploy on Vercel | ||
|
||
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_EXAMPLE_CMS_STORYBLOK_API_KEY>` and `<NEXT_EXAMPLE_CMS_STORYBLOK_PREVIEW_SECRET>` with the corresponding strings in `.env`. | ||
|
||
``` | ||
vercel secrets add next_example_cms_storyblok_api_key <NEXT_EXAMPLE_CMS_STORYBLOK_API_KEY> | ||
vercel secrets add next_example_cms_storyblok_preview_secret <NEXT_EXAMPLE_CMS_STORYBLOK_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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
export default function Avatar({ name, picture }) { | ||
return ( | ||
<div className="flex items-center"> | ||
<img | ||
src={picture.filename} | ||
className="w-12 h-12 rounded-full mr-4 grayscale" | ||
alt={name} | ||
/> | ||
<div className="text-xl font-bold">{name}</div> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import Link from 'next/link' | ||
|
||
export default function CoverImage({ title, url, slug }) { | ||
return ( | ||
<div className="-mx-5 sm:mx-0"> | ||
{slug ? ( | ||
<Link as={`/posts/${slug}`} href="/posts/[slug]"> | ||
<a aria-label={title}> | ||
<img src={url} alt={title} /> | ||
</a> | ||
</Link> | ||
) : ( | ||
<img src={url} alt={title} /> | ||
)} | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { parseISO, format } from 'date-fns' | ||
import { useEffect, useState } from 'react' | ||
|
||
// dateString might be null for unpublished posts | ||
export default function DateComponent({ dateString }) { | ||
const [date, setDate] = useState(dateString ? parseISO(dateString) : null) | ||
useEffect(() => { | ||
if (!date) { | ||
setDate(new Date()) | ||
} | ||
}, [date]) | ||
return date && <time dateTime={date}>{format(date, 'LLLL d, yyyy')}</time> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import Link from 'next/link' | ||
|
||
export default function Header() { | ||
return ( | ||
<h2 className="text-2xl md:text-4xl font-bold tracking-tight md:tracking-tighter leading-tight mb-20 mt-8"> | ||
<Link href="/"> | ||
<a className="hover:underline">Blog</a> | ||
</Link> | ||
. | ||
</h2> | ||
) | ||
} |
Oops, something went wrong.