From 608492e7355d324b9fbace9a6bbdc3383199c7ec Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sat, 14 Mar 2020 11:48:54 +0100 Subject: [PATCH 1/9] Update blog-starter example --- examples/blog-starter/.babelrc | 4 - examples/blog-starter/.gitignore | 2 + examples/blog-starter/README.md | 150 ++++++++++++-- examples/blog-starter/_posts/hello-world.md | 19 ++ examples/blog-starter/blog.config.js | 13 -- examples/blog-starter/components/alert.js | 42 ++++ examples/blog-starter/components/avatar.js | 8 + .../components/blog-index-item.js | 32 --- examples/blog-starter/components/container.js | 15 +- .../blog-starter/components/cover-image.js | 25 +++ examples/blog-starter/components/date.js | 6 + examples/blog-starter/components/footer.js | 45 +++-- examples/blog-starter/components/head.js | 57 ------ examples/blog-starter/components/header.js | 148 +------------- examples/blog-starter/components/hero-post.js | 37 ++++ examples/blog-starter/components/intro.js | 21 ++ examples/blog-starter/components/layout.js | 16 ++ .../components/layouts/blog-post.js | 86 -------- .../components/layouts/default.js | 18 -- .../blog-starter/components/layouts/page.js | 21 -- .../components/markdown-styles.module.css | 18 ++ examples/blog-starter/components/meta.js | 42 ++++ .../blog-starter/components/more-stories.js | 24 +++ examples/blog-starter/components/nav.js | 20 -- .../blog-starter/components/next-prev-post.js | 32 --- examples/blog-starter/components/post-body.js | 12 ++ .../blog-starter/components/post-header.js | 26 +++ .../blog-starter/components/post-preview.js | 35 ++++ .../blog-starter/components/post-title.js | 7 + examples/blog-starter/components/profile.js | 39 ---- .../components/section-separator.js | 3 + .../components/syntax-highlight.js | 191 ------------------ examples/blog-starter/components/title.js | 35 ---- .../components/utils/published-at.js | 26 --- examples/blog-starter/lib/api.js | 39 ++++ examples/blog-starter/lib/constants.js | 4 + examples/blog-starter/lib/markdownToHtml.js | 9 + examples/blog-starter/next.config.js | 39 ---- examples/blog-starter/now.json | 8 - examples/blog-starter/package.json | 36 ++-- examples/blog-starter/pages/_app.js | 7 + examples/blog-starter/pages/_document.js | 9 +- examples/blog-starter/pages/about.mdx | 21 -- examples/blog-starter/pages/index.js | 119 ++++------- examples/blog-starter/pages/posts/[slug].js | 84 ++++++++ .../pages/posts/deploy-to-now.mdx | 23 --- .../pages/posts/syntax-highlighting.mdx | 75 ------- examples/blog-starter/pages/posts/welcome.mdx | 28 --- examples/blog-starter/postcss.config.js | 18 ++ examples/blog-starter/posts/get-blog-posts.js | 30 --- examples/blog-starter/posts/index.js | 16 -- examples/blog-starter/posts/rss-feed.js | 32 --- examples/blog-starter/public/favicon.ico | Bin 15086 -> 0 bytes .../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 .../blog-starter/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 ++ .../blog-starter/public/static/_jolvera.png | Bin 37183 -> 0 bytes examples/blog-starter/public/static/next.svg | 5 - .../public/static/site-feature.png | Bin 41756 -> 0 bytes examples/blog-starter/styles/index.css | 5 + examples/blog-starter/tailwind.config.js | 32 +++ 68 files changed, 829 insertions(+), 1146 deletions(-) delete mode 100644 examples/blog-starter/.babelrc create mode 100644 examples/blog-starter/.gitignore create mode 100644 examples/blog-starter/_posts/hello-world.md delete mode 100644 examples/blog-starter/blog.config.js create mode 100644 examples/blog-starter/components/alert.js create mode 100644 examples/blog-starter/components/avatar.js delete mode 100644 examples/blog-starter/components/blog-index-item.js create mode 100644 examples/blog-starter/components/cover-image.js create mode 100644 examples/blog-starter/components/date.js delete mode 100644 examples/blog-starter/components/head.js create mode 100644 examples/blog-starter/components/hero-post.js create mode 100644 examples/blog-starter/components/intro.js create mode 100644 examples/blog-starter/components/layout.js delete mode 100644 examples/blog-starter/components/layouts/blog-post.js delete mode 100644 examples/blog-starter/components/layouts/default.js delete mode 100644 examples/blog-starter/components/layouts/page.js create mode 100644 examples/blog-starter/components/markdown-styles.module.css create mode 100644 examples/blog-starter/components/meta.js create mode 100644 examples/blog-starter/components/more-stories.js delete mode 100644 examples/blog-starter/components/nav.js delete mode 100644 examples/blog-starter/components/next-prev-post.js create mode 100644 examples/blog-starter/components/post-body.js create mode 100644 examples/blog-starter/components/post-header.js create mode 100644 examples/blog-starter/components/post-preview.js create mode 100644 examples/blog-starter/components/post-title.js delete mode 100644 examples/blog-starter/components/profile.js create mode 100644 examples/blog-starter/components/section-separator.js delete mode 100644 examples/blog-starter/components/syntax-highlight.js delete mode 100644 examples/blog-starter/components/title.js delete mode 100644 examples/blog-starter/components/utils/published-at.js create mode 100644 examples/blog-starter/lib/api.js create mode 100644 examples/blog-starter/lib/constants.js create mode 100644 examples/blog-starter/lib/markdownToHtml.js delete mode 100644 examples/blog-starter/next.config.js delete mode 100644 examples/blog-starter/now.json create mode 100644 examples/blog-starter/pages/_app.js delete mode 100644 examples/blog-starter/pages/about.mdx create mode 100644 examples/blog-starter/pages/posts/[slug].js delete mode 100644 examples/blog-starter/pages/posts/deploy-to-now.mdx delete mode 100644 examples/blog-starter/pages/posts/syntax-highlighting.mdx delete mode 100644 examples/blog-starter/pages/posts/welcome.mdx create mode 100644 examples/blog-starter/postcss.config.js delete mode 100644 examples/blog-starter/posts/get-blog-posts.js delete mode 100644 examples/blog-starter/posts/index.js delete mode 100644 examples/blog-starter/posts/rss-feed.js delete mode 100644 examples/blog-starter/public/favicon.ico create mode 100644 examples/blog-starter/public/favicon/android-chrome-192x192.png create mode 100644 examples/blog-starter/public/favicon/android-chrome-512x512.png create mode 100644 examples/blog-starter/public/favicon/apple-touch-icon.png create mode 100644 examples/blog-starter/public/favicon/browserconfig.xml create mode 100644 examples/blog-starter/public/favicon/favicon-16x16.png create mode 100644 examples/blog-starter/public/favicon/favicon-32x32.png create mode 100644 examples/blog-starter/public/favicon/favicon.ico create mode 100644 examples/blog-starter/public/favicon/mstile-150x150.png create mode 100644 examples/blog-starter/public/favicon/safari-pinned-tab.svg create mode 100644 examples/blog-starter/public/favicon/site.webmanifest delete mode 100644 examples/blog-starter/public/static/_jolvera.png delete mode 100644 examples/blog-starter/public/static/next.svg delete mode 100644 examples/blog-starter/public/static/site-feature.png create mode 100644 examples/blog-starter/styles/index.css create mode 100644 examples/blog-starter/tailwind.config.js diff --git a/examples/blog-starter/.babelrc b/examples/blog-starter/.babelrc deleted file mode 100644 index ecad227b84ef7..0000000000000 --- a/examples/blog-starter/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["next/babel"], - "plugins": ["preval", "macros"] -} \ No newline at end of file diff --git a/examples/blog-starter/.gitignore b/examples/blog-starter/.gitignore new file mode 100644 index 0000000000000..5900fa96e8d3e --- /dev/null +++ b/examples/blog-starter/.gitignore @@ -0,0 +1,2 @@ +.env +.now \ No newline at end of file diff --git a/examples/blog-starter/README.md b/examples/blog-starter/README.md index d5045de295772..ef71e5c4b3747 100644 --- a/examples/blog-starter/README.md +++ b/examples/blog-starter/README.md @@ -1,16 +1,10 @@ -# Blog starter example +# A statically generated blog example using Next.js and DatoCMS -This is an example of a blog built with Next.js. [Read more about the motivation and how it is built](https://jolvera.dev/posts/rebuilding-my-blog-with-nextjs). +This example showcases Next.js's [Static Generation](/docs/basic-features/pages.md) feature using [DatoCMS](https://www.datocms.com/) as the data source. -The blog is still barebones and need more improvements and styling, but this should be enough to get you started. +## Demo -[Demo deployed in Now](https://nextjs-blog-starter.now.sh/) - -## Deploy your own - -Deploy the example using [ZEIT Now](https://zeit.co/now): - -[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/next.js/tree/canary/examples/blog-starter) +### [https://next-blog-datocms.now.sh/](https://next-blog-datocms.now.sh/) ## How to use @@ -19,29 +13,145 @@ Deploy the example using [ZEIT Now](https://zeit.co/now): 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 blog-starter blog-starter-app +npm init next-app --example cms-datocms cms-datocms-app # or -yarn create next-app --example blog-starter blog-starter-app +yarn create next-app --example cms-datocms cms-datocms-app ``` ### Download manually -Download the example [or clone the repo](https://github.com/zeit/next.js): +Download the example: + +```bash +curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/cms-datocms +cd cms-datocms +``` + +## Configuration + +### Step 1. Create an account and a project on DatoCMS + +First, [create an account on DatoCMS](https://datocms.com). + +After creating an account, create a **new project** from the dashboard. You can select a **Blank Project**. + +### Step 2. Create an `Author` model + +From the project setting page, create a new **Model**. + +- The name should be `Author`. + +Next, add these fields (you don't have to modify the settings): + +- `Name` - **Text** field (**Single-line String**) +- `Picture` - **Media** field (**Single asset**) + +### Step 3. Create a `Post` model + +From the project setting page, create a new **Model**: + +- The name should be `Post`. +- **Important:** From the "Additional Settings" tab, turn on **Enable draft/published system.** This lets you preview the content. + +Next, add these fields (you don't have to modify the settings unless specified): + +- `Title` - **Text** field (**Single-line String**) +- `Content` - **Text** field (**Multiple-paragraph Text**) +- `Excerpt` - **Text** field (**Single-line String**) +- `Cover Image` - **Media** field (**Single asset**) +- `Date` - **Date and time** field (**Date**) +- `Author` - **Links** field (**Single link**) , and from the "Validations" tab under "Accept only specified model", select **Author**. +- `Slug` - **SEO** field (**Slug**), and from the "Validations" tab under "Reference field" select **Title**. + +### Step 4. Populate Content + +From the **Content** menu at the top, select **Author** and create a new record. + +- You just need **1 Author record**. +- Use dummy data for the text. +- For the image, you can download one from [Unsplash](https://unsplash.com/). + +Next, select **Post** and create a new record. + +- We recommend creating at least **2 Post records**. +- Use dummy data for the text. +- You can write markdown for the **Content** field. +- For the images, you can download ones from [Unsplash](https://unsplash.com/). +- Pick the **Author** you created earlier. + +**Important:** For each post record, you need to click **Publish** after saving. If not, the post will be in the draft state. + +### Step 5. Set up environment variables + +Go to the **Settings** menu at the top and click **API tokens**. + +Then click **Read-only API token** and copy the token. + +Next, copy the `.env.example` file in this directory to `.env` (which will be ignored by Git): ```bash -curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/blog-starter -cd blog-starter +cp .env.example .env ``` -### Run locally +Then set each variable on `.env`: + +- `NEXT_EXAMPLE_CMS_DATOCMS_API_TOKEN` should be the API token you just copied. +- `NEXT_EXAMPLE_CMS_DATOCMS_PREVIEW_SECRET` can be any random string (but avoid spaces), like `MY_SECRET` - this is used for [the Preview Mode](/docs/advanced-features/preview-mode.md). + +Your `.env` file should look like this: + +```bash +NEXT_EXAMPLE_CMS_DATOCMS_API_TOKEN=... +NEXT_EXAMPLE_CMS_DATOCMS_PREVIEW_SECRET=... +``` -Install and run the development server: +### Step 6. Run Next.js in development mode ```bash +npm install +npm run dev + +# or + yarn install -now dev +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 7. Try preview mode + +On DatoCMS, go to one of the posts you've created and: + +- **Update the title**. For example, you can add `[Draft]` in front of the title. +- Click **Save**, but **DO NOT** click **Publish**. By doing this, the post will be in the draft state. + +(If it doesn't become draft, you need to go to the model settings for `Post`, go to **Additional Settings**, and turn on **Enable draft/published system**.) + +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 enable the Preview Mode, go to this URL: + +``` +http://localhost:3000/api/preview?secret=&slug= ``` -### Deploy +- `` should be the string you entered for `NEXT_EXAMPLE_CMS_DATOCMS_PREVIEW_SECRET`. +- `` should be the post's `slug` attribute (you can check on DatoCMS). + +You should now be able to see the updated title. To exit the preview mode, you can click **Click here to exit preview mode** at the top. + +### Step 8. Deploy on ZEIT Now + +You can deploy this app to the cloud with [ZEIT Now](https://zeit.co/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). + +To deploy on ZEIT Now, you need to set the environment variables with **Now Secrets** using [Now CLI](https://zeit.co/download) ([Documentation](https://zeit.co/docs/now-cli#commands/secrets)). + +Install [Now CLI](https://zeit.co/download), log in to your account from the CLI, and run the following commands to add the environment variables. Replace `` and `` with the corresponding strings in `.env`. + +``` +now secrets add next_example_cms_datocms_api_token +now secrets add next_example_cms_datocms_preview_secret +``` -Deploy it to the cloud with [ZEIT Now](https://zeit.co/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). +Then push the project to GitHub/GitLab/Bitbucket and [import to ZEIT Now](https://zeit.co/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) to deploy. diff --git a/examples/blog-starter/_posts/hello-world.md b/examples/blog-starter/_posts/hello-world.md new file mode 100644 index 0000000000000..30c9f0378d05b --- /dev/null +++ b/examples/blog-starter/_posts/hello-world.md @@ -0,0 +1,19 @@ +--- +title: 'Learn How to Pre-render Pages Using Static Generation with Next.js' +excerpt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilisi morbi tempus.' +coverImage: 'https://www.datocms-assets.com/23626/1583571209-jj-ying-7jx0-bfiuxq-unsplash.jpg?fit=crop&fm=jpg&h=1000&w=2000' # '/static/blog/hello-world/cover.png' +date: '2019-12-08T05:35:07.322Z' +author: + name: Tim Neutkens + picture: 'https://www.datocms-assets.com/23626/1583571355-6324199.jpeg?fit=crop&fm=jpg&h=100&sat=-100&w=100' # '/static/blog/authors/someone' +ogImage: + url: '/static/blog/hello-world/card.png' +--- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilisi morbi tempus. Praesent elementum facilisis leo vel fringilla. Congue mauris rhoncus aenean vel. Egestas sed tempus urna et pharetra pharetra massa massa ultricies. + +Venenatis cras sed felis eget velit. Consectetur libero id faucibus nisl tincidunt. Gravida in fermentum et sollicitudin ac orci phasellus egestas tellus. Volutpat consequat mauris nunc congue nisi vitae. Id aliquet risus feugiat in ante metus dictum at tempor. Sed blandit libero volutpat sed cras. Sed odio morbi quis commodo odio aenean sed adipiscing. Velit euismod in pellentesque massa placerat. Mi bibendum neque egestas congue quisque egestas diam in arcu. Nisi lacus sed viverra tellus in. Nibh cras pulvinar mattis nunc sed. Luctus accumsan tortor posuere ac ut consequat semper viverra. Fringilla ut morbi tincidunt augue interdum velit euismod. + +## Lorem Ipsum + +Tristique senectus et netus et malesuada fames ac turpis. Ridiculus mus mauris vitae ultricies leo integer malesuada nunc vel. In mollis nunc sed id semper. Egestas tellus rutrum tellus pellentesque. Phasellus vestibulum lorem sed risus ultricies tristique nulla. Quis blandit turpis cursus in hac habitasse platea dictumst quisque. Eros donec ac odio tempor orci dapibus ultrices. Aliquam sem et tortor consequat id porta nibh. Adipiscing elit duis tristique sollicitudin nibh sit amet commodo nulla. Diam vulputate ut pharetra sit amet. Ut tellus elementum sagittis vitae et leo. Arcu non odio euismod lacinia at quis risus sed vulputate. diff --git a/examples/blog-starter/blog.config.js b/examples/blog-starter/blog.config.js deleted file mode 100644 index 2ddf1d03693f0..0000000000000 --- a/examples/blog-starter/blog.config.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = { - siteMeta: { - title: 'Next.js Starter Blog', - author: 'Juan Olvera', - image: '/static/site-feature.png', - description: 'Next.js starter blog', - siteUrl: 'https://nextjs-blog-starter.now.sh', - social: { - twitter: '_jolvera', - }, - postsPerPage: 5, - }, -} diff --git a/examples/blog-starter/components/alert.js b/examples/blog-starter/components/alert.js new file mode 100644 index 0000000000000..3530e66e59c8d --- /dev/null +++ b/examples/blog-starter/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 is page is a preview.{' '} + + Click here + {' '} + to exit preview mode. + + ) : ( + <> + The source code for this blog is{' '} + + available on GitHub + + . + + )} +
+
+
+ ) +} diff --git a/examples/blog-starter/components/avatar.js b/examples/blog-starter/components/avatar.js new file mode 100644 index 0000000000000..2dcc7eee10693 --- /dev/null +++ b/examples/blog-starter/components/avatar.js @@ -0,0 +1,8 @@ +export default function Avatar({ name, picture }) { + return ( +
+ {name} +
{name}
+
+ ) +} diff --git a/examples/blog-starter/components/blog-index-item.js b/examples/blog-starter/components/blog-index-item.js deleted file mode 100644 index faa7410409060..0000000000000 --- a/examples/blog-starter/components/blog-index-item.js +++ /dev/null @@ -1,32 +0,0 @@ -import Link from 'next/link' -import PublishedAt from './utils/published-at' - -const Post = ({ title, summary, date, path }) => ( -
-
-

- - {title} - -

- - -
-
{summary}
- -
-) - -export default Post diff --git a/examples/blog-starter/components/container.js b/examples/blog-starter/components/container.js index 1f528a5a8bbe2..fc1c29dfb0747 100644 --- a/examples/blog-starter/components/container.js +++ b/examples/blog-starter/components/container.js @@ -1,12 +1,3 @@ -const Container = ({ children }) => ( - <> -
{children}
- - -) - -export default Container +export default function Container({ children }) { + return
{children}
+} diff --git a/examples/blog-starter/components/cover-image.js b/examples/blog-starter/components/cover-image.js new file mode 100644 index 0000000000000..b9df0f27e2354 --- /dev/null +++ b/examples/blog-starter/components/cover-image.js @@ -0,0 +1,25 @@ +import cn from 'classnames' +import Link from 'next/link' + +export default function CoverImage({ title, src, slug }) { + const image = ( + {`Cover + ) + return ( +
+ {slug ? ( + + {image} + + ) : ( + image + )} +
+ ) +} diff --git a/examples/blog-starter/components/date.js b/examples/blog-starter/components/date.js new file mode 100644 index 0000000000000..eac5681378bfd --- /dev/null +++ b/examples/blog-starter/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/blog-starter/components/footer.js b/examples/blog-starter/components/footer.js index 663ab794d94e9..dbde8ff306efd 100644 --- a/examples/blog-starter/components/footer.js +++ b/examples/blog-starter/components/footer.js @@ -1,25 +1,30 @@ -import Profile from './profile' +import Container from './container' +import { EXAMPLE_PATH } from '../lib/constants' -function Footer() { +export default function Footer() { return ( -