diff --git a/docs/basic-features/data-fetching.md b/docs/basic-features/data-fetching.md index b5eca093ed8bdd1..44c6a09c31c3c2c 100644 --- a/docs/basic-features/data-fetching.md +++ b/docs/basic-features/data-fetching.md @@ -428,6 +428,7 @@ function Profile() { Take a look at the following examples to learn more: +- [Blog Starter using markdown files](https://github.com/zeit/next.js/tree/canary/examples/blog-starter) ([Demo](https://next-blog-starter.now.sh/)) - [DatoCMS Example](https://github.com/zeit/next.js/tree/canary/examples/cms-datocms) ([Demo](https://next-blog-datocms.now.sh/)) ## Learn more diff --git a/docs/basic-features/pages.md b/docs/basic-features/pages.md index 9c156edbda0797b..204e73b9b8e0b51 100644 --- a/docs/basic-features/pages.md +++ b/docs/basic-features/pages.md @@ -246,6 +246,7 @@ We've discussed two forms of pre-rendering for Next.js. Take a look at the following examples to learn more: +- [Blog Starter using markdown files](https://github.com/zeit/next.js/tree/canary/examples/blog-starter) ([Demo](https://next-blog-starter.now.sh/)) - [DatoCMS Example](https://github.com/zeit/next.js/tree/canary/examples/cms-datocms) ([Demo](https://next-blog-datocms.now.sh/)) ## Learn more diff --git a/examples/blog-starter/.babelrc b/examples/blog-starter/.babelrc deleted file mode 100644 index ecad227b84ef7ac..000000000000000 --- 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 000000000000000..5900fa96e8d3ebb --- /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 d5045de295772ab..520e465f0e38aa2 100644 --- a/examples/blog-starter/README.md +++ b/examples/blog-starter/README.md @@ -1,16 +1,18 @@ -# Blog starter example +# A statically generated blog example using Next.js and Markdown -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](https://nextjs.org/docs/basic-features/pages) feature using markdown files as the data source. -The blog is still barebones and need more improvements and styling, but this should be enough to get you started. +The blog posts are stored in `/_posts` as markdown files with front matter support. Adding a new markdown file in there will create a new blog post. -[Demo deployed in Now](https://nextjs-blog-starter.now.sh/) +To create the blog posts we use [`remark`](https://github.com/gnab/remark) and [`remark-html`](https://github.com/remarkjs/remark-html) to convert the markdown files into an HTML string, and then send it down as a prop to the page. The metadata of every post is handled by [`gray-matter`](https://github.com/jonschlinkert/gray-matter) and also sent in props to the page. -## Deploy your own +## Demo -Deploy the example using [ZEIT Now](https://zeit.co/now): +[https://next-blog-starter.now.sh/](https://next-blog-starter.now.sh/) -[![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) +### Related examples + +- [DatoCMS](/examples/cms-datocms) ## How to use @@ -26,22 +28,25 @@ yarn create next-app --example blog-starter blog-starter-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/blog-starter cd blog-starter ``` -### Run locally - -Install and run the development server: +Install dependencies and run the example: ```bash +npm install +npm run dev + +# or + yarn install -now dev +yarn dev ``` -### Deploy +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). 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)). diff --git a/examples/blog-starter/_posts/dynamic-routing.md b/examples/blog-starter/_posts/dynamic-routing.md new file mode 100644 index 000000000000000..76a0b0a06ad55f3 --- /dev/null +++ b/examples/blog-starter/_posts/dynamic-routing.md @@ -0,0 +1,19 @@ +--- +title: 'Dynamic Routing and Static Generation' +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: '/assets/blog/dynamic-routing/cover.webp' +date: '2020-03-16T05:35:07.322Z' +author: + name: JJ Kasper + picture: '/assets/blog/authors/jj.jpeg' +ogImage: + url: '/assets/blog/dynamic-routing/cover.webp' +--- + +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/_posts/hello-world.md b/examples/blog-starter/_posts/hello-world.md new file mode 100644 index 000000000000000..005b883a60ae632 --- /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: '/assets/blog/hello-world/cover.jpg' +date: '2020-03-16T05:35:07.322Z' +author: + name: Tim Neutkens + picture: '/assets/blog/authors/tim.jpeg' +ogImage: + url: '/assets/blog/hello-world/cover.jpg' +--- + +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/_posts/preview.md b/examples/blog-starter/_posts/preview.md new file mode 100644 index 000000000000000..15b4ae5132d2601 --- /dev/null +++ b/examples/blog-starter/_posts/preview.md @@ -0,0 +1,19 @@ +--- +title: 'Preview Mode for Static Generation' +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: '/assets/blog/preview/cover.webp' +date: '2020-03-16T05:35:07.322Z' +author: + name: Joe Haddad + picture: '/assets/blog/authors/joe.jpeg' +ogImage: + url: '/assets/blog/preview/cover.webp' +--- + +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 2ddf1d03693f037..000000000000000 --- 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 000000000000000..3530e66e59c8d35 --- /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 000000000000000..2dcc7eee1069383 --- /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 faa7410409060d1..000000000000000 --- 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 1f528a5a8bbe207..fc1c29dfb074756 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 000000000000000..b9df0f27e235470 --- /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 000000000000000..eac5681378bfd4f --- /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 663ab794d94e9a0..dbde8ff306efdbf 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 ( -