A JOURNEY FROM DRONGO TO DEV

> BACK TO ALL POSTS

GatsbyJS - Static Website Generator: Part5 - Bringing in our Blogposts

day

27 October 2018


Last Edited: 31 October 2018

TIME TO BRING IN THE POSTS!..👍

In order to have access to our Contentful content, we first need to set a few things up in our app.

Gatsby can use "plugins" in order to carry out various functions and services prior to the pages being build.

The plugin that we will be using is called gatsby-source-contentful which is installed using the normal npm method:

npm i gatsby-source-contentful

Part 5 - 1

Once the install is complete, we need to tell Gatsby to use this plugin.

Head over to the gatsby-config.js file and create a new entry in the plugins array, by creating an object with the following keys/values:

{
  resolve: "gatsby-source-contentful",
  options: {
    spaceId: "k63p3vhzl1vu",
    accessToken:
      "1e2b79193c4531379a508a1a54bdbfb2ef00d24ca3f713d1d392dd401c9add86",
  },
    },

Where the spaceId and accessToken are the ones specific to your Contentful space.

Part 5 - 2

That's it! That is all we have to do to wire up our contentful data, super simple! 🤓

The method in which Gatsby accesses your Contentful contentful models is via a query language called GraphQL, I'm not going to go much further into this as it comes pre-configured on our Gatsby server and is ready to use.

I recommend Scott Tolinski's Level Up TUTs for further learning on GraphQL: LevelUpTuts

Gatsby provides a GraphQL 'Playground" for us in order to test out our queries. This is made available at: http://localhost:8000/___graphql

Launch

gatsby develop

And head over to the GraphQL Playground.

Part 5 - 3

GraphQL used a notation similar to JavaScript Objects where selectors are nested within Parentheses {}.

Start off your query with a set of open and closed bracket and place your cursor in-between them.

Now press ctrl + space to see the list of available selectors, choose allContentfulBlogPost and place another set of parentheses after it to drill further into the query.

Repeat these steps for, edges > node with node being the last step before we hit the return types.

The node is essentially a single post which is held in an array of posts, the edges.

So, from the node we would like to return the, title, slug, and the body; which is nested inside a further body selector.

Notice these return types are exactly that specified by our Contentful content type..so it must be working right!? 🙏

Part 5 - 4

Part 5 - 5

Press the Play button to run our query. Aaaaand BOOM!💥 All going well you should see all of our Contenful posts displayed in the right hand pane.

Ugly but it works! 👍

Part 5 - 6

Remove the body selectors from our query and re-run it, this time we only get the title and slugs from our posts.

This is what is so great about GraphQL, if you don't need the whole data structure then you don't have to request the whole data structure..just the parts you need 🆒.

Another great thing about this playground is that in order to use your querys here inside your application, all you need to do is copy/paste them in.

We will do that next!

Part 5 - 7

Ok..maybe it's not quite that simple, but hang tight and we will get there!

Firstly, lets create a page to house all of our posts.

In the pages folder create a new posts.js file and copy and paste the following code:

import React from 'react'
import { StaticQuery, graphql } from 'gatsby'
import Layout from '../components/layout'

const Posts = ({ children }) => (
  <StaticQuery
    query={graphql`
      query getPostData {
        allContentfulBlogPost{
          edges{
            node{
              title
              slug
            }
          }
        }
      }
  `}

render={data => (
            
  <Layout>
    Posts!
    {console.log(data)}
   </Layout>
)}
/>
)

export default Posts

Part 5 - 8

Open up your browsers developer tools and check out the console log. You will see that the response from out query is now available as a data prop within our page.

Part 5 - 9

What is going on in the above code? Well it's not easy to explain but we are using a special Gatsby react component:

<StaticQuery />

And passing it our GraphQL query.

When the StaticQuery component is rendered is passes the results to the children components..which in this case is our Posts page, meaning our query results are exposed to our page via its props.

This is a React pattern known as render props, which you can find loads of tutorials about elsewhere if you are interested. (See LevelupTuts above).

