TECHY360
Everything You Need To Know About Tech

Gatsby JS starter guide for beginners

0 167

1. Introducing Gatsby Building Blocks

Gatsby Process
Gatsby Process

In the previous section, you prepared the local development environment by installing the necessary software and creating your first Gatsby website using the “hello world” starter. Now dive deeper into the code generated by this starter.

Using Gatsby Starters

Gatsby Starter
Gatsby Starter
gatsby new hello-world https://github.com/gatsbyjs/gatsby-starter-hello-world

When creating a new site on Gatsby, you can use the following command structure to create a new site based on any existing Gatsby starter:

gatsby new [SITE_DIRECTORY_NAME] [URL_OF_STARTER_GITHUB_REPO]

If you omit the URL at the end, Gatsby will automatically create the site for you based on the default starter. For this section of the tutorial, stick to the site “Hello World”, which you have already created in the zero part of the tutorial. You can learn more about changing starters in the documentation.

Introducing Gatsby Pages

Gatsby Pages
Gatsby Pages

Open the directory /srcin the code editor. Inside is a single directory: /pages.

Open the file at src/pages/index.js. The code in this file creates a component that contains one div and some text – respectively, “Hello world!”

Gatsby uses a hot reload to speed up the development process. In fact, when the Gatsby development server is running, each time you save the file, the Gatsby site files are “viewed” in the background and your changes are immediately displayed in the browser. You do not need to manually refresh the page or restart the development server.

Gatsby data

gatsby process

In the next four parts of the tutorial (including this one), you will dive into the Gatsby data layer, which is a powerful Gatsby feature that makes it easy to create sites from Markdown, WordPress, headless CMSs and other data sources of all tastes.

Gatsby’s data layer runs on GraphQL. About GraphQL, you can read the article How to use GraphQL.

The website has four parts: HTML, CSS, JS, and data. Let’s find out how to use data on Gatsby sites.

What is data?

A very computerized answer would be: data is things like “strings”, integers (42), objects ({pizza: true}), etc.

For the purposes of working at Gatsby, however, a more useful answer is “everything that lives outside the React component”.

So far, you have written text and added images directly to components. Which is a great way to create many websites. But often you need to store data outside the components, and then enter them into the component as needed.

If you create a site using WordPress (so that other participants have a good interface for adding and maintaining content) and Gatsby, the data for the site (pages and posts) is in WordPress, and you extract this data into your components as necessary.

Data can also be located in file types such as Markdown, CSV, etc., as well as databases and APIs of all kinds.

Gatsby’s data layer allows you to extract data from these (and any other sources) directly into your components – in the form you need.

Using Unstructured Data or GraphQL

Gatsby Graphql
Gatsby Graphql

Is it mandatory to use GraphQL and source plugins to retrieve data on Gatsby sites?

Not necessary! You can use the API createPagesto extract unstructured data to Gatsby pages directly, and not through the GraphQL data layer. This is a great choice for small sites, while GraphQL and source plugins can help save time on more complex sites.

See the Using Gatsby without GraphQL tutorial for how to get data to your Gatsby site using the node API createPagesand see an example site!

When to use unstructured data, and when is GraphQL?

If you are creating a small site, one of the effective ways to create it is to extract unstructured data, as described in this guide, using the API createPages, and then if the site becomes more complex, you proceed to create more complex sites, or you want to convert your data follow these steps:

  1. Check the Plugin Library to find out if there are plugin sources and / or converted plugins that you want to use
  2. If not, read the plugin development guide and consider creating your own!

How Gatsby’s Data Layer Uses GraphQL to Extract Data into Components

There are many options for loading data into React components. One of the most popular and powerful of them is GraphQL technology.

GraphQL was invented on Facebook to help product engineers gather the necessary data into components.

GraphQL is a query language (QL-query language). If you are familiar with SQL, it works in a very similar way. Using special syntax, you describe the necessary data in the component, and then this data is transmitted to you.

Gatsby uses GraphQL to allow components to declare the data they need.

Creating a new example site

Create another new site for this part of the guide. You are about to create a Markdown blog called “Pandas Eat A Lot.” It is dedicated to showcasing the best photos and videos of pandas eating a lot of food. Along the way, you’ll immerse your toes in GraphQL and Gatsby’s Markdown support.

