Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: Recipe for Contentful data source #17318

Merged
merged 32 commits into from Oct 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0e1cbab
Added recipe for sourcing from contentful
Sep 2, 2019
34060ee
Editing
Sep 2, 2019
2784824
Merge branch 'master' into docs/recipe-source-contentful-14949
sidharthachatterjee Sep 3, 2019
752dc44
Moved Conentful recipe into recipe.md
Sep 3, 2019
a936c23
Merge branch 'docs/recipe-source-contentful-14949' of https://github.…
Sep 3, 2019
a71302d
Merge branch 'master' of https://github.com/gatsbyjs/gatsby into docs…
Sep 3, 2019
f78e713
Prettier formatting
Sep 3, 2019
d392cb7
Apply suggestions from code review
kevee Sep 4, 2019
bc0a2bb
Removed issue note
kevee Sep 4, 2019
545f00e
More base-relative URLs.
Sep 4, 2019
78e8d57
Linting
Sep 4, 2019
319db1b
Merge remote-tracking branch 'upstream/master' into docs/recipe-sourc…
Sep 5, 2019
9d34136
Added example repo
Sep 10, 2019
8cf346a
Added readme to sample
Sep 10, 2019
1eb7a30
Stronger language on environment variables
Sep 11, 2019
6bf6201
Semantic example
kevee Sep 17, 2019
3fcf567
Removed unneeded files from example, news in index
Sep 17, 2019
b038316
Resolve merge
Sep 17, 2019
ef7b7a7
Formatting for step 4
Sep 17, 2019
95facc9
Define example field types
Sep 17, 2019
762db9a
Tightened up a sentence
Sep 17, 2019
4f60fb9
Changed to using seeded blog space
Sep 18, 2019
003d82b
Use page context
Sep 18, 2019
dc73101
Unused graphql variable
Sep 18, 2019
4f2126e
Edited readme
Sep 18, 2019
35d3464
Added env vars note
Sep 18, 2019
7b9d09b
Changed recipe to use contentful blog seed
Sep 20, 2019
f893794
Removed duplicate content
Sep 20, 2019
48d2ecf
Applied suggestions from review
kevee Sep 25, 2019
376eda5
Extra space
kevee Sep 25, 2019
2015385
Applied code review suggestions
kevee Oct 23, 2019
47249a5
Merge remote-tracking branch 'upstream/master' into docs/recipe-sourc…
Oct 24, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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/)
kevee marked this conversation as resolved.
Show resolved Hide resolved
- 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.
gillkyle marked this conversation as resolved.
Show resolved Hide resolved

```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'
gillkyle marked this conversation as resolved.
Show resolved Hide resolved
```

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
```
kevee marked this conversation as resolved.
Show resolved Hide resolved

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
},
},
kevee marked this conversation as resolved.
Show resolved Hide resolved
// highlight-end
],
```

7. Run `gatsby develop` and make sure the site compiled successfully.
muescha marked this conversation as resolved.
Show resolved Hide resolved

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`.
gillkyle marked this conversation as resolved.
Show resolved Hide resolved

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>
kevee marked this conversation as resolved.
Show resolved Hide resolved
)

export default BlogPage

export const query = graphql`
{
allContentfulBlogPost(sort: { fields: [updatedAt] }) {
edges {
node {
title
slug
}
}
}
}
`
```

kevee marked this conversation as resolved.
Show resolved Hide resolved
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.
gillkyle marked this conversation as resolved.
Show resolved Hide resolved

#### Additional resources
kevee marked this conversation as resolved.
Show resolved Hide resolved

- [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