Skip to content

Commit

Permalink
Docs: Recipe for Contentful data source (#17318)
Browse files Browse the repository at this point in the history
* Added recipe for sourcing from contentful

* Editing

* Moved Conentful recipe into recipe.md

* Prettier formatting

* Apply suggestions from code review

Co-Authored-By: Marcy Sutton <marcy@gatsbyjs.com>

* Removed issue note

Co-Authored-By: Marcy Sutton <marcy@gatsbyjs.com>

* More base-relative URLs.

* Linting

* Added example repo

* Added readme to sample

* Stronger language on environment variables

* Semantic example

Co-Authored-By: Marcy Sutton <marcy@gatsbyjs.com>

* Removed unneeded files from example, news in index

* Formatting for step 4

* Define example field types

* Tightened up a sentence

* Changed to using seeded blog space

* Use page context

* Unused graphql variable

* Edited readme

* Added env vars note

* Changed recipe to use contentful blog seed

* Removed duplicate content

* Applied suggestions from review

Co-Authored-By: Marcy Sutton <marcy@gatsbyjs.com>
Co-Authored-By: Michael <184316+muescha@users.noreply.github.com>

* Extra space

Co-Authored-By: Michael <184316+muescha@users.noreply.github.com>

* Applied code review suggestions

Co-Authored-By: Marcy Sutton <marcy@gatsbyjs.com>
Co-Authored-By: Michael <184316+muescha@users.noreply.github.com>
  • Loading branch information
3 people authored and gillkyle committed Oct 24, 2019
1 parent 8926acd commit 177d2e7
Show file tree
Hide file tree
Showing 12 changed files with 995 additions and 0 deletions.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
130 changes: 130 additions & 0 deletions docs/docs/recipes.md
Expand Up @@ -985,6 +985,136 @@ export const pageQuery = graphql`
- [Guide to creating pages from data programmatically](/docs/programmatically-create-pages-from-data/)
- [Example repo](https://github.com/gatsbyjs/gatsby/tree/master/examples/recipe-sourcing-markdown) for this recipe

### Sourcing data from Contentful

#### Prerequisites

- A [Gatsby site](/docs/quick-start/)
- A [Contentful account](https://www.contentful.com/)
- The [Contentful CLI](https://www.npmjs.com/package/contentful-cli) installed

#### Directions

1. Log in to Contentful with the CLI and follow the steps. It will help you create an account if you don't have one.
```shell
contentful login
```
2. Create a new space if you don't already have one. Make sure to save the space ID given to you at the end of the command. If you already have a Contentful space and space ID, you can skip steps 2 and 3.

Note: for new accounts, you can overwrite the default onboarding space. Check to see the [spaces included with your account](https://app.contentful.com/account/profile/space_memberships).

```shell
contentful space create --name 'Gatsby example'
```

3. Seed the new space with example blog content using the new space ID returned from the previous command, in place of `<space ID>`.

```shell
contentful space seed -s '<space ID>' -t blog
```

For example, with a space ID in place: `contentful space seed -s '22fzx88spbp7' -t blog`

4. Create a new access token for your space. Remember this token, as you will need it in step 6.

```shell
contentful space accesstoken create -s '<space ID>' --name 'Example token'
```

5. Install the `gatsby-source-contentful` plugin in your Gatsby site:

```shell
npm install --save gatsby-source-contentful
```

6. Edit the file `gatsby-config.js` and add the `gatsby-source-contentful` to the `plugins` array to enable the plugin. You should strongly consider using [environment variables](/docs/environment-variables/) to store your space ID and token for security purposes.

```javascript:title=gatsby-config.js
plugins: [
// add to array along with any other installed plugins
  // highlight-start
  {
resolve: `gatsby-source-contentful`,
options: {
spaceId: `<space ID>`, // or process.env.CONTENTFUL_SPACE_ID
accessToken: `<access token>`, // or process.env.CONTENTFUL_TOKEN
},
},
// highlight-end
],
```

7. Run `gatsby develop` and make sure the site compiled successfully.

8. Query data with the [GraphiQL editor](/docs/introducing-graphiql/) at `https://localhost:8000/___graphql`. The Contentful plugin adds several new node types to your site, including every content type in your Contentful website. Your example space with a "Blog Post" content type produces a `allContentfulBlogPost` node type in GraphQL.

![the graphql interface, with a sample query outlined below](./images/recipe-sourcing-contentful-graphql.png)

To query for Blog Post titles from Contentful, use the following GraphQL query:

```graphql
{
allContentfulBlogPost {
edges {
node {
title
}
}
}
}
```

Contentful nodes also include several metadata fields like `createdAt` or `node_locale`.

9. To show a list of links to the blog posts, create a new file in `/src/pages/blog.js`. This page will display all posts, sorted by updated date.

```jsx:title=src/pages/blog.js
import React from "react"
import { graphql, Link } from "gatsby"
const BlogPage = ({ data }) => (
<div>
<h1>Blog</h1>
<ul>
{data.allContentfulBlogPost.edges.map(({ node, index }) => (
<li key={index}>
<Link to={`/blog/${node.slug}`}>{node.title}</Link>
</li>
))}
</ul>
</div>
)
export default BlogPage
export const query = graphql`
{
allContentfulBlogPost(sort: { fields: [updatedAt] }) {
edges {
node {
title
slug
}
}
}
}
`
```

To continue building out your Contentful site including post detail pages, check out the rest of the [Gatsby docs](/docs/sourcing-from-contentful/) and additional resources below.

#### Additional resources

- [Building a Site with React and Contentful](/blog/2018-1-25-building-a-site-with-react-and-contentful/)
- [More on Sourcing from Contentful](/docs/sourcing-from-contentful/)
- [Contentful source plugin](/packages/gatsby-source-contentful/)
- [Long-text field types returned as objects](/packages/gatsby-source-contentful/#a-note-about-longtext-fields)
- [Example repository for this recipe](https://github.com/gatsbyjs/gatsby/tree/master/examples/recipe-sourcing-contentful)

### Pulling data from an external source and creating pages without GraphQL

You don't have to use the GraphQL data layer to include data in pages, [though there are reasons why you should consider GraphQL](/docs/why-gatsby-uses-graphql/). You can use the node `createPages` API to pull unstructured data directly into Gatsby sites rather than through GraphQL and source plugins.
Expand Down
3 changes: 3 additions & 0 deletions examples/recipe-sourcing-contentful/README.md
@@ -0,0 +1,3 @@
# Sourcing data from Contentful recipe example

This repo is an example Gatsby site that shows how to source data from Contentful. To get started, [follow the Gatsby recipe to create a sample Contentful space](https://www.gatsbyjs.org/docs/recipes/#sourcing-data-from-contentful).
17 changes: 17 additions & 0 deletions examples/recipe-sourcing-contentful/gatsby-config.js
@@ -0,0 +1,17 @@
module.exports = {
siteMetadata: {
title: `Gatsby Contentful Recipe`,
description: `Example Gatsby site sourcing data from Contentful.`,
author: `@gatsbyjs`,
},
plugins: [
{
resolve: `gatsby-source-contentful`,
options: {
spaceId: `[space ID]`, // or process.env.CONTENTFUL_SPACE_ID
accessToken: `[access token]`, // or process.env.CONTENTFUL_TOKEN
},
},
`gatsby-transformer-remark`,
],
}
30 changes: 30 additions & 0 deletions examples/recipe-sourcing-contentful/gatsby-node.js
@@ -0,0 +1,30 @@
const path = require(`path`)

exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
const result = await graphql(`
query {
allContentfulBlogPost {
edges {
node {
slug
title
childContentfulBlogPostBodyTextNode {
childMarkdownRemark {
html
}
}
}
}
}
}
`)

result.data.allContentfulBlogPost.edges.forEach(({ node }) => {
createPage({
path: `blog/${node.slug}`,
component: path.resolve(`./src/templates/blog-post.js`),
context: node,
})
})
}
39 changes: 39 additions & 0 deletions examples/recipe-sourcing-contentful/package.json
@@ -0,0 +1,39 @@
{
"name": "gatsby-recipe-sourcing-contentful",
"private": true,
"description": "A simple starter to get up and developing quickly with Gatsby",
"version": "0.1.0",
"author": "@gatsbyjs",
"dependencies": {
"gatsby": "^2.15.14",
"gatsby-image": "^2.2.18",
"gatsby-plugin-offline": "^2.2.10",
"gatsby-source-contentful": "^2.1.35",
"gatsby-transformer-remark": "^2.6.22",
"prop-types": "^15.7.2",
"react": "^16.9.0",
"react-dom": "^16.9.0"
},
"devDependencies": {
"prettier": "^1.18.2"
},
"keywords": [
"gatsby"
],
"license": "MIT",
"scripts": {
"build": "gatsby build",
"develop": "gatsby develop",
"format": "prettier --write \"**/*.{js,jsx,json,md}\"",
"start": "npm run develop",
"serve": "gatsby serve",
"test": "echo \"Write tests! -> https://gatsby.dev/unit-testing \""
},
"repository": {
"type": "git",
"url": "https://github.com/gatsbyjs/gatsby-starter-default"
},
"bugs": {
"url": "https://github.com/gatsbyjs/gatsby/issues"
}
}
42 changes: 42 additions & 0 deletions examples/recipe-sourcing-contentful/src/components/header.js
@@ -0,0 +1,42 @@
import { Link } from "gatsby"
import PropTypes from "prop-types"
import React from "react"

const Header = ({ siteTitle }) => (
<header
style={{
background: `rebeccapurple`,
marginBottom: `1.45rem`,
}}
>
<div
style={{
margin: `0 auto`,
maxWidth: 960,
padding: `1.45rem 1.0875rem`,
}}
>
<h1 style={{ margin: 0 }}>
<Link
to="/"
style={{
color: `white`,
textDecoration: `none`,
}}
>
{siteTitle}
</Link>
</h1>
</div>
</header>
)

Header.propTypes = {
siteTitle: PropTypes.string,
}

Header.defaultProps = {
siteTitle: ``,
}

export default Header

0 comments on commit 177d2e7

Please sign in to comment.