Open a new terminal window and run the following commands to create a new Gatsby website in a directory called tutorial-part-four. Then go to the new directory:

gatsby new tutorial-part-four https://github.com/gatsbyjs/gatsby-starter-hello-world

cd tutorial-part-four

Then install some other necessary dependencies in the root of the project. You will use the Typography theme “Kirkham” and you will try the CSS-in-JS library, “Emotion” :

npm install --save gatsby-plugin-typography typography react-typography typography-theme-kirkham gatsby-plugin-emotion @emotion/core

Create a site similar to what you finished in the third part. This site will have a layout component and two-page components:

src / components / layout.js

import React from "react"
import { css } from "@emotion/core"
import { Link } from "gatsby"

import { rhythm } from "../utils/typography"

export default ({ children }) => (
  <div
    css={css`
      margin: 0 auto;
      max-width: 700px;
      padding: ${rhythm(2)};
      padding-top: ${rhythm(1.5)};
    `}
  &gt;
    <Link to={`/`}&gt;
      <h3
        css={css`
          margin-bottom: ${rhythm(2)};
          display: inline-block;
          font-style: normal;
        `}
      &gt;
        Pandas Eating Lots
      </h3&gt;
    </Link&gt;
    <Link
      to={`/about/`}
      css={css`
        float: right;
      `}
    &gt;
      About
    </Link&gt;
    {children}
  </div&gt;
)

src / pages / index.js

import React from "react"
import Layout from "../components/layout"

export default () =&gt; (
  <Layout&gt;
    <h1&gt;Amazing Pandas Eating Things</h1&gt;
    <div&gt;
      <img
         data-src="https://2.bp.blogspot.com/-BMP2l6Hwvp4/TiAxeGx4CTI/AAAAAAAAD_M/XlC_mY3SoEw/s1600/panda-group-eating-bamboo.jpg"
        alt="Group of pandas eating bamboo"
      /&gt;
    </div&gt;
  </Layout&gt;
)

src / pages / about.js

import React from "react"
import Layout from "../components/layout"

export default () =&gt; (
  <Layout&gt;
    <h1&gt;About Pandas Eating Lots</h1&gt;
    <p&gt;
      We're the only site running on your computer dedicated to showing the best
      photos and videos of pandas eating lots of food.
    </p&gt;
  </Layout&gt;
)

src / utils / typography.js

import Typography from "typography"
import kirkhamTheme from "typography-theme-kirkham"

const typography = new Typography(kirkhamTheme)

export default typography
export const rhythm = typography.rhythm

gatsby-config.js

module.exports = {
  plugins: [
    `gatsby-plugin-emotion`,
    {
      resolve: `gatsby-plugin-typography`,
      options: {
        pathToConfigModule: `src/utils/typography`,
      },
    },
  ],
}

Add the above files, and then run the command gatsby develop.

Your first GraphQL query

Graphql Query
Graphql Query

When creating sites, you probably want to reuse common parts of the data – for example, the name of the site. Look at the page /about/. You will notice that you have a site name (Pandas eat a lot) both in the layout component (site title) and in the <h1 />page-tag about.js(page title).

But what if you want to change the name of the site? You will have to search for a title in all of your components and edit each instance. This is both cumbersome and error-prone, especially for larger and more complex sites. Instead, you can store the header in one place and link to it from other files; change the title in one place and Gatsby will extract your updated title into files that link to it.

The place for these shared pieces of data is the object siteMetadatain the file gatsby-config.js. Add the name of your site to the file gatsby-config.js:

gatsby-config.js

module.exports = {
  siteMetadata: {
    title: `Title from siteMetadata`,
  },
  plugins: [
    `gatsby-plugin-emotion`,
    {
      resolve: `gatsby-plugin-typography`,
      options: {
        pathToConfigModule: `src/utils/typography`,
      },
    },
  ],
}

Reboot the development server.

Using Page Request

Now the site name is available for request. Add it to the file about.jsusing the page request :

src / pages / about.js

import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"

export default ({ data }) =&gt; (
  <Layout&gt;
    <h1&gt;About {data.site.siteMetadata.title}</h1&gt;
    <p&gt;
      We're the only site running on your computer dedicated to showing the best
      photos and videos of pandas eating lots of food.
    </p&gt;
  </Layout&gt;
)