The query itself is done using the graphql function imported at the top and used within the StaticQuery component.

You will notice that the function doesn't take arguments like a conventional function, via function(arguments), instead it uses a template string tagged at the end of the function, which is passed using the back-ticks.

This allows the function to accept a large string and interpolated variables, using ${variableName} as a single argument.

But I digress, that's outside the scope of this tutorial.

So let's get this bad boy rendered onto our page!

In order to do this we will loop over our array of posts and return a new div containing the title of each post.

Inside our Layout component, enter the following:

<Layout>
            Posts!
            { data.allContentfulBlogPost.edges.map(({node: post}) => {
            
                return(
                    <div>
                        <h3>{post.title}</h3>
                    </div>
                )
            })}
</Layout>
  

Here we use the JavaScript map function to loop over the items in the data array, and extract the post.

We can then use the post.title inside our JSX to render it dynamically within a heading tag.

Part 5 - 10

Sweet!

Part 5 - 11

Awesome! Now let's include the body into our query and render it below the title.

Part 5 - 12

Part 5 - 13

Easy!!

Only thing is...it looks kind of...crappy!, the text is just a big block, no formatting and no HTML elements.

Gatsby sends us a blob of text rather than a blob of HTML, so what do we do? We can't have this on our super awesome blog, eh?!

Thankfully another plugin comes to the rescue..this time gatsby-transformer-remark. This is a Markup file parser which will transform our markup text into the intended HTML. It also adds some other sweet features.

Let's get it installed and added to the gatsby-config (notice this time no options are required so we just pass the plugin as a String to the array, rather than an object).

Part 5 - 14

Part 5 - 15

Turn back to our GraphQL playground and query the posts again, and again drill down until we reach the body selector.

You will see that this time around we are given a new selector, childMarkdownRemark, and inside this we find the HTML selector.

These new selectors were added by gatsby-transformer-remark..just like magic! ✨✨

This is what we will now target inside of our query in our posts.js

Part 5 - 16

Add a paragraph tag below our title and set the paragraph attribute to:

<p dangerouslySetInnerHTML={{__html: post.body.childMarkdownRemark.html}}></p>

Weird thing to do I agree, but that's just how React renders text as HTML. We need to provide the function dangerouslySetInnerHTML with an object containing a key of __html and a value of the text we want to render.

Part 5 - 17

BINGO! We are so smart!

Part 5 - 18

But something is still a bit off!, if this is a collection of all of our posts then surely we don't want to display the full blog post on this page! That would be CRAZY!!!!!!

What we want to do is provide a taste of what the post contains, then the user can select it and be brought to a page containing that single post.

What we require is an excerpt.

Go to our posts.js and modify the query, remove HTML and instead put excerpt(pruneLength: 250).

This will trim the HTML to 250 characters. (You can set 250 to anything you like).

It will also add ... at the end of the trimmed section. Neat!

Part 5 - 19

Part 5 - 20

Ok, cool! we now have our all of our posts showing on the posts.js page, we now need a way to click on the excerpt in order to be sent to a unique post page.

This is where the Contentful generated slug comes in to play. We have access to this slug via our query so we can simply create a link and use the slug as the URL, first we need to import the Link component from Gatsby:

import { Link } from 'gatsby'

Then add a Link component to the bottom of each Post excerpt with the href set to:

`/posts/${post.slug}` 

(notice the back-ticks rather than single or double quotes. Back ticks allow you to include a variable into the string by using the ${} notation.

Part 5 - 21

Part 5 - 22

Return to the browser and inspect the new hyperlinks at the bottom of the posts.

Click on one and we can see that we are brought to a 'not found' page, but look at the address bar! You can see that the URL points to /post/slug where the slug is the post title.

Isn't that clever?

Part 5 - 23

Obviously we haven't yet created these pages, in-fact we will be getting Gatsby to do that for us..after all what's the use in using a static site generator if we are writing everything ourselves.

Part 5 - 24

🚀🌛