-
Notifications
You must be signed in to change notification settings - Fork 27.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
ondrejch
committed
Aug 10, 2020
1 parent
f4433ce
commit 2a805fa
Showing
56 changed files
with
1,002 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
KONTENT_PROJECT_ID= | ||
KONTENT_PREVIEW_SECRET= | ||
KONTENT_PREVIEW_API_KEY= |
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,34 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
# vercel | ||
.vercel |
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,211 @@ | ||
# A statically generated blog example using Next.js and Kontent | ||
|
||
This example showcases Next.js's [Static Generation](https://nextjs.org/docs/basic-features/pages) feature using [Kentico Kontent](https://kontent.ai) as the data source. | ||
|
||
## Demo | ||
|
||
[https://next-blog-kontent.vercel.app/](https://next-blog-kontent.vercel.app/) | ||
|
||
## Deploy your own | ||
|
||
Once you have access to [the environment variables you'll need](#step-4-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/import/git?c=1&s=https://github.com/vercel/next.js/tree/canary/examples/cms-kontent&env=KONTENT_PROJECT_ID,KONTENT_PREVIEW_API_KEY,KONTENT_PREVIEW_SECRET&envDescription=Required%20to%20connect%20the%20app%20with%20Kontent) | ||
|
||
### 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) | ||
- [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 blog-kontent blog-kontent-app | ||
# or | ||
yarn create next-app --example blog-kontent blog-kontent-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-kontent | ||
cd cms-starter | ||
``` | ||
|
||
## Configuration | ||
|
||
### Step 1. Create an account on Kontent | ||
|
||
First, [create an account on Kontent.ai](https://app.kontent.ai/sign-up?utm_source=nextjs_docs_example&utm_medium=devrel). | ||
|
||
After signing up, [create an empty project](https://docs.kontent.ai/tutorials/set-up-kontent/projects/manage-projects#a-creating-projects). | ||
|
||
### Step 2. Create a content models and fill them with data | ||
|
||
The [content model](https://docs.kontent.ai/tutorials/set-up-kontent/content-modeling/what-is-content-modeling) defines the data structures of your application/websites. The structures are flexible and you can tailor them to your needs. | ||
|
||
For this example you need to create a content model that defines an `author` and a `post` content type. **You can import these automatically or by doing it manually** to familiarize yourself with the Kontent user interface. | ||
|
||
#### Import content models and it's data | ||
|
||
1. Enter [Kontent application](https://app.kontent.ai) | ||
1. Go to "Project Settings", select API keys | ||
1. Activate Management API | ||
1. Copy `Project ID` and `Management API` key | ||
1. Install [Kontent Backup Manager](https://github.com/Kentico/kontent-backup-manager-js) and import data to newly created project from kontent-backup.zip file (place appropriate values for apiKey and projectId arguments): | ||
|
||
```sh | ||
npm i -g @kentico/kontent-backup-manager | ||
kbm --action=restore --apiKey=<Management API key> --projectId=<Project ID> --zipFilename=kontent-backup | ||
``` | ||
|
||
> **:bulb: Alternatively, you can use the [Template Manager UI](https://kentico.github.io/kontent-template-manager/import-from-file) for importing the content.** | ||
1. Go to your Kontent project and publish all the imported items. | ||
> You could deactivate Management API key, it is not necessary any more. | ||
#### Create the content models and it's data manually | ||
|
||
##### Create an `Author` content type | ||
|
||
From your Kontent project, go to **Content models** and add a new `Content type`: | ||
|
||
> you don't have to modify the element configuration unless specified | ||
- Content type name: `Author` | ||
- Add following content elements | ||
- `Name` - **Text** element | ||
- `Picture` - **Asset** element - configure to allow to select `At most 1` asset and `Limit file types` only to `Adjustable images` | ||
|
||
Save the content type and continue. | ||
|
||
The content type should looks like that: | ||
![Content type Author](./docs/author-content-type.png) | ||
|
||
##### Create an `Post` content type | ||
|
||
From your Kontent project, go to **Content models** and add a new content type: | ||
|
||
> you don't have to modify the element configuration unless specified | ||
- Content type name: `Post` | ||
- Add following content elements | ||
- `Title` - **Text** element | ||
- `Date` - **Date & time** element | ||
- `Excerpt` - **Text** element | ||
- `Content` - **Rich Text** element | ||
- `Cover Image` - **Asset Text** element - configure to allow to select `At most 1` asset and `Limit file types` only to `Adjustable images` - `Content` - `Slug` - **URL slug** element - auto-generated from `Title` element | ||
- `Author` - **Linked items** element - configure to accept `Exactly 1` item of type `Author` | ||
|
||
Save the content type and continue. | ||
|
||
The content type should looks like that: | ||
![Content type Author](./docs/post-content-type.png) | ||
|
||
##### Fill content models with data | ||
|
||
Go to `Content & Assets` section in your project and click `Create new` on the `Content` tab and select `Author` content type. | ||
|
||
- You just need **1 author item** first. | ||
- Use dummy data for his name. | ||
- For the image, you can download one from [Unsplash](https://unsplash.com/). | ||
|
||
Next, create another item based on **Post** content type: | ||
|
||
- It's recommend to create at least **2 post items**. | ||
- Use dummy data for the text. | ||
- For images, you can download them from [Unsplash](https://unsplash.com/). | ||
- Pick the **author** you created earlier. | ||
|
||
**Important:** For each item, you need to click on **Publish**. If not, the entry will be in draft workflow step. | ||
|
||
![Published post item overview](./docs/publish-post-overview.png) | ||
|
||
### Step 4. Set up environment variables | ||
|
||
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` from `Project settings` > `API keys`: | ||
|
||
- `KONTENT_PROJECT_ID` - Project ID from the `API keys` section. | ||
- `KONTENT_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). | ||
- `KONTENT_PREVIEW_API_KEY` - one of the Preview API keys from the `API keys` section. | ||
|
||
### Step 5. 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 6. Try preview mode | ||
|
||
In your Kontent project, go to **Project Settings > Preview URLs** and set a new preview URL for `Post` content type to: | ||
|
||
```plain | ||
http://localhost:3000/api/preview?secret=<KONTENT_PREVIEW_SECRET>&slug={URLslug} | ||
``` | ||
|
||
Replace `<KONTENT_PREVIEW_SECRET>` with its respective value in `.env.local`. | ||
|
||
![Preview URL setup](./docs/preview-URLs-setup.png) | ||
|
||
Once saved, go to one of the posts you've created and: | ||
|
||
- Create a new version of the post | ||
- **Update the title**. For example, you can add `[Draft]` in front of the title. | ||
> Mind the title also regenerates the URL slug | ||
- **Do not** publish it. By doing this, the post will be in draft workflow step. | ||
- On the menu, you will see the **Preview** button. Click on it! | ||
|
||
![Post preview button](./docs/post-preview-button.jpg). | ||
|
||
You will now be able to see the updated title. To exit preview mode, you can click on **Click here to exit preview mode** at the top of the page. | ||
|
||
### Step 7. 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/import/git?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/import/git?c=1&s=https://github.com/vercel/next.js/tree/canary/examples/cms-kontent&env=KONTENT_PROJECT_ID,KONTENT_PREVIEW_API_KEY,KONTENT_PREVIEW_SECRET&envDescription=Required%20to%20connect%20the%20app%20with%20Kontent) | ||
|
||
## Notes | ||
|
||
This starter uses [Tailwind CSS](https://tailwindcss.com). To control the generated stylesheet's filesize, this example uses Tailwind CSS' v1.4 [`purge` option](https://tailwindcss.com/docs/controlling-file-size/#removing-unused-css) to remove unused CSS. |
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 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/vercel/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,8 @@ | ||
export default function Avatar({ name, picture }) { | ||
return ( | ||
<div className="flex items-center"> | ||
<img src={picture} className="w-12 h-12 rounded-full mr-4" 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,25 @@ | ||
import cn from 'classnames' | ||
import Link from 'next/link' | ||
|
||
export default function CoverImage({ title, src, slug }) { | ||
const image = ( | ||
<img | ||
src={src} | ||
alt={`Cover Image for ${title}`} | ||
className={cn('shadow-small', { | ||
'hover:shadow-medium transition-shadow duration-200': slug, | ||
})} | ||
/> | ||
) | ||
return ( | ||
<div className="-mx-5 sm:mx-0"> | ||
{slug ? ( | ||
<Link as={`/posts/${slug}`} href="/posts/[slug]"> | ||
<a aria-label={title}>{image}</a> | ||
</Link> | ||
) : ( | ||
image | ||
)} | ||
</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,6 @@ | ||
import { parseISO, format } from 'date-fns' | ||
|
||
export default function DateFormater({ dateString }) { | ||
const date = parseISO(dateString) | ||
return <time dateTime={dateString}>{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/vercel/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.