export const query = graphql`
  query {
    site {
      siteMetadata {
        title
      }
    }
  }
`

Save the file

Using StaticQuery

StaticQuery is a new API added in Gatsby v2 that allows non-page components (like the layout.js component) to retrieve data using GraphQL queries. Let’s use this newly introduced version of the hook – useStaticQuery.

Make some changes to the src / components / layout.js file to use the hook useStaticQueryand the {data.site.siteMetadata.title} link that uses this data. When you are done, your file will look like this:

src / components / layout.js

import React from "react"
import { css } from "@emotion/core"
import { useStaticQuery, Link, graphql } from "gatsby"

import { rhythm } from "../utils/typography"
export default ({ children }) =&gt; {
  const data = useStaticQuery(
    graphql`
      query {
        site {
          siteMetadata {
            title
          }
        }
      }
    `
  )
  return (
    <div
      css={css`
        margin: 0 auto;
        max-width: 700px;
        padding: ${rhythm(2)};
        padding-top: ${rhythm(1.5)};
      `}
    &gt;
      <Link to={`/`}&gt;
        <h3
          css={css`
            margin-bottom: ${rhythm(2)};
            display: inline-block;
            font-style: normal;
          `}
        &gt;
          {data.site.siteMetadata.title}
        </h3&gt;
      </Link&gt;
      <Link
        to={`/about/`}
        css={css`
          float: right;
        `}
      &gt;
        О сайте
      </Link&gt;
      {children}
    </div&gt;
  )
}

Why use two different queries here? These examples were a brief introduction to query types, how they are formatted, and where they can be used. In the meantime, keep in mind that only pages can make page requests. Non-page components such as Layout can use StaticQuery. Part 7 of the textbook explains them in more detail.

One of the main principles of Gatsby is that the creators need a direct connection with what they create ( hat tip to Bret Victor ). In other words, when you make any changes to the code, you should immediately see the effect of this change. You manipulate Gatsby input and see the new output on the screen.

Source Plugins

This tutorial will show you how to use GraphQL and source plugins to upload data to Gatsby website. However, before you learn about these plugins, you should know how to use the GraphiQL tool to help you structure your queries correctly.

Introduction to GraphiQL

GraphiQL is GraphQL’s integrated development environment (IDE). This is a powerful tool that you’ll often use when building Gatsby websites.

You can access it when your site’s development server is running – usually at http: // localhost: 8000/graphql .

Browse the built-in site “type” and see which fields are available on it — including the siteMetadata object that you requested earlier. Try to open GraphiQL and play with your data! Press Ctrl + Space (or use Shift + Space as an alternative keyboard shortcut) to open the autocomplete window, and Ctrl + Enter to start the GraphQL query. In the remainder of the lesson, you will use GraphiQL much more.

USING THE GRAPHIQL BROWSER

GraphiQL Browser allows you to interactively create complete queries by clicking on the available fields and input data without repeating the process of manually entering these queries.

Data to Gatsby sites can come from anywhere: APIs, databases, CMS, local files, etc.

Source plugins retrieve data from their source. For example, the source filesystem plugin knows how to extract data from a file system. The WordPress plugin knows how to get data from the WordPress API.

Add gatsby-source-filesystemand learn how it works.

First, install the plugin in the root of the project:

npm install --save gatsby-source-filesystem

Then add it to the file gatsby-config.js:

gatsby-config.js

module.exports = {
  siteMetadata: {
    title: `Pandas Eating Lots`,
  },
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `src`,
        path: `${__dirname}/src/`,
      },
    },
    `gatsby-plugin-emotion`,
    {
      resolve: `gatsby-plugin-typography`,
      options: {
        pathToConfigModule: `src/utils/typography`,
      },
    },
  ],
}

Save this and reboot the gatsby development server. Then open GraphiQL again.

In the explorer area, you will see allFileand file, available as selected.

Related Posts
1 of 26

Click the allFile drop-down list. Place the cursor after all files in the request area, and then type Ctrl + Enter. This will allow you to pre-fill the request for the identifier of each file. Click the “Play” button to complete the request.

In the explorer panel, the id field was selected automatically. Make a selection for more fields by checking the corresponding field checkbox. Click the “Play” button to run the query again with the new fields.

In addition, you can add fields using the autocomplete keyboard shortcut (Ctrl + spacebar).

