From 2c01166bdf4aa4c9d945716a78f1e4730067c695 Mon Sep 17 00:00:00 2001 From: Jesse Date: Wed, 10 Jun 2020 17:41:55 +0200 Subject: [PATCH 01/13] added graphcms --- examples/cms-graphcms/.env.example | 4 + examples/cms-graphcms/.gitignore | 32 ++++ examples/cms-graphcms/README.md | 130 +++++++++++++++ examples/cms-graphcms/components/alert.js | 42 +++++ examples/cms-graphcms/components/avatar.js | 8 + examples/cms-graphcms/components/container.js | 3 + .../cms-graphcms/components/cover-image.js | 28 ++++ examples/cms-graphcms/components/date.js | 6 + examples/cms-graphcms/components/footer.js | 30 ++++ examples/cms-graphcms/components/header.js | 12 ++ examples/cms-graphcms/components/hero-post.js | 37 +++++ examples/cms-graphcms/components/intro.js | 28 ++++ examples/cms-graphcms/components/layout.js | 16 ++ examples/cms-graphcms/components/meta.js | 42 +++++ .../cms-graphcms/components/more-stories.js | 24 +++ examples/cms-graphcms/components/post-body.js | 10 ++ .../cms-graphcms/components/post-header.js | 26 +++ .../cms-graphcms/components/post-preview.js | 31 ++++ .../components/post-styles.module.css | 22 +++ .../cms-graphcms/components/post-title.js | 7 + .../components/section-separator.js | 3 + examples/cms-graphcms/jsconfig.json | 5 + examples/cms-graphcms/lib/constants.js | 5 + examples/cms-graphcms/lib/graphcms.js | 154 ++++++++++++++++++ examples/cms-graphcms/package.json | 21 +++ examples/cms-graphcms/pages/_app.js | 7 + examples/cms-graphcms/pages/_document.js | 15 ++ .../cms-graphcms/pages/api/exit-preview.js | 8 + examples/cms-graphcms/pages/api/preview.js | 28 ++++ examples/cms-graphcms/pages/index.js | 43 +++++ examples/cms-graphcms/pages/posts/[slug].js | 74 +++++++++ examples/cms-graphcms/postcss.config.js | 21 +++ .../public/favicon/android-chrome-192x192.png | Bin 0 -> 4795 bytes .../public/favicon/android-chrome-512x512.png | Bin 0 -> 14640 bytes .../public/favicon/apple-touch-icon.png | Bin 0 -> 1327 bytes .../public/favicon/browserconfig.xml | 9 + .../public/favicon/favicon-16x16.png | Bin 0 -> 595 bytes .../public/favicon/favicon-32x32.png | Bin 0 -> 880 bytes .../cms-graphcms/public/favicon/favicon.ico | Bin 0 -> 15086 bytes .../public/favicon/mstile-150x150.png | Bin 0 -> 3567 bytes .../public/favicon/safari-pinned-tab.svg | 33 ++++ .../public/favicon/site.webmanifest | 19 +++ examples/cms-graphcms/styles/index.css | 5 + examples/cms-graphcms/tailwind.config.js | 32 ++++ 44 files changed, 1020 insertions(+) create mode 100644 examples/cms-graphcms/.env.example create mode 100644 examples/cms-graphcms/.gitignore create mode 100644 examples/cms-graphcms/README.md create mode 100644 examples/cms-graphcms/components/alert.js create mode 100644 examples/cms-graphcms/components/avatar.js create mode 100644 examples/cms-graphcms/components/container.js create mode 100644 examples/cms-graphcms/components/cover-image.js create mode 100644 examples/cms-graphcms/components/date.js create mode 100644 examples/cms-graphcms/components/footer.js create mode 100644 examples/cms-graphcms/components/header.js create mode 100644 examples/cms-graphcms/components/hero-post.js create mode 100644 examples/cms-graphcms/components/intro.js create mode 100644 examples/cms-graphcms/components/layout.js create mode 100644 examples/cms-graphcms/components/meta.js create mode 100644 examples/cms-graphcms/components/more-stories.js create mode 100644 examples/cms-graphcms/components/post-body.js create mode 100644 examples/cms-graphcms/components/post-header.js create mode 100644 examples/cms-graphcms/components/post-preview.js create mode 100644 examples/cms-graphcms/components/post-styles.module.css create mode 100644 examples/cms-graphcms/components/post-title.js create mode 100644 examples/cms-graphcms/components/section-separator.js create mode 100644 examples/cms-graphcms/jsconfig.json create mode 100644 examples/cms-graphcms/lib/constants.js create mode 100644 examples/cms-graphcms/lib/graphcms.js create mode 100644 examples/cms-graphcms/package.json create mode 100644 examples/cms-graphcms/pages/_app.js create mode 100644 examples/cms-graphcms/pages/_document.js create mode 100644 examples/cms-graphcms/pages/api/exit-preview.js create mode 100644 examples/cms-graphcms/pages/api/preview.js create mode 100644 examples/cms-graphcms/pages/index.js create mode 100644 examples/cms-graphcms/pages/posts/[slug].js create mode 100644 examples/cms-graphcms/postcss.config.js create mode 100644 examples/cms-graphcms/public/favicon/android-chrome-192x192.png create mode 100644 examples/cms-graphcms/public/favicon/android-chrome-512x512.png create mode 100644 examples/cms-graphcms/public/favicon/apple-touch-icon.png create mode 100644 examples/cms-graphcms/public/favicon/browserconfig.xml create mode 100644 examples/cms-graphcms/public/favicon/favicon-16x16.png create mode 100644 examples/cms-graphcms/public/favicon/favicon-32x32.png create mode 100644 examples/cms-graphcms/public/favicon/favicon.ico create mode 100644 examples/cms-graphcms/public/favicon/mstile-150x150.png create mode 100644 examples/cms-graphcms/public/favicon/safari-pinned-tab.svg create mode 100644 examples/cms-graphcms/public/favicon/site.webmanifest create mode 100644 examples/cms-graphcms/styles/index.css create mode 100644 examples/cms-graphcms/tailwind.config.js diff --git a/examples/cms-graphcms/.env.example b/examples/cms-graphcms/.env.example new file mode 100644 index 0000000000000..b020e7a7348e7 --- /dev/null +++ b/examples/cms-graphcms/.env.example @@ -0,0 +1,4 @@ +NEXT_EXAMPLE_CMS_GCMS_PREVIEW_SECRET= +NEXT_EXAMPLE_CMS_GCMS_PROJECT_API= +NEXT_EXAMPLE_CMS_GCMS_PROD_AUTH_TOKEN= +NEXT_EXAMPLE_CMS_GCMS_DEV_AUTH_TOKEN= diff --git a/examples/cms-graphcms/.gitignore b/examples/cms-graphcms/.gitignore new file mode 100644 index 0000000000000..b6022f53f8a33 --- /dev/null +++ b/examples/cms-graphcms/.gitignore @@ -0,0 +1,32 @@ +# 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 + +# 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 \ No newline at end of file diff --git a/examples/cms-graphcms/README.md b/examples/cms-graphcms/README.md new file mode 100644 index 0000000000000..60ad6e5f065e9 --- /dev/null +++ b/examples/cms-graphcms/README.md @@ -0,0 +1,130 @@ +# A statically generated blog example using Next.js and GraphCMS + +This example showcases Next.js's [Static Generation](https://nextjs.org/docs/basic-features/pages) feature using [GraphCMS](https://www.graphcms.com/) as the data source. + +## Demo + +### [https://next-blog-graphcms.now.sh/](https://next-blog-graphcms.now.sh/) + +### Related examples + +- [Blog Starter](/examples/blog-starter) +- [DatoCMS](/examples/cms-datocms) +- [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/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: + +```bash +npm init next-app --example cms-graphcms cms-graphcms-app +# or +yarn create next-app --example cms-graphcms cms-graphcms-app +``` + +### Download manually + +Download the example: + +```bash +curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/cms-graphcms +cd cms-graphcms +``` + +## Configuration + +### Step 1. Create an account and a project in GraphCMS + +First, [create an account in GraphCMS](https://app.graphcms.com). + +### Step 2. Create a new GraphCMS project + +After creating an account, create a new project from the "Blog Starter template" - be sure to include the example content. + +### Step 3. Copy your environment variables + +Copy the `.env.example` file in this directory to `.env.local` (which will be ignored by Git): + +```bash +cp .env.example .env.local +``` + +Then set each variable in `.env.local`: + +- `NEXT_EXAMPLE_CMS_GCMS_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). +- `NEXT_EXAMPLE_CMS_GCMS_PROJECT_API`: Get the `Project API` endpoint value from the Settings > API Access page. +- `NEXT_EXAMPLE_CMS_GCMS_PROD_AUTH_TOKEN`: Copy the API token from your project API Access Settings. This will only query content that is published. +- `NEXT_EXAMPLE_CMS_GCMS_DEV_AUTH_TOKEN`: Copy the API token from your project API Access Settings. This will only query content that is in draft. + +You can find all of these tokens under Settings > API Access (lefthand menu, bottom group of icons.) + +Your `.env.local` file should look like this: + +```bash +NEXT_EXAMPLE_CMS_GCMS_PREVIEW_SECRET=... +NEXT_EXAMPLE_CMS_GCMS_PROJECT_API=... +NEXT_EXAMPLE_CMS_GCMS_PROD_AUTH_TOKEN=... +NEXT_EXAMPLE_CMS_GCMS_DEV_AUTH_TOKEN=... + +``` + +### Step 4. 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/zeit/next.js/discussions). + +### Step 5. Try preview mode + +In GraphCMS, go to one of the posts you've created and: + +- **Update the title**. For example, you can add `[Draft]` in front of the title. +- After you edit the document save the article as a draft, but **DO NOT** click **Publish**. By doing this, the post will be in the draft stage. + +Now, if you go to the post page on localhost, you won't see the updated title. However, if you use the **Preview Mode**, you'll be able to see the change ([Documentation](/docs/advanced-features/preview-mode.md)). + +To view the preview, transform the url to the following format: `http://localhost:3000/api/preview?secret=[YOUR_SECRET_TOKEN]&slug=[SLUG_TO_PREVIEW]` where \[YOUR_SECRET_TOKEN]\ is the same secret you defined in the `.env` file and \[SLUG_TO_PREVIEW]\ is the slug of one of the posts you want to preview. + +You should now be able to see the updated title. To exit the preview mode, you can click on _"Click here to exit preview mode"_ at the top. + +### Step 6. Deploy on Vercel + +You can deploy this 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/cli#commands/secrets)). + +Install [Vercel CLI](https://vercel.com/download), log in to your account from the CLI by running the following command. + +```bash +vercel login +``` + +Now, link your project to a Vercel project by running `vercel` in the terminal and follow the command-line prompts. It is usually safe to accept all the defaults. + +Before we deploy, we need to add our secrets to the the Vercel run time. The commandline pattern for adding secrts to vercel looks like: + +```bash +vercel secrets add my-secret "my value" +``` + +Run that command for each of the entries in our .env.local file. For example, adding the secret would look like + +```bash +vercel secrets add NEXT_EXAMPLE_CMS_GCMS_PREVIEW_SECRET "12345token" +``` + +Once all th secrets hav been added, you can re-run the vercel deploy with `vercel`. + +That's it! You now have a blog on Vercel, made with NextJS and powered by GraphCMS with preview's enabled! diff --git a/examples/cms-graphcms/components/alert.js b/examples/cms-graphcms/components/alert.js new file mode 100644 index 0000000000000..74b887c1a0460 --- /dev/null +++ b/examples/cms-graphcms/components/alert.js @@ -0,0 +1,42 @@ +import Container from './container' +import cn from 'classnames' +import { EXAMPLE_PATH } from '../lib/constants' + +export default function Alert({ preview }) { + return ( +
+ +
+ {preview ? ( + <> + This page is a preview.{' '} + + Click here + {' '} + to exit preview mode. + + ) : ( + <> + The source code for this blog is{' '} + + available on GitHub + + . + + )} +
+
+
+ ) +} diff --git a/examples/cms-graphcms/components/avatar.js b/examples/cms-graphcms/components/avatar.js new file mode 100644 index 0000000000000..2dcc7eee10693 --- /dev/null +++ b/examples/cms-graphcms/components/avatar.js @@ -0,0 +1,8 @@ +export default function Avatar({ name, picture }) { + return ( +
+ {name} +
{name}
+
+ ) +} diff --git a/examples/cms-graphcms/components/container.js b/examples/cms-graphcms/components/container.js new file mode 100644 index 0000000000000..fc1c29dfb0747 --- /dev/null +++ b/examples/cms-graphcms/components/container.js @@ -0,0 +1,3 @@ +export default function Container({ children }) { + return
{children}
+} diff --git a/examples/cms-graphcms/components/cover-image.js b/examples/cms-graphcms/components/cover-image.js new file mode 100644 index 0000000000000..28bbeaa563605 --- /dev/null +++ b/examples/cms-graphcms/components/cover-image.js @@ -0,0 +1,28 @@ +import cn from "classnames"; +import Link from "next/link"; + +export default function CoverImage({ title, url, slug }) { + const image = ( + {`Cover + ); + + return ( +
+ {slug ? ( + + {image} + + ) : ( + image + )} +
+ ); +} diff --git a/examples/cms-graphcms/components/date.js b/examples/cms-graphcms/components/date.js new file mode 100644 index 0000000000000..eac5681378bfd --- /dev/null +++ b/examples/cms-graphcms/components/date.js @@ -0,0 +1,6 @@ +import { parseISO, format } from 'date-fns' + +export default function Date({ dateString }) { + const date = parseISO(dateString) + return +} diff --git a/examples/cms-graphcms/components/footer.js b/examples/cms-graphcms/components/footer.js new file mode 100644 index 0000000000000..dbde8ff306efd --- /dev/null +++ b/examples/cms-graphcms/components/footer.js @@ -0,0 +1,30 @@ +import Container from './container' +import { EXAMPLE_PATH } from '../lib/constants' + +export default function Footer() { + return ( + + ) +} diff --git a/examples/cms-graphcms/components/header.js b/examples/cms-graphcms/components/header.js new file mode 100644 index 0000000000000..562e7e3eebb6a --- /dev/null +++ b/examples/cms-graphcms/components/header.js @@ -0,0 +1,12 @@ +import Link from 'next/link' + +export default function Header() { + return ( +

+ + Blog + + . +

+ ) +} diff --git a/examples/cms-graphcms/components/hero-post.js b/examples/cms-graphcms/components/hero-post.js new file mode 100644 index 0000000000000..115cdf8bb8130 --- /dev/null +++ b/examples/cms-graphcms/components/hero-post.js @@ -0,0 +1,37 @@ +import Avatar from "../components/avatar"; +import Date from "../components/date"; +import CoverImage from "../components/cover-image"; +import Link from "next/link"; + +export default function HeroPost({ + title, + coverImage, + date, + excerpt, + author, + slug, +}) { + return ( +
+
+ +
+
+
+

+ + {title} + +

+
+ +
+
+
+

{excerpt}

+ +
+
+
+ ); +} diff --git a/examples/cms-graphcms/components/intro.js b/examples/cms-graphcms/components/intro.js new file mode 100644 index 0000000000000..5931b3c5961bd --- /dev/null +++ b/examples/cms-graphcms/components/intro.js @@ -0,0 +1,28 @@ +import { CMS_NAME, CMS_URL } from '../lib/constants' + +export default function Intro() { + return ( +
+

+ Blog. +

+

+ A statically generated blog example using{' '} + + Next.js + {' '} + and{' '} + + {CMS_NAME} + + . +

+
+ ) +} diff --git a/examples/cms-graphcms/components/layout.js b/examples/cms-graphcms/components/layout.js new file mode 100644 index 0000000000000..99d95353131e0 --- /dev/null +++ b/examples/cms-graphcms/components/layout.js @@ -0,0 +1,16 @@ +import Alert from '../components/alert' +import Footer from '../components/footer' +import Meta from '../components/meta' + +export default function Layout({ preview, children }) { + return ( + <> + +
+ +
{children}
+
+