-
Notifications
You must be signed in to change notification settings - Fork 27.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
examples: Add
cms-umbraco
example (#52777)
Co-authored-by: Lee Robinson <me@leerob.io>
- Loading branch information
Showing
50 changed files
with
1,363 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,11 @@ | ||
# This is necessary when you run locally against a self-signed server. Do NOT include this in production. | ||
NODE_TLS_REJECT_UNAUTHORIZED=0 | ||
|
||
# Add your Umbraco server URL here. Please do not include a trailing slash. | ||
UMBRACO_SERVER_URL = | ||
|
||
# Add your Umbraco Delivery API key here if you want to use preview. | ||
UMBRACO_DELIVERY_API_KEY = | ||
|
||
# Add the secret token that will be used to "authorize" preview | ||
UMBRACO_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,35 @@ | ||
# 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 | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts |
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,161 @@ | ||
# A statically generated blog example using Next.js and Umbraco CMS | ||
|
||
This example showcases Next.js's [Static Generation](https://nextjs.org/docs/basic-features/pages) feature using [Umbraco CMS](https://www.umbraco.com/) as the data source. | ||
|
||
## Demo | ||
|
||
### https://nextjs-umbraco-sample-blog.vercel.app/ | ||
|
||
## 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) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: | ||
|
||
```bash | ||
npx create-next-app --example cms-umbraco umbraco-app | ||
# or | ||
yarn create next-app --example cms-umbraco umbraco-app | ||
# or | ||
pnpm create next-app --example cms-umbraco umbraco-app | ||
``` | ||
|
||
## Configuration | ||
|
||
### Step 1. Create an Umbraco project | ||
|
||
Use the .NET CLI to create a project locally. | ||
|
||
1. Create an empty folder and open a terminal there. | ||
2. If you haven't already, install the Umbraco .NET CLI templates for version 12.0 or above by running: `dotnet new install Umbraco.Templates::13.*`. | ||
3. Create the Umbraco project by running: `dotnet new umbraco` | ||
|
||
For more information on the Umbraco .NET CLI templates, visit [this page](https://docs.umbraco.com/umbraco-cms/fundamentals/setup/install/install-umbraco-with-templates). | ||
|
||
### Step 2. Install sample data | ||
|
||
To avoid having to create the entire blog dataset in hand, we have created a [NuGet package](https://www.nuget.org/packages/Umbraco.Sample.Headless.Blog) with everything you need to get started. | ||
|
||
Install the NuGet package with the following command in the terminal window: `dotnet add package Umbraco.Sample.Headless.Blog`. | ||
|
||
### Step 3. Configure the Umbraco Delivery API | ||
|
||
The Umbraco Delivery API will be the data source for the blog. This API must be enabled explicitly. | ||
|
||
Open `appsettings.json` and add the `DeliveryApi` configuration inside `Umbraco::CMS`: | ||
|
||
```json | ||
"Umbraco": { | ||
"CMS": { | ||
"DeliveryApi": { | ||
"Enabled": true, | ||
"ApiKey": "my-secret-api-key" | ||
}, | ||
.... | ||
``` | ||
|
||
_The `ApiKey` configuration is optional, though necessary if you want to use the preview functionality of the blog sample._ | ||
|
||
### Step 4. Run Umbraco | ||
|
||
Start Umbraco with the following command in the terminal window: `dotnet run`. | ||
|
||
Follow the installation wizard to complete the Umbraco setup. | ||
|
||
Once completed you'll be redirected to the Umbraco backoffice where the blog sample data is already installed. | ||
|
||
### Step 5. Publish the sample data | ||
|
||
All the sample content is unpublished to begin with. You need to publish all of it to show the blog posts on the blog. | ||
|
||
1. Click the _Posts_ item in the Content tree. This item contains all the individual blog posts. | ||
2. In the lower right hand corner of the browser you'll find a green button labelled "Save and publish". | ||
3. Click the little up-arrow next to this button and select "Publish with descendants...". | ||
4. In the dialog, tick "Include unpublished content items" to publish the _Posts_ item and all the blog posts in one go. | ||
|
||
Now do the same for the _Authors_ item. | ||
|
||
### Step 6. Set up environment variables | ||
|
||
Locate `.env.local.example` where you created the `umbraco-app` project. Create a copy of the file and name it `.env.local`. Now edit the file and fill in the blanks. | ||
|
||
- `UMBRACO_SERVER_URL`: The base URL of your Umbraco site. Avoid trailing slashes here. | ||
- `UMBRACO_DELIVERY_API_KEY`: The API key you configured in `appsettings.json`. This is only necessary if you want to test Preview Mode. | ||
- `UMBRACO_PREVIEW_SECRET` This can be any random string (but avoid spaces), like `my-preview-secret`. This is used for triggering preview, thus only necessary if you want to test Preview Mode. | ||
|
||
The file should end up looking something like this: | ||
|
||
``` | ||
NODE_TLS_REJECT_UNAUTHORIZED=0 | ||
UMBRACO_SERVER_URL = 'https://localhost:12345' | ||
UMBRACO_DELIVERY_API_KEY = 'my-secret-api-key' | ||
UMBRACO_PREVIEW_SECRET = 'my-preview-secret' | ||
``` | ||
|
||
Notice the `NODE_TLS_REJECT_UNAUTHORIZED=0` setting. When running a .NET website locally, a self-signed SSL certificate is created to allow HTTPS bindings. Node.js does not trust self-signed SSL certificates, so you need to bypass the SSL/TLS certificate verification with this setting. Do not use this workaround in production. | ||
|
||
### Step 7. Run Next.js in development mode | ||
|
||
In the `umbraco-app` project folder, 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)! If it doesn't work, post on [GitHub discussions](https://github.com/vercel/next.js/discussions). | ||
|
||
### Step 8. Try Preview Mode | ||
|
||
If you edit a post in Umbraco without publishing the changes, you won't see these changes at `http://localhost:3000` by default. However, if you enable **Preview Mode**, you'll be able to see the changes ([Documentation](https://nextjs.org/docs/advanced-features/preview-mode)). | ||
|
||
To enable Preview Mode, go to this URL: | ||
|
||
``` | ||
http://localhost:3000/api/preview?secret=<secret> | ||
``` | ||
|
||
- `<secret>` should be the string you entered for `UMBRACO_PREVIEW_SECRET` in `.env.local`. | ||
|
||
If you browse to the changed post, you will now see the unpublished changes. | ||
|
||
To exit Preview Mode go to this URL: | ||
|
||
``` | ||
http://localhost:3000/api/exit-preview | ||
``` | ||
|
||
### Step 9. 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 Umbraco | ||
|
||
Before you can deploy the blog to Vercel, you first need to deploy your Umbraco site to a hosting provider, to make the blog data available for Vercel. | ||
|
||
If you use Azure, be sure to read [the guidelines](https://docs.umbraco.com/umbraco-cms/fundamentals/setup/server-setup/azure-web-apps) on deploying Umbraco to Azure. | ||
|
||
You can also try this out on [Umbraco Cloud](https://umbraco.com/try-umbraco-cms/). | ||
|
||
#### 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 Umbraco deployment. | ||
|
||
#### Deploy from Our Template | ||
|
||
Alternatively, you can deploy using our template by clicking on the Deploy button below. | ||
|
||
[](https://vercel.com/new/clone?repository-url=https://github.com/vercel/next.js/tree/canary/examples/cms-umbraco&project-name=nextjs-umbraco-blog&repository-name=nextjs-umbraco-blog&env=UMBRACO_SERVER_URL,UMBRACO_DELIVERY_API_KEY,UMBRACO_PREVIEW_SECRET&envDescription=Required%20to%20connect%20the%20app%20with%20Umbraco%20CMS&envLink=https://github.com/vercel/next.js/tree/canary/examples/cms-umbraco%23step-6-set-up-environment-variables) | ||
|
||
### Getting to know Umbraco's Content Delivery API | ||
|
||
This example utilizes the native Content Delivery API in Umbraco to fetch the blog data headlessly. | ||
|
||
The Content Delivery API is a feature-rich API for headless content delivery. However, in an effort to keep the complexity down in this sample, certain features and optimizations have been omitted from the API queries. This results in slight over-fetching, particularly when fetching multiple blog posts. | ||
|
||
You can read all about the Content Delivery API [here](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api). |
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,46 @@ | ||
import Container from "./container"; | ||
import cn from "classnames"; | ||
import { EXAMPLE_PATH } from "../lib/constants"; | ||
|
||
type Props = { | ||
preview?: boolean; | ||
}; | ||
|
||
export default function Alert({ preview }: Props) { | ||
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 a page 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,24 @@ | ||
import Image from "next/image"; | ||
import Author from "../types/author"; | ||
|
||
type Props = { | ||
author: Author; | ||
}; | ||
|
||
export default function Avatar({ author }: Props) { | ||
const name: string = author?.name; | ||
|
||
return ( | ||
<div className="flex items-center"> | ||
<div className="w-12 h-12 relative mr-4"> | ||
<Image | ||
src={author.picture.url} | ||
layout="fill" | ||
className="rounded-full" | ||
alt={name} | ||
/> | ||
</div> | ||
<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,7 @@ | ||
type Props = { | ||
children: React.ReactNode; | ||
}; | ||
|
||
export default function Container({ children }: Props) { | ||
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,35 @@ | ||
import cn from "classnames"; | ||
import Image from "next/image"; | ||
import Link from "next/link"; | ||
import Picture from "../types/picture"; | ||
|
||
type Props = { | ||
title: string; | ||
coverImage: Picture; | ||
slug?: string; | ||
}; | ||
|
||
export default function CoverImage({ title, coverImage, slug }: Props) { | ||
const image = ( | ||
<Image | ||
width={2000} | ||
height={1000} | ||
alt={`Cover Image for ${title}`} | ||
src={coverImage.url} | ||
className={cn("shadow-small", { | ||
"hover:shadow-medium transition-shadow duration-200": slug, | ||
})} | ||
/> | ||
); | ||
return ( | ||
<div className="sm:mx-0"> | ||
{slug ? ( | ||
<Link href={`/posts${slug}`} aria-label={title}> | ||
{image} | ||
</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,10 @@ | ||
import { parseISO, format } from "date-fns"; | ||
|
||
type Props = { | ||
dateString: string; | ||
}; | ||
|
||
export default function Date({ dateString }: Props) { | ||
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="/" className="hover:underline"> | ||
Blog | ||
</Link> | ||
. | ||
</h2> | ||
); | ||
} |
Oops, something went wrong.