Try adding several fields to the query, press Ctrl + Enter each time to re-execute the query. You will see the updated query results:

Creating a Page Using GraphQL Queries

Creating new pages with Gatsby often starts in GraphiQL. First, you sketch out a data query while playing in GraphiQL, and then copy it to the React component page to begin building the user interface.

Create a new file src/pages/my-files.jswith the GraphQL query allFilethat you just created:

src / pages / my-files.js

import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"

export default ({ data }) =&gt; {
  console.log(data)
  return (
    <Layout&gt;
      <div&gt;Hello world</div&gt;
    </Layout&gt;
  )
}

export const query = graphql`
  query {
    allFile {
      edges {
        node {
          relativePath
          prettySize
          extension
          birthTime(fromNow: true)
        }
      }
    }
  }
`

The line is console.log(data)often useful when creating a new component to display the data that you get from the GraphQL query so that you can examine the data in the browser console while building the user interface.

If you go to a new page in /my-files/and open the browser console, you will see something like:

The data form is the same as the GraphQL query form.

Add some code to the component to print the file data.

src / pages / my-files.js

import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"

export default ({ data }) =&gt; {
  console.log(data)
  return (
    <Layout&gt;
      <div&gt;
        <h1&gt;My Site's Files</h1&gt;
        <table&gt;
          <thead&gt;
            <tr&gt;
              <th&gt;relativePath</th&gt;
              <th&gt;prettySize</th&gt;
              <th&gt;extension</th&gt;
              <th&gt;birthTime</th&gt;
            </tr&gt;
          </thead&gt;
          <tbody&gt;
            {data.allFile.edges.map(({ node }, index) =&gt; (
              <tr key={index}&gt;
                <td&gt;{node.relativePath}</td&gt;
                <td&gt;{node.prettySize}</td&gt;
                <td&gt;{node.extension}</td&gt;
                <td&gt;{node.birthTime}</td&gt;
              </tr&gt;
            ))}
          </tbody&gt;
        </table&gt;
      </div&gt;
    </Layout&gt;
  )
}

export const query = graphql`
  query {
    allFile {
      edges {
        node {
          relativePath
          prettySize
          extension
          birthTime(fromNow: true)
        }
      }
    }
  }
`

Now visit http://localhost:8000/my-files

Now you’ve learned how to source plugins bring data to the Gatsby data system. In the next lesson, you will learn how transformer plugins transform the raw content that source plugins bring. The combination of source plugins and transformer plugins can handle all the data sources and data transformations that you might need when creating a Gatsby website. Learn about transformer plugins in the sixth part of this guide.

Transformer Plugins

The previous lesson showed how to source plugins deliver data to the Gatsby data system. In this tutorial, you will learn how transformer plugins transform the original content obtained with source plugins. The combination of source plugins and transformer plugins can process all data sources and convert the data that may be required when creating a site on Gatsby.

Often the data format that you get from source plugins is not what you want to use to create your website. The source filesystem plugin allows you to request data about files, but what if you want to request data inside files?

To make this possible, Gatsby supports transformer plugins that take raw content from source plugins and transform it into something more useful.

Take markdown files, for example. It is convenient to write articles in markdown, but when you create a page with it, you need markdown to be converted to HTML.

Add the markdown file to your website at src/pages / sweet-pandas-eating-sweets.md (this will be your first markdown blog post) and learn how to convert it to HTML using the transformer and GraphQL plugins.

src / pages / sweet-pandas-eating-sweets.md

---
title: "Sweet Pandas Eating Sweets"
date: "2017-08-10"
---

Pandas are really sweet.

Here's a video of a panda eating sweets.

<iframe width="560" height="315"  data-src="https://www.youtube.com/embed/4n0xNbfJLR8" frameborder="0" allowfullscreen&gt;</iframe&gt;

Once you save the file, look /my-files/again – the new markdown file is in the table. This is a very powerful feature of Gatsby. As in the previous example siteMetadata, source plugins can perform a quick reload of data. gatsby-source-filesystemalways looking for new files to be added, and when they appear, it re-executes your requests.

Add a transformer plugin that can convert markdown files:

npm install --save gatsby-transformer-remark

Then add it to gatsby-config.js:

gatsby-config.js

