Skip to content

Commit ecf9f87

Browse files
rasmusjpleerobtimneutkenskodiakhq[bot]
authored
Add Umbraco Heartcore blog example (#21409)
Co-authored-by: Lee Robinson <me@leerob.io> Co-authored-by: Tim Neutkens <tim@timneutkens.nl> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
1 parent d459b5f commit ecf9f87

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1056
-0
lines changed

docs/advanced-features/preview-mode.md

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ description: Next.js has the preview mode for statically generated pages. You ca
2323
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-storyblok">Storyblok Example</a> (<a href="https://next-blog-storyblok.vercel.app/">Demo</a>)</li>
2424
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-graphcms">GraphCMS Example</a> (<a href="https://next-blog-graphcms.vercel.app/">Demo</a>)</li>
2525
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-kontent">Kontent Example</a> (<a href="https://next-blog-kontent.vercel.app//">Demo</a>)</li>
26+
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-umbraco-heartcore">Umbraco Heartcore Example</a> (<a href="https://next-blog-umbraco-heartcore.vercel.app/">Demo</a>)</li>
2627
</ul>
2728
</details>
2829

examples/blog-starter/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_mediu
3737
- [Storyblok](/examples/cms-storyblok)
3838
- [GraphCMS](/examples/cms-graphcms)
3939
- [Kontent](/examples/cms-kontent)
40+
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
4041

4142
## How to use
4243

examples/cms-agilitycms/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Once you have access to [the environment variables you'll need](#step-15-set-up-
3030
- [GraphCMS](/examples/cms-graphcms)
3131
- [Kontent](/examples/cms-kontent)
3232
- [Ghost](/examples/cms-ghost)
33+
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
3334
- [Blog Starter](/examples/blog-starter)
3435

3536
## How to use

examples/cms-buttercms/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Once you have access to [the environment variables you'll need](#step-2-set-up-e
2727
- [GraphCMS](/examples/cms-graphcms)
2828
- [Kontent](/examples/cms-kontent)
2929
- [Ghost](/examples/cms-ghost)
30+
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
3031
- [Blog Starter](/examples/blog-starter)
3132

3233
## How to use

examples/cms-contentful/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Using the Deploy Button below, you'll deploy the Next.js project as well as conn
2727
- [GraphCMS](/examples/cms-graphcms)
2828
- [Kontent](/examples/cms-kontent)
2929
- [Ghost](/examples/cms-ghost)
30+
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
3031
- [Blog Starter](/examples/blog-starter)
3132

3233
## How to use

examples/cms-cosmic/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Once you have access to [the environment variables you'll need](#step-3-set-up-e
2727
- [GraphCMS](/examples/cms-graphcms)
2828
- [Kontent](/examples/cms-kontent)
2929
- [Ghost](/examples/cms-ghost)
30+
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
3031
- [Blog Starter](/examples/blog-starter)
3132

3233
## How to use

examples/cms-datocms/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ This example showcases Next.js's [Static Generation](https://nextjs.org/docs/bas
2121
- [GraphCMS](/examples/cms-graphcms)
2222
- [Kontent](/examples/cms-kontent)
2323
- [Ghost](/examples/cms-ghost)
24+
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
2425
- [Blog Starter](/examples/blog-starter)
2526

2627
## Deploy your own

examples/cms-ghost/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Once you have access to [the environment variables you'll need](#step-2-set-up-e
2525
- [Storyblok](/examples/cms-storyblok)
2626
- [GraphCMS](/examples/cms-graphcms)
2727
- [Kontent](/examples/cms-kontent)
28+
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
2829
- [Blog Starter](/examples/blog-starter)
2930

3031
## How to use

examples/cms-graphcms/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ This example showcases Next.js's [Static Generation](https://nextjs.org/docs/bas
2424
- [Storyblok](/examples/cms-storyblok)
2525
- [Kontent](/examples/cms-kontent)
2626
- [Ghost](/examples/cms-ghost)
27+
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
2728
- [Blog Starter](/examples/blog-starter)
2829

2930
## Deploy your own

examples/cms-kontent/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Once you have access to [the environment variables you'll need](#step-3-set-up-e
2727
- [Storyblok](/examples/cms-storyblok)
2828
- [GraphCMS](/examples/cms-graphcms)
2929
- [Ghost](/examples/cms-ghost)
30+
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
3031
- [Blog Starter](/examples/blog-starter)
3132

3233
## How to use

examples/cms-prismic/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Once you have access to [the environment variables you'll need](#step-5-set-up-e
2626
- [Storyblok](/examples/cms-storyblok)
2727
- [Kontent](/examples/cms-kontent)
2828
- [Ghost](/examples/cms-ghost)
29+
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
2930
- [Blog Starter](/examples/blog-starter)
3031

3132
## How to use

examples/cms-sanity/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Once you have access to [the environment variables you'll need](#step-4-set-up-e
2727
- [GraphCMS](/examples/cms-graphcms)
2828
- [Kontent](/examples/cms-kontent)
2929
- [Ghost](/examples/cms-ghost)
30+
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
3031
- [Blog Starter](/examples/blog-starter)
3132

3233
## How to use

examples/cms-storyblok/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Once you have access to [the environment variables you'll need](#step-6-set-up-e
2727
- [GraphCMS](/examples/cms-graphcms)
2828
- [Kontent](/examples/cms-kontent)
2929
- [Ghost](/examples/cms-ghost)
30+
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
3031
- [Blog Starter](/examples/blog-starter)
3132

3233
## How to use

examples/cms-strapi/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Once you have access to [the environment variables you'll need](#step-7-set-up-e
2727
- [GraphCMS](/examples/cms-graphcms)
2828
- [Kontent](/examples/cms-kontent)
2929
- [Ghost](/examples/cms-ghost)
30+
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
3031
- [Blog Starter](/examples/blog-starter)
3132

3233
## How to use
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
UMBRACO_PROJECT_ALIAS=
2+
UMBRACO_API_KEY=
3+
UMBRACO_PREVIEW_SECRET=
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# next.js
12+
/.next/
13+
/out/
14+
15+
# production
16+
/build
17+
18+
# misc
19+
.DS_Store
20+
*.pem
21+
22+
# debug
23+
npm-debug.log*
24+
yarn-debug.log*
25+
yarn-error.log*
26+
27+
# local env files
28+
.env.local
29+
.env.development.local
30+
.env.test.local
31+
.env.production.local
32+
33+
# vercel
34+
.vercel
+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# A statically generated blog example using Next.js and Umbraco Heartcore
2+
3+
This example showcases Next.js's [Static Generation](https://nextjs.org/docs/basic-features/pages) feature using [Umbraco Heartcore](https://umbraco.com/heartcore) as the data source.
4+
5+
## Demo
6+
7+
- **Live**: [https://next-blog-umbraco-heartcore.vercel.app/](https://next-blog-umbraco-heartcore.vercel.app/)
8+
- **Preview Mode**: [https://next-blog-umbraco-heartcore.vercel.app/api/preview...](https://next-blog-umbraco-heartcore.vercel.app/api/preview?secret=ivfgc53v8d8ikh7z4nnd5hzwgs298ma6&slug=/posts/learn-how-to-pre-render-pages-using-static-generation-with-next-js)
9+
10+
## Deploy your own
11+
12+
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):
13+
14+
[![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-umbraco-heartcore&env=UMBRACO_PROJECT_ALIAS,UMBRACO_API_KEY,UMBRACO_PREVIEW_SECRET&envDescription=Required%20to%20connect%20the%20app%20with%20Umbraco%20Heartcore&envLink=https://vercel.link/cms-umbraco-heartcore-env)
15+
16+
### Related examples
17+
18+
- [WordPress](/examples/cms-wordpress)
19+
- [DatoCMS](/examples/cms-datocms)
20+
- [Sanity](/examples/cms-sanity)
21+
- [TakeShape](/examples/cms-takeshape)
22+
- [Prismic](/examples/cms-prismic)
23+
- [Contentful](/examples/cms-contentful)
24+
- [Strapi](/examples/cms-strapi)
25+
- [Agility CMS](/examples/cms-agilitycms)
26+
- [Cosmic](/examples/cms-cosmic)
27+
- [ButterCMS](/examples/cms-buttercms)
28+
- [Storyblok](/examples/cms-storyblok)
29+
- [GraphCMS](/examples/cms-graphcms)
30+
- [Kontent](/examples/cms-kontent)
31+
- [Ghost](/examples/cms-ghost)
32+
- [Blog Starter](/examples/blog-starter)
33+
34+
## How to use
35+
36+
Execute [`create-next-app`](https://github.com/zeit/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:
37+
38+
```bash
39+
npx create-next-app --example cms-umbraco-heartcore cms-umbraco-heartcore-app
40+
# or
41+
yarn create next-app --example cms-umbraco-heartcore cms-umbraco-heartcore-app
42+
```
43+
44+
## Configuration
45+
46+
### Step 1. Create an account and a project in Umbraco Heartcore
47+
48+
First, [create an account in Umbraco Heartcore](https://umbraco.com/heartcore), this will also create an empty project.
49+
50+
### Step 2. Login into Umbraco Heartcore and install sample data
51+
52+
After your account has been created, you are redirected to the Umbraco Cloud Portal, from here you click on the **Go to backoffice** link and login to your new Umbraco Heartcore project.
53+
54+
![Project page](./docs/project-page.png)
55+
56+
From the dashboard click **Install sample** on the **Blog Starter** sample.
57+
58+
![Install sample](./docs/install-sample.png)
59+
60+
### Step 3. Set up environment variables
61+
62+
Copy the `.env.local.example` file in this directory to `.env.local` (which will be ignored by Git):
63+
64+
```bash
65+
cp .env.local.example .env.local
66+
```
67+
68+
Then set each variable in `.env.local`:
69+
70+
- `UMBRACO_PROJECT_ALIAS`: Set it to the project alias, which can be found under **Settings** -> **Headless**.
71+
- `UMBRACO_API_KEY`: Create a new API Key under **Users > "Your Username" > API Keys**.
72+
- `UMBRACO_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).
73+
74+
Your `.env.local` file should look like this:
75+
76+
```bash
77+
UMBRACO_PROJECT_ALIAS=...
78+
UMBRACO_API_KEY=...
79+
UMBRACO_PREVIEW_SECRET=...
80+
```
81+
82+
### Step 4. Run Next.js in development mode
83+
84+
```bash
85+
npm install
86+
npm run dev
87+
88+
# or
89+
90+
yarn install
91+
yarn dev
92+
```
93+
94+
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/zeit/next.js/discussions).
95+
96+
### Step 5. Try preview mode
97+
98+
Then click save and go back to the **Content** section, click on _Posts_ and then on a post and:
99+
100+
- **Update the title**. For example, you can add `[Draft]` in front of the title.
101+
- Click **Save**, but **DO NOT** click **Publish**. By doing this, the post will be in the draft state.
102+
103+
Now, if you go to the post page on localhost, you won't see the updated title. However, if you use **Preview Mode**, you'll be able to see the change ([Documentation](/docs/advanced-features/preview-mode.md)).
104+
105+
To enable the Preview Mode, go to this URL:
106+
107+
```
108+
http://localhost:3000/api/preview?secret=<secret>&slug=<slug>
109+
```
110+
111+
- `<secret>` should be the string you entered for `STRAPI_PREVIEW_SECRET`.
112+
- `<slug>` should be the post's `url`, which can be found under **Info**.
113+
114+
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 of the page.
115+
116+
To make it easier to go into **Preview Mode** you can enable a preview button on the posts in the backoffice.
117+
118+
In Umbraco Heartcore, go to **Settings > Headless > Preview**. From here you can add a new Preview Url by clicking the **Add Preview Url** button.
119+
120+
Fill in the form with the following values:
121+
122+
![Add Preview Url](./docs/add-preview-url.png)
123+
124+
- **Root Content**: Select the **Posts** node
125+
- **Culture**: en-US
126+
- **Url**: http://localhost:3000/api/preview?secret=YOUR_PREVIEW_SECRET
127+
- **Name**: Local Test
128+
- **Path type**: Path in querystring
129+
- **Querystring parameter nam**: slug
130+
131+
If you go back to one of the posts, you should now see a **Preview** button at the bottom right of the screen next to the **Save** button. If you click it, you should be in **Preview Mode**.
132+
133+
![Preview Button](./docs/preview-button.png)
134+
135+
### Step 6. Deploy on Vercel
136+
137+
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)).
138+
139+
#### Deploy Your Local Project
140+
141+
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).
142+
143+
**Important**: When you import your project on Vercel, make sure to click on **Environment Variables** and set them to match your `.env.local` file.
144+
145+
#### Deploy from Our Template
146+
147+
Alternatively, you can deploy using our template by clicking on the Deploy button below.
148+
149+
[![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-umbraco-heartcore&env=UMBRACO_PROJECT_ALIAS,UMBRACO_API_KEY,UMBRACO_PREVIEW_SECRET&envDescription=Required%20to%20connect%20the%20app%20with%20Umbraco%20Heartcore&envLink=https://vercel.link/cms-umbraco-heartcore-env)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import Container from './container'
2+
import cn from 'classnames'
3+
import { EXAMPLE_PATH } from '../lib/constants'
4+
5+
export default function Alert({ preview }) {
6+
return (
7+
<div
8+
className={cn('border-b', {
9+
'bg-accent-7 border-accent-7 text-white': preview,
10+
'bg-accent-1 border-accent-2': !preview,
11+
})}
12+
>
13+
<Container>
14+
<div className="py-2 text-center text-sm">
15+
{preview ? (
16+
<>
17+
This page is a preview.{' '}
18+
<a
19+
href="/api/exit-preview"
20+
className="underline hover:text-cyan duration-200 transition-colors"
21+
>
22+
Click here
23+
</a>{' '}
24+
to exit preview mode.
25+
</>
26+
) : (
27+
<>
28+
The source code for this blog is{' '}
29+
<a
30+
href={`https://github.com/zeit/next.js/tree/canary/examples/${EXAMPLE_PATH}`}
31+
className="underline hover:text-success duration-200 transition-colors"
32+
>
33+
available on GitHub
34+
</a>
35+
.
36+
</>
37+
)}
38+
</div>
39+
</Container>
40+
</div>
41+
)
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Image from 'next/image'
2+
3+
export default function Avatar({ name, picture }) {
4+
return (
5+
<div className="flex items-center">
6+
<div className="w-12 h-12 relative mr-4">
7+
<Image
8+
src={picture}
9+
layout="fill"
10+
className="rounded-full"
11+
alt={name}
12+
/>
13+
</div>
14+
<div className="text-xl font-bold">{name}</div>
15+
</div>
16+
)
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Container({ children }) {
2+
return <div className="container mx-auto px-5">{children}</div>
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import cn from 'classnames'
2+
import Link from 'next/link'
3+
import Image from 'next/image'
4+
5+
export default function CoverImage({ title, url, slug }) {
6+
const image = (
7+
<Image
8+
width={2000}
9+
height={1000}
10+
alt={`Cover Image for ${title}`}
11+
className={cn('shadow-small', {
12+
'hover:shadow-medium transition-shadow duration-200': slug,
13+
})}
14+
src={url}
15+
/>
16+
)
17+
18+
return (
19+
<div className="sm:mx-0">
20+
{slug ? (
21+
<Link href={slug}>
22+
<a aria-label={title}>{image}</a>
23+
</Link>
24+
) : (
25+
image
26+
)}
27+
</div>
28+
)
29+
}

0 commit comments

Comments
 (0)