Why does Gatsby use GraphQL? This is part 3 of a 4-part series that shows how to create pages in Gatsby, how data becomes hard to manage over time, and how GraphQL helps limit the complexity of data management.
In this video, you’ll create product pages from a JSON file and add images to the pages. This video starts to show the complexity of managing complex data.
Instructor: [00:00] In most real world use cases, data isn't going to be hard-coded. It's going to come from some external source. It could be something like a database or, in our case, it's going to be a JSON file.
[00:12] This is products.json. It contains three products that come from the Gatsby slug store that we'll use for the example here. What we want to do is read these pages and create them dynamically. By the time we're done, we want three product pages, one for the vintage purple tea, one for the socks, and one for the hat.
[00:32] To do this, we're going to create in our Gatsby node a createPages API function. We're going to start by creating exports.createPages so that Gatsby knows to create pages during build. We're going to destructure the arguments so we get the actions. We want the createPage helper function.
[00:55] Then we want to load our products by requiring the data, products.json. Next, we're going to do a product.forEach product. We want to run createPage for each product.
[01:17] The way that we're going to do this is we're going to create under a product top-level folder, and then we'll use the product.slug, which, if we look at the products, we have a slug along with the title, description, price, and image. We're going to use the slug as its actual address on the Internet.
[01:38] Then we need to give it a component, which is how we render the template. This is a React component. We haven't built this yet, but let's tell it where to look. We're going to use require.resolve, and this is going to live in the source. We'll create a folder called templates, and we'll create a file, a React component called product.js.
[01:56] Finally, we need to pass some context to that product. Context is how Gatsby is able to pass data into a given component. In our case, we're going to pass in the title, so we'll do product.title. We're also going to do the description. We will grab out the image, and finally, we'll get the price.
[02:25] Now we're ready to build, but we still need to create this product template, so let's go in and create a new file called template is the directory, and we'll create product.js. Inside of product.js, we're going to import react from React since this is a React component. We're going to define our template as product. We want to get the pageContext from Gatsby.
[02:53] The pageContext is going to contain everything that gets passed into context. In the case here, pageContext will have a title, description, image, and price property that we can get by accessing pageContext.title, etc.
[03:10] For our products, we're going to do div, we give it a title. That's going to use the title, so pageContext.title. We will show the image. The image that we want to show is going to have a source of pageContext.image. We'll give it an alt tag, because accessibility matters, pageContext.title.
[03:35] Then we'll give it a little bit of style just to make sure that it doesn't look terrible. We'll do flow left. We'll set a little bit of margin right. This just makes it a little more visible. Then we're going to make the width nice and small so that we can see everything during the demo. That will be our image.
[03:54] We're going to set the price. We want to show that, pageContext.price. Finally, we will show the description, which is going to be dangerously set in our HTML. That's going to HTML, use pageContext.description. We can see inside of products.json that the description, it's got some HTML in it.
[04:26] Upon saving this, we need to make sure that we export it, default-product. We're now ready to fire up and look at the results. Let's run Gatsby develop.
[04:43] We know that the products live at /products/whatever this is. We'll take the first slug. We open up localhost:8000 and we'll go to /products/vintage-purple-tea. That shows us our tea, but our image is broken.
[05:03] The reason this image is broken is that they're not currently visible to Gatsby. It's being looked for at images/EmilyRonaldRegans or AronFoxandSullivan, and that is not currently here. We don't have those images anywhere in our source.
[05:20] The way that Gatsby works, anything that we put inside the static folder becomes available at root. We're looking for an images folder at root. The way that we can prove it is if we look at favicon.ico, we can go here and we can look at favicon.ico, and we'll see the favicon is there. How do we get folders here?
[05:38] We're going to take our images and we're going to drop them right into this static folder. If I refresh here, we'll see now we got the images, and I can see Emily's dog, Reagan. I can see David's cat. I can see Erin's cat. If we reload, we see now that we can see the photo as expected.
[05:59] If we come back in here and we go to a different product, let's look at the space socks, we can change it up here, /products/space-socks, and there we go. We've got our image. We've got our description, all the things that we expected.
[06:14] The downside to this is that we have our images here in this data/products, and it's really difficult to tell where do these images come from. How did we set /images? There's no relationship between the static folder of images and this JSON file of data.
[06:35] This is one of the limitations of complex data as you start getting into more and more advanced use cases. In the next video, we'll start looking at how to use GraphQL to overcome some of this complexity.
@ian I think you may have caught this series mid-publish — part 4 is live now! The full series is here: https://egghead.io/playlists/why-gatsby-uses-graphql-1c319a1c
Hooray! Thanks, great series. 👍
I can't find part 4, does it exist?