module.exports = {
  siteMetadata: {
    title: `Pandas Eating Lots`,
  },
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `src`,
        path: `${__dirname}/src/`,
      },
    },
    `gatsby-transformer-remark`,
    `gatsby-plugin-emotion`,
    {
      resolve: `gatsby-plugin-typography`,
      options: {
        pathToConfigModule: `src/utils/typography`,
      },
    },
  ],
}

Reboot the development server, then refresh (or open again) GraphiQL and look at the autocomplete.

Again select allMarkdownRemarkand run it the same way as for allFile. You will see there a markdown file that you recently added. Explore the fields available on the site MarkdownRemark.

Creating a list of markdown files for your site in src/pages / index.js

Now you will need to create a list of your markdown files on the first page. As with many blogs, you want the final link list on the first page to point to each blog post. With GraphQL, you can query the current list of blog posts by markdown so you don’t need to maintain the list manually.

Like a page src/pages/my-files.js, replace src/pages/index.jswith the following to add a GraphQL query with some initial HTML and style.

src / pages / index.js

import React from "react"
import { graphql } from "gatsby"
import { css } from "@emotion/core"
import { rhythm } from "../utils/typography"
import Layout from "../components/layout"

export default ({ data }) =&gt; {
  console.log(data)
  return (
    <Layout&gt;
      <div&gt;
        <h1
          css={css`
            display: inline-block;
            border-bottom: 1px solid;
          `}
        &gt;
          Amazing Pandas Eating Things
        </h1&gt;
        <h4&gt;{data.allMarkdownRemark.totalCount} Posts</h4&gt;
        {data.allMarkdownRemark.edges.map(({ node }) =&gt; (
          <div key={node.id}&gt;
            <h3
              css={css`
                margin-bottom: ${rhythm(1 / 4)};
              `}
            &gt;
              {node.frontmatter.title}{" "}
              <span
                css={css`
                  color: #bbb;
                `}
              &gt;
                — {node.frontmatter.date}
              </span&gt;
            </h3&gt;
            <p&gt;{node.excerpt}</p&gt;
          </div&gt;
        ))}
      </div&gt;
    </Layout&gt;
  )
}

export const query = graphql`
  query {
    allMarkdownRemark {
      totalCount
      edges {
        node {
          id
          frontmatter {
            title
            date(formatString: "DD MMMM, YYYY")
          }
          excerpt
        }
      }
    }
  }
`

But your only blog post looks a little lonely. So let’s add another one to src/pages/pandas-and-bananas.md.

src / pages / pandas-and-bananas.md

---
title: "Pandas and Bananas"
date: "2017-08-21"
---

Do Pandas eat bananas? Check out this short video that shows that yes! pandas do
seem to really enjoy bananas!

<iframe width="560" height="315" src="https://www.youtube.com/embed/4SZl1r2O_bY" frameborder="0" allowfullscreen&gt;</iframe&gt;

It looks great! That’s just … the order of the posts is wrong.

But this is easy to fix. When requesting a connection of a certain type, you can pass many arguments to a GraphQL query. You can sort and filter the nodes, set the number of nodes to skip, and choose a limit on the number of nodes to be retrieved. With this powerful set of operators you can select any data you want – in the format you need.

In the GraphQL query, change the index page allMarkdownRemarkto allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }). Note: there are 3 underscores between frontmatter and date. Save this and the sort order should be set.

Try opening GraphiQL and playing around with different sorting options. You can sort a compound allFilealong with other compounds.

For more documentation on our query operators, explore our GraphQL reference.

It’s great! You have just created a beautiful index page where you request your markdown files and create a list of headings and excerpts from blog entries. But you do not want to just see excerpts, you need real pages for your markdown files.

You can continue to create pages by placing React components in src/pages. However, later you will learn how to programmatically create pages from data. Gatsby is not limited to creating pages from files, like many static site generators. Gatsby allows you to use GraphQL to query data and display query results on pages – all at build time. This is a really powerful idea. You will learn its effects and uses in the next tutorial, where you will learn how to programmatically create pages from data.

Programmatically creating pages from data

In the previous guide, you created a beautiful index page that requests markdown files and creates a list of headings and excerpts from blog entries. But you need not just excerpts, but real pages for your markdown files.

You can continue to create pages by placing React components in src/pages. However, now you will learn how to programmatically create pages from data. Gatsby is not limited to creating pages from files, like many static site generators. Gatsby allows you to use GraphQL to query data and display query results on pages – all at build time.

