Skip to content

Commit e478106

Browse files
megfhForestry.io
authored and
Forestry.io
committed
Update from Forestry.io
Meghan Hannon created src/content/posts/what-i-learned-from-100-days-of-gatsby.md
1 parent 064076d commit e478106

File tree

2 files changed

+209
-0
lines changed

2 files changed

+209
-0
lines changed

.forestry/front_matter/templates/blog-post.yml

+1
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ fields:
2323
label: tags
2424
pages:
2525
- src/content/posts/welcome.md
26+
- src/content/posts/what-i-learned-from-100-days-of-gatsby.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
---
2+
date: 2021-08-05T02:45:01Z
3+
tags:
4+
- gatsby
5+
- " react "
6+
title: What I Learned from 100 Days of Gatsby
7+
8+
---
9+
Earlier this year I worked my way through the #100DaysOfGatsby challenges. This year's project has been divided into sprints, with each sprint having a new set of features to implement. While I didn't keep up with the schedule exactly (and this blog post is very belated!), I really enjoyed having the project broken down into manageable chunks like this.
10+
11+
I had played with Gatsby a bit previously, but this project really helped me to dive deeper and get comfortable with the Gatsby framework and the wonderful world of Gatsby plugins! In this post I will highlight some of the hiccups I encountered and things I learned along the way.
12+
13+
## [Challenge 1](https://www.gatsbyjs.com/blog/100days-challenge-1)
14+
15+
The first challenge involved a few things to get a Proof of Concept site up and running:
16+
17+
* Use Gatsby’s Contentful plugin and connect to a test Contentful site
18+
* Create the following pages:
19+
* home
20+
* about
21+
* a collection of pages for every city
22+
* Build it on Gatsby Cloud and use their preview URL
23+
24+
The `npm init gatsby` command makes setting up a new site easy, and prompts to choose your preferred CMS, styling tools and additional features. Per the challenge instructions, I selected Contentful as the CMS and configured a few additional plugins (“responsive images”, “sitemap”, and “metatags”).
25+
26+
Since creating a page in Gatsby is as easy as exporting a React component from a page located in the src/pages directory, I created the `src/pages/about.js` to create a route at /about. The "home" page is `src/pages/index.js` which is automatically created by the `npm init gatsby` command. To create the pages for each city, I had to learn something new!
27+
28+
This was my first time using Gatsby's [File System Route API](https://www.gatsbyjs.com/docs/reference/routing/file-system-route-api/), which allows you to programmatically create pages from your GraphQL data, without touching the `gatsby-node.js` file at all.
29+
30+
For this case, I wanted to create pages for each city that audioC0RE operates in, nested under the `/location/` route.
31+
First, the cities were created as a content type in [Contentful](https://www.contentful.com/):
32+
![contentful dashboard showing the city content type](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cpbj4c4xee8wjv2r0q1b.png)
33+
Since the `gatsby-source-contentful` plugin was already configured, after creating the content model, I could now see the contentfulCity type in the GraphiQL explorer:
34+
![contentfulCity type highlighted in the GraphiQL explorer sidebar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7rfyfl302qyrk6id77yf.png)
35+
36+
So, to create the city pages, I created a new file, `src/pages/location/{contentfulCity.name}.js`. At build time, Gatsby uses the content within the curly braces to generate GraphQL queries to retrieve the nodes that should be built for this collection (allContentfulCity), and create a page for each of them. In this case, the following query is generated:
37+
38+
```graphql
39+
allContentfulCity {
40+
nodes {
41+
id
42+
name
43+
}
44+
}
45+
```
46+
47+
Inside the `src/pages/location/{contentfulCity.name}.js` component itself, I used the following query to get all the data needed for each page that is being created:
48+
49+
```graphql
50+
query ($id: String = "") {
51+
contentfulCity(id: {eq: $id}) {
52+
name
53+
description
54+
coordinates {
55+
lat
56+
lon
57+
}
58+
skylineImage {
59+
title
60+
gatsbyImageData
61+
}
62+
}
63+
}
64+
```
65+
66+
And voila! 3 pages have been created for the 3 cities that are stored in Contentful:
67+
68+
* /location/toronto/
69+
* /location/new-york/
70+
* /location/san-fransisco/
71+
72+
***
73+
74+
## [Challenge 2](https://www.gatsbyjs.com/blog/challenge-2/)
75+
76+
Challenge 2 involved actually getting the website up and running, styling with ChakraUI, adding a contact form with Formium, and adding a skyline image for each city page.
77+
78+
Having never used ChakraUI before (and admittedly rusty on my frontend skills), I had to search for some inspiration. I found this fantastic [blog post](https://raptis.wtf/blog/build-a-landing-page-with-chakra-ui-part-1/) from Jim Raptis, and used it to help me build the home page and header, with a few adjustments.
79+
80+
![audioC0RE landing page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zkanhim0n33shp51aw6u.png)
81+
82+
I wanted to have the header contain links to all cities, but was encountering an error:
83+
84+
```console
85+
Exported queries are only executed for Page components. It's possible you're
86+
trying to create pages in your gatsby-node.js and that's failing for some
87+
reason.
88+
89+
If the failing component(s) is a regular component and not intended to be a page
90+
component, you generally want to use a <StaticQuery> (https://gatsbyjs.org/docs/static-query)
91+
instead of exporting a page query.
92+
```
93+
94+
This led me to discover Gatsby's [<StaticQuery>](https://www.gatsbyjs.com/docs/how-to/querying-data/static-query/)! From the Gatsby docs:
95+
96+
> By using StaticQuery, you can colocate a component with its data. It is no longer required to, say, pass data down from Layout to Header.
97+
98+
That's exactly what I needed it for! So I used the `<StaticQuery>` to populate my header with the links to the cities:
99+
100+
```react
101+
<StaticQuery
102+
query={graphql`
103+
query AllCities {
104+
allContentfulCity {
105+
edges {
106+
node {
107+
name
108+
gatsbyPath(filePath: "/location/{contentfulCity.name}")
109+
}
110+
}
111+
}
112+
}
113+
`
114+
}
115+
render={data => <HeaderComponent data={data} />}
116+
/>
117+
```
118+
119+
**A Hiccup**: When building the dropdown menu for the cities, I was trying to use `ChevronDownIcon` in my <HeaderComponent>, but I was importing it from `@chakra-ui/react` instead of `@chakra-ui/icons`, and the error message was a bit confusing:
120+
121+
```console
122+
Uncaught Error: Undefined component passed to createElement()
123+
124+
You likely forgot to export your component or might have mixed up default and named imports
125+
```
126+
127+
_Lesson_: always double check your imports!
128+
129+
***
130+
131+
## [Challenge 3](https://www.gatsbyjs.com/blog/100days-challenge-3/)
132+
133+
Challenge 3 involved using Gatsby's new [WordPress integration](https://www.gatsbyjs.com/plugins/gatsby-source-wordpress/) to add a blog to the site!
134+
135+
This would involve setting up a `/blog` page, and creating a new page for each blog post sourced from WordPress. The [docs](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-wordpress/docs/tutorials/building-a-new-site-wordpress-and-gatsby.md#creating-pages-for-each-blog-post-and-linking-to-them) suggest using `gatsby-node.js` and the `createPages` API, but I had a hunch that this wasn't necessary - I could simply use the [File System Route API](https://www.gatsbyjs.com/docs/reference/routing/file-system-route-api/), as I had with the Contentful cities.
136+
137+
First, I had to setup the `src/pages/blog` page, which would list out all the posts, using the following query:
138+
139+
```graphql
140+
query wpPosts {
141+
allWpPost(sort: { fields: date, order: DESC}) {
142+
edges {
143+
node {
144+
title
145+
date
146+
id
147+
slug
148+
excerpt
149+
}
150+
}
151+
}
152+
}
153+
```
154+
155+
This was used to create a grid of posts excerpts, linking to the actual blog post page:
156+
157+
```react
158+
{data.allWpPost.edges.map(({node:post}) => (
159+
<Box m="10px" p="10px" grow="1" maxW="400px" key={post.slug}>
160+
<Link to={'/blog/' + post.slug}>
161+
<Heading as="h4" size="lg" color="primary.800" mb="1.5" textAlign="center">
162+
{post.title}
163+
</Heading>
164+
<Text dangerouslySetInnerHTML={{ __html: post.excerpt }} isTruncated="true">
165+
</Text>
166+
</Link>
167+
</Box>
168+
))}
169+
```
170+
171+
Next, I created the collection route & template for the actual blog post itself, at `src/pages/blog/{wpPost.slug}.js`, which uses the following query:
172+
173+
```graphql
174+
query ($id: String = "") {
175+
wpPost(id: {eq: $id}) {
176+
title
177+
date(formatString: "DD MMMM, YYYY")
178+
content
179+
slug
180+
id
181+
}
182+
}
183+
```
184+
185+
This would create a page for each blog post, which were already linked from the `/blog` page! Fantastic!
186+
187+
***
188+
189+
## [Challenge 4](https://www.gatsbyjs.com/blog/100days-challenge-4/)
190+
191+
Challenge 4 involved setting up a Shopify e-commerce store to sell swag for the popular fictional startup, audioC0RE!
192+
193+
So, I setup a Shopify developer account, installed the necessary plugin and configured everything according to the [docs](https://github.com/gatsbyjs/gatsby-source-shopify). Unfortunately, I encountered an error:
194+
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gruto9tq2w7jrlbtx7ku.png)
195+
196+
Hmm...that's not very helpful, is it? I searched everywhere, asked twitter and couldn't find anything! So, I opened an [issue](https://github.com/gatsbyjs/gatsby-source-shopify/issues/108#event-4518155849) on Github! This was my first time opening an issue, so I was a little intimidated, but thankfully the maintainer was incredibly nice and helpful! After lots of back and forth, I eventually determined the source of the error: a typo 🤦
197+
198+
I had trailing commas in my `.env` file, which were causing the unauthenticated error because it was adding an extra character to the API key! I felt a little foolish for missing this, but ultimately I'm glad for it! I had a great first issue experience, and it resulted in some additional logging being added to the plugin, which will hopefully help other developers to debug their own issues faster!
199+
200+
After getting that issue sorted out, setting up the `/shop` page went smoothly. I was able to use the [File System Route API](https://www.gatsbyjs.com/docs/reference/routing/file-system-route-api/) again, with a `src/pages/shop/{shopifyProduct.handle.}js` to create the individual pages for each product, and had a listing of all products on the `/src/pages/shop.js` page.
201+
202+
I'll spare you the details once again, but if you want to see the code feel free to look through the [repo](https://github.com/megfh/100daysofgatsby2021)!
203+
204+
## Conclusion
205+
206+
Ultimately, the #100DaysOfGatsby challenge was a great experience! I was able to add a new project to my resume, learn some new things, and I now feel more confident working with both React & Gatsby.
207+
208+
I highly recommend anyone who is interested in learning Gatsby give this challenge a try!

0 commit comments

Comments
 (0)