Create page slugs

To create a new page, you need to perform two steps:

  1. Create a “path” or “slug” for the page.
  2. Create page.

slug is a human-readable fragment of text from a URL, unlike, for example, an ID, which can be an incomprehensible character set.

Note: often data sources directly provide a slug or a path for content – when working with one of these systems (for example, CMS), you do not need to create slugs yourself, as you do with markdown files.

To create markdown pages, you will learn how to use two Gatsby APIs: onCreateNodeand createPages. These are two API workhorses that you will see on many sites and plugins.

We do our best to make the Gatsby API easy to implement. To implement the API, you must export a function named API from gatsby-node.js.

In the root of your site, create a file with the name gatsby-node.js. Then add the following to it.

exports.onCreateNode = ({ node }) =&gt; {
  console.log(node.internal.type)
}

This function onCreateNodewill be called by Gatsby whenever a new node is created (or updated).

Stop and restart the development server. Once you do this, you will see that quite a few newly created nodes will go into the terminal console.

In the next section, you will use this API to add slacks for your Markdown site pages MarkdownRemark.

gatsby-node.js

exports.onCreateNode = ({ node }) =&gt; {
  if (node.internal.type === `MarkdownRemark`) {
    console.log(node.internal.type)
  }
}

You want to use each markdown file name to create the page slug. So it pandas-and-bananas.mdwill be /pandas-and-bananas/. But how to get the file name from the node MarkdownRemark? To get it, you need to cross the “nodal graph” to its parent node File, since the nodes Filecontain the data you need about the files on disk. To do this, change your function again:

gatsby-node.js

exports.onCreateNode = ({ node, getNode }) =&gt; {
  if (node.internal.type === `MarkdownRemark`) {
    const fileNode = getNode(node.parent)
    console.log(`\n`, fileNode.relativePath)
  }
}

After rebooting the development server, you should see the relative paths for the two markdown files printed on the terminal screen.

 pages/sweet-pandas-eating-sweets.md

 pages/pandas-and-bananas.md

Now you have to create slacks. Since the logic for creating slugs from file names can be complex, the plugin gatsby-source-filesystemcomes with a function for creating slugs. Let’s take advantage of this.

gatsby-node.js

const { createFilePath } = require(`gatsby-source-filesystem`)

exports.onCreateNode = ({ node, getNode }) =&gt; {
  if (node.internal.type === `MarkdownRemark`) {
    console.log(createFilePath({ node, getNode, basePath: `pages` }))
  }
}

The function handles the search for the parent node Filealong with the creation of the slug. Run the development server again and you will see that the terminal has two slugs, one for each markdown file.

Now you can add new slugs directly to nodes MarkdownRemark. This is very important since any data that you add to nodes is available for a subsequent queries using GraphQL. So when it comes time to create pages, it will be easy to get a slug.

To do this, you will use the function passed to your API implementation called createNodeField. This function allows you to create additional fields in nodes created by other plugins. Only the original creator of the node can directly modify the node – all other plugins (including yours gatsby-node.js) should use this function to create additional fields.

gatsby-node.js

const { createFilePath } = require(`gatsby-source-filesystem`)
exports.onCreateNode = ({ node, getNode, actions }) =&gt; {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const slug = createFilePath({ node, getNode, basePath: `pages` })
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
  }
}

Reboot the development server and open or update GraphiQL. Then run this GraphQL query to see your new slugs.

{
  allMarkdownRemark {
    edges {
      node {
        fields {
          slug
        }
      }
    }
  }
}

Now that the slags are created, you can create pages.

Page creation

In the same file gatsby-node.js, add the following.

const { createFilePath } = require(`gatsby-source-filesystem`)

exports.onCreateNode = ({ node, getNode, actions }) =&gt; {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const slug = createFilePath({ node, getNode, basePath: `pages` })
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
  }
}

exports.createPages = async ({ graphql, actions }) =&gt; {
  // **Note:** The graphql function call returns a Promise
  // see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise for more info
  const result = await graphql(`
    query {
      allMarkdownRemark {
        edges {
          node {
            fields {
              slug
            }
          }
        }
      }
    }
  `)
  console.log(JSON.stringify(result, null, 4))
}

You have added an API implementation createPagesthat calls Gatsby so plugins can add pages.

As mentioned in the introduction to this part of the manual, the steps for programmatically creating pages are:

  1. Querying data with GraphQL
  2. Display query results on pages

The above code is the first step to create pages from your markdown, as you use the provided function graphqlto request the markdown slugs you created. Then you print the result of the query, which should look like this:

To create pages, you will need one more thing besides the slug: the page template component. Like everything in Gatsby, program pages are powered by React components. When creating a page, you must specify which component to use.

Create a directory in src/templates, and then add the following to a file named src/templates/blog-post.js.

import React from "react"
import Layout from "../components/layout"

export default () =&gt; {
  return (
    <Layout&gt;
      <div&gt;Hello blog post</div&gt;
    </Layout&gt;
  )
}

Then modify gatsby-node.js

const path = require(`path`)
const { createFilePath } = require(`gatsby-source-filesystem`)

exports.onCreateNode = ({ node, getNode, actions }) =&gt; {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const slug = createFilePath({ node, getNode, basePath: `pages` })
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
  }
}

exports.createPages = async ({ graphql, actions }) =&gt; {
  const { createPage } = actions
  const result = await graphql(`
    query {
      allMarkdownRemark {
        edges {
          node {
            fields {
              slug
            }
          }
        }
      }
    }
  `)

  result.data.allMarkdownRemark.edges.forEach(({ node }) =&gt; {
    createPage({
      path: node.fields.slug,
      component: path.resolve(`./src/templates/blog-post.js`),
      context: {
        // Data passed to context is available
        // in page queries as GraphQL variables.
        slug: node.fields.slug,
      },
    })
  })
}

Restart the development server and your pages will be created! An easy way to find new pages that you create during development is to go to a random path where Gatsby will happily show you a list of pages on the site. If you go to http://localhost: 8000/sdf , you will see the new pages that you created.

This is a little boring and not what you want. Now you can get data from your markdown post. Change src/templates/blog-post.jsas follows:

import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"

export default ({ data }) =&gt; {
  const post = data.markdownRemark
  return (
    <Layout&gt;
      <div&gt;
        <h1&gt;{post.frontmatter.title}</h1&gt;
        <div dangerouslySetInnerHTML={{ __html: post.html }} /&gt;
      </div&gt;
    </Layout&gt;
  )
}

export const query = graphql`
  query($slug: String!) {
    markdownRemark(fields: { slug: { eq: $slug } }) {
      html
      frontmatter {
        title
      }
    }
  }
`

The final step is to link to your new pages from the index page.

Go back to src/pages/index.jsrequest your markdown slacks and create links.

import React from "react"
import { css } from "@emotion/core"
import { Link, graphql } from "gatsby"
import { rhythm } from "../utils/typography"
import Layout from "../components/layout"

export default ({ data }) =&gt; {
  return (
    <Layout&gt;
      <div&gt;
        <h1
          css={css`
            display: inline-block;
            border-bottom: 1px solid;
          `}
        &gt;
          Amazing Pandas Eating Things
        </h1&gt;
        <h4&gt;{data.allMarkdownRemark.totalCount} Posts</h4&gt;
        {data.allMarkdownRemark.edges.map(({ node }) =&gt; (
          <div key={node.id}&gt;
            <Link
              to={node.fields.slug}
              css={css`
                text-decoration: none;
                color: inherit;
              `}
            &gt;
              <h3
                css={css`
                  margin-bottom: ${rhythm(1 / 4)};
                `}
              &gt;
                {node.frontmatter.title}{" "}
                <span
                  css={css`
                    color: #555;
                  `}
                &gt;
                  — {node.frontmatter.date}
                </span&gt;
              </h3&gt;
              <p&gt;{node.excerpt}</p&gt;
            </Link&gt;
          </div&gt;
        ))}
      </div&gt;
    </Layout&gt;
  )
}

export const query = graphql`
  query {
    allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
      totalCount
      edges {
        node {
          id
          frontmatter {
            title
            date(formatString: "DD MMMM, YYYY")
          }
          fields {
            slug
          }
          excerpt
        }
      }
    }
  }
`

In this part of the tutorial, you learned the basics of a building using the Gatsby data layer. You learned how to create and transform data using plugins, how to use GraphQL to display data on pages, and then how to create page template components that request data for each page.

Comments
Loading...

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More