DEV Community

loading...
Cover image for Gatsby - Trash Course [1/3]

Gatsby - Trash Course [1/3]

Vinicius Cerqueira Bonifácio
JavaScript developer, technology passionate, Ubuntu evangelist, ex mountain guide, active football player, inactive surfer, professional backpacker and hitchhiker.
・10 min read

Hey, my friend devs.

How have you all been? Doing good? If you are so do I. 🙏

I am back with an other Trash Course series. 🍾 🎉

Trash Course, for who doesn't know yet, is something like a crash course but worst. 😂

What will be covered in this part?

  • Initial blah blah blah
  • Minimal Requirements
  • What is Gatsby?
  • What will we build?
  • Initial Setup (installing, starter sites etc.)
  • Pages and Routing
  • Components
  • Layouts
  • Styling (CSS - Global and Modules)
  • Farewell (and what will come next?)

TLDR: You can skip all the introduction and go straight to Finally Let's Get Started section. Be aware you will lose all my first class jokes. 😂


Thankful Section

Before start, I would like to thank each one of you about the repercussion that the Next.js Trash Course has had so far.😃

I didn't expected that because I am not writing anything very technical here, it is more like "having fun while doing it" than "how to get hired into a FAANG company with this series."
(BTW, if you are expecting for the last one I have very bad news for you: wrong place, comrade. 🤣 🤣 🤣)


At this time I will be covering some of the Gatsby fundamentals and at the end of this series you will be able to build a very simple website using Gatsby. (I hope I will be clear enough to guide you to do so 🤲.)

Before we start our journey, there are some requirements that will make the development process smoother: 🤏

  • Node / NPM installed in your machine,
  • Basics of HTML, CSS and JavaScript,
  • Basics of React and GraphQL,
  • Your favorite code editor (e.g. VSCode, Papyrus, MS Word, 💁 etc),
  • Git / GitHub (optional).

That's said, let's get s t a r t e d !

What is Gatsby?

Gatsby is an acronym for "Get All Time Sunbath By Yourself". 😭 It is totally true, believe me, as 2 plus 2 is 354. 😅

Now, seriously, Gatsby is known as a SSG or Static Site Generator, in other words, it builds your site as "static" files which can be deployed easily on different kind of services. 🤯(Ahh, now my joke doesn't look like that bad, right?! 😋 Too late, mate.)

Indeed, for me the phrase above doesn't "say" anything either. I will try to explain it concisely in the following lines. (I wrote "try", doesn't expect too much. 😜)

A SSG usually generates static HTML pages using a combination of data, components, templates etc.

You may be thinking: 💭 ".. But I could do it using the classic frontend stack (HTML, CSS and JS), maybe build a Simple Page Application (SPA) or even reach the same result with a Server Side Rendered website (SSR)".

Answer: It reminds once when I traveled to Colombia and people there used to answer my questions with Sí pero no. that is the equivalent to Yes but not. 🇨🇴 💓

💡 If all these acronyms are somehow confusing you (e.g SSR, SSG, FBI, F4F, TBT etc) I have explained some of them less in depth (yeah, you read it right, It is written "less".) here.

In short, some of the advantages of using Gatsby over the another approaches I have mentioned previously are: 👇

  • It creates the static pages at build time, not during the deployment,
  • Those pages are created using React components,
  • After the first request, the application behaves pretty much as a SPA,
  • Combines all data sources into a GraphQL layer,
  • Good for SEO, speed, easy to maintain and update etc.

Next.js (SSR and SSG), for example, has almost all the benefits that Gatsby has but with some exceptions. Its speed is not very optimized when it regards fetching data / rendering (when dealing with large amounts of data, for example.).

I have mentioned Next.js just because, but it applies for all the other examples we have just (shallow) discussed.

Some of them advantages have and some of them don't. (Yoda)

Yoda

Am I telling that Gatsby is better than the others? By any means!

Just think of frameworks, libraries, programming languages and similars as just tools. You always need to wisely choose between them given the "problem" you intend to solve.

Imagine one scenario where you need a knife to cut your bread and maybe put some butter on it. Would you buy a Katana to do so? It gets the job done but is it really necessary?

If you got my point here we are good to go. If you didn't ... 👇👇

Katana

I know I have written a lot before starting the real coding (that I am sure is the reason you are here 👨‍💻 👩‍💻) but I don't like to just copy-paste theories.

By the way, it is just my point of view and it is a Trash Course. So please chill and have some fun while learning something new (If it is the case 😆).

What will we build?

A very simple website with my favorite Super Smash Bros characters. 💪

It is totally fine if you are not a Nintendo fan. Deep inside we know which one is the best games factory on earth, right? 🏆
(PS.: I am not earning a dime from Nintendo, I am just a stupid person doing free marketing for them. 🤦)

As I was saying (I am losing the track here), our website will look like very much as the screenshots below:

  • Home Page:
    Home Page

  • Heroes Page:
    Heroes Page

  • Individual Hero:
    Individual Hero

Finally Let's Get Started

Initial Setup

First of all, we need to have the gatsby-cli package installed globally in our machine.

npm install gatsby-cli

After done that, you can check if it was installed correctly typing:

gatsby --version

If you, for some reason, have a a message like gatsby: command not found after finished the installation process, close your terminal and re open it or open a new tab. (It worked for me. 💌)

We will use a Starter Site" as the bare-bone of our project. It is similar to create-react-app as it holds all the basic settings we need initially.

See more: Gatsby - Hello World

On the terminal, type:
gatsby new gatsby-sample https://github.com/gatsbyjs/gatsby-starter-hello-world

Where:

  • gatsby new: creates a new gatsby application
  • gatsby-sample: is the name you want to give to your project. Obviously you can change it to whatever name you wish to.
  • https://github.com/gatsbyjs/gatsby-starter-hello-world is the url of the starter site we will use, in our case, the hello-world one.

cd gastby-sample && code .. I assume you are using VSCode because of that command code ..

Let's run our local development server and see what is waiting for us there in the browser.

gatsby develop (Note: This script is created by default in the package.json file.)

In your console you should see a message similar to:

You can now view gatsby-starter-hello-world in the browser.
⠀
  http://localhost:8000/
Enter fullscreen mode Exit fullscreen mode

What are you waiting for? Type that address in your browser. ⌨️ 🏃‍♀️💨

If everything went fine during the initial settings process, you should be able to see the so famous Hello world! in your browser.
That is nothing more nothing less than the content of src/pages/index.js rendered in your browser. Perfect, let's keep going.

🗒️ If you have followed my Next.js series you know I have made a "quick walking through the files and folders" but here I won't do that!

Why? No, I am not angry or anything. When we created a new application in the steps before, Gatsby has generated a very well written docs for us. You can find it in the README.md file. 📚 🔥

Pages and Routing

Creating pages and routes it pretty easy with Gatsby. If you have any basic experience using Next.js so you already have mastered it. If you haven't you are going to. 😎

Look at the src/pages directory. There is where we will place all our page components. Every folder inside of the src/pages is equivalent a route and every whatever.js file you create there corresponds to a page.

Examples:

  • If you have src/pages/devs/index.js directory, the url in our browser will be /devs/,
  • src/pages/devs/about.js creates a devs/about page.
  • src/pages/hello/index.js creates the /hello/ route and its home page (index).

Note:

  • If you name a file as index.js it will be the homepage of whatever route (folder) you have created.
  • The src/pages/ folder is the root path, for example, the localhost:8080/ in development mode.

I hope it makes sense. Anyway, learning by doing is the motto here. 💪

Let's improve our home page. For now, we will make some changes in the src/pages/index.js file.

import { Link } from "gatsby"
import React from "react"

const Home = () => {
  return (
    <section>
      <div>
        <h1>Smash Bros</h1>
        <h3>The Best Heroes</h3>
        <Link to="/heroes">Check Heroes</Link>
      </div>
    </section>
  )
}

export default Home
Enter fullscreen mode Exit fullscreen mode

Before you even ask about these two lines. 😉

👉 import { Link } from "gatsby" 👈
👉 <Link to="/heroes">Check Heroes</Link> 👈

👇                                                      👇
/** The Link component is intended only for links to pages handled by Gatsby.
 * For links to pages on other domains or pages on the same domain not handled by the current Gatsby site, use the normal <a> element. */

Enter fullscreen mode Exit fullscreen mode

Except for the <Link/> component, the rest is pretty much just React stuff. Now we have a brand new and ugly home page. Nice!

Components

Same as in React, we can create reusable components and, guess what, reuse them through the application. ♽ ♽

Personally I like to place all components inside of a components folder so it is easy to track them.

But as Kurt Cobain used to sing: 🎵"... The choice is yours, don't be late ..." 🎵

Kurt Cobain

As an example, let's create a Navbar component: src/components/Navbar.js. (Navbar)

import { Link } from "gatsby"
import React from "react"

const Navbar = () => {
  return (
    <nav>
      <h1>
        <span>Smash Bros.</span>
      </h1>
      <div>
        <Link to="/">Home</Link>
        <Link to="/heroes">Heroes</Link>
        <Link to="/about">About</Link>
      </div>
    </nav>
  )
}

export default Navbar
Enter fullscreen mode Exit fullscreen mode

Layouts

Creating and using layouts is a nice way to DRY (Oh no, other acronym detected 🥱).

Imagine that we have both a Navbar and Footer components and our intention is to place them in every page of our site. Instead importing them individually in every single page we could make use of a Layout component in order to place them there.

There we go: src/components/Layout.js

import React from "react"
import Navbar from "./Navbar"

export const Layout = ({ children }) => {
  return (
    <div>
      <Navbar />
      <main>{children}</main>
      {/** You could add a footer component here, for instance*/}
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

And it is time to import and use the Layout in our Home page component.

src/pages/index.js

import { Link } from "gatsby"
import React from "react"
+ import { Layout } from "../components/Layout"


const Home = () => {
  return (
+    <Layout>
      <section>
        <div>
          <h1>Smash Bros</h1>
          <h3>The Best Heroes</h3>
          <Link to="/heroes">Check Heroes</Link>
        </div>
      </section>
+   </Layout>
  )
}

export default Home
Enter fullscreen mode Exit fullscreen mode

Amazing! We have had some progress here but our Home page is a little bit clunky, isn't it?
What about adding some styling? 💅 Hell, yeah! (Sorry! 🤭)

Styling

There are two simple ways to add styles on Gatsby:

  • Using the classic and old school (but still loved ❤️) global stylesheets file,
  • Using CSS modules.

The difference between them you can find in my Next.js Trash Course as well as their usage (Please refer to: Part 6 - Adding Styles 💅).

  • Global Stylesheets

Let's create the CSS file (src/styles/global-styles.css) that will hold the global styling and also the style of both <Navbar> and <Layout /> components.

* {
  margin: 0;
  padding: 0;
  text-decoration: none;
  font-family: Verdana, Geneva, Tahoma, sans-serif;
  color: rgb(192, 189, 189);
}

:root {
  --pink-text: #b1283f;
}

body,
html {
  min-height: 100%;
}

body {
  background: linear-gradient(
    326deg,
    rgba(96, 110, 106, 1) 0%,
    rgba(17, 149, 163, 1) 51%,
    rgba(7, 8, 89, 1) 100%
  );
  background-repeat: no-repeat;
}

p {
  margin: 20px auto;
  line-height: 1.3rem;
}

nav {
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin: 50px auto;
}

nav h1 {
  text-shadow: 2px 2px black;
}

nav h1 span {
  color: var(--pink-text);
  letter-spacing: 2px;
  background-color: rgba(0, 0, 0, 0.1);
  padding: 2px 5px;
  border-radius: 7px;
}

nav.links {
  display: inline-block;
  text-align: right;
}

nav a {
  display: inline-block;
  margin-left: 20px;
  font-size: 20px;
  font-weight: bold;
  text-shadow: 2px 2px black;
  padding-bottom: 10px;
  border-bottom: 2px solid transparent;
}

nav a:hover {
  border-color: var(--pink-text);
}

.layout {
  max-width: 1200px;
  margin: 0 auto;
}
Enter fullscreen mode Exit fullscreen mode

🚨 The styles applied in this project were created merely for demonstration. Use it in other projects at your own risk. 🚨

After saving this file, could you see our Navbar shinning? ✨ 🥺

No? Of course not, we have neither added any classes nor imported the CSS file in our components, my friend. 😂

  • src/components/Layout.js
import React from "react"
import Navbar from "./Navbar"
+ import "../styles/global-styles.css"

export const Layout = ({ children }) => {
  return (
+    <div className="layout">
      <Navbar />
      <main>{children}</main>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode
  • src/components/Navbar.js
import { Link } from "gatsby"
import React from "react"

const Navbar = () => {
  return (
    <nav>
      <h1>
        <span>Smash Bros.</span>
      </h1>
+     <div className="links">
        <Link to="/">Home</Link>
        <Link to="/heroes">Heroes</Link>
        <Link to="/">About</Link>
      </div>
    </nav>
  )
}

export default Navbar
Enter fullscreen mode Exit fullscreen mode

Nice! Now the styles should have applied. Now let's style our Home component but this time using CSS modules.

  • Create a new css file ➡️ ´src/styles/home.modules.css´ and place the content below:
.header {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-gap: 40px;
  align-items: center;
  background-color: rgb(0, 0, 0, 0.2);
  padding: 20px;
  margin-top: 100px;
  border-radius: 12px;
}

.header h1 {
  font-size: 4em;
  text-shadow: 2px 2px #0a0303;
  color: var(--pink-text);
}

.header h3 {
  font-size: 2.7em;
  font-weight: 400;
  margin-bottom: 20px;
}

.btn {
  display: inline-block;
  background-color: var(--pink-text);
  border: 1px solid rgb(231, 229, 229);
  padding: 10px 19px;
  border-radius: 10px;
  margin-top: 20px;
  font-size: 1.2rem;
  font-weight: bold;
  text-shadow: 2px 2px #0a0303;
}

.btn:hover {
  background-color: rgb(170, 155, 155);
  border: 1px solid var(--pink-text);
  color: var(--pink-text);
  transform: scale(1.03);
}
Enter fullscreen mode Exit fullscreen mode

The way we apply the styles using CSS modules in our components is slightly different from the conventional one.

  • src/pages/index.js:
import { Link } from "gatsby"
import React from "react"
import { Layout } from "../components/Layout"
+ import * as styles from "../styles/home.module.css"

const Home = () => {

  return (
    <div>
      <Layout>
+        <section className={styles.header}>
          <div>
            <h1>Smash Bros</h1>
            <h3>The Best Heroes</h3>
+            <Link className={styles.btn} to="/heroes">
              Check Heroes
            </Link>
          </div>
        </section>
      </Layout>
    </div>
  )
}

export default Home
Enter fullscreen mode Exit fullscreen mode

It is pretty straightforward and now way prettier than before I guess. 😃 😃

I have sad news, guys. 😭 😭 It is just that for today.

As in the next parts (probably two more) we will be dealing with GraphQL queries, Gatsby plugins, source files etc I don't want you to get overwhelmed by them right now.

I didn't have time yet to plan in each order I will introduce you those concepts (and I am sorry for that) but I promise I am going to try hard to follow a "development logic" order.

Well, that's it. Thanks a lot for staying with me so far and I hope to see you in the next part! 🙏 🤗

Have a great week everybody!

Stay safe, drink some water and be kind with each other. 💞 💞

Please let me know if something is not very clear so I can try to explain it in an other way.

Discussion (11)

Collapse
ekafyi profile image
Eka

I don't plan/need to learn Gatsby at the moment but dropped a like because of the name Trash Course! 🍻

Collapse
vinicius77 profile image
Vinicius Cerqueira Bonifácio Author

Thanks a lot for the support, Eka. 😊

Collapse
abror1997 profile image
Abror Xalilov • Edited

Why is it named "Trash Course"?)

Collapse
leandroruel profile image
Leandro RR

is just a joke

Collapse
abror1997 profile image
Abror Xalilov

😄😄 ok I got it

Collapse
vinicius77 profile image
Vinicius Cerqueira Bonifácio Author

🤣 💦 😂 💦 Am I a joke to you? 🤣 💦 😂 💦

Just kidding, you are right!! Thanks for you comment. :)

Collapse
vinicius77 profile image
Vinicius Cerqueira Bonifácio Author

I got a little bit late to reply you but our friend Leandro already did it. :)

Thanks for participating, Abror. 🙏

Collapse
upupkenchoong profile image
Ken Choong

hahhahahaha, I like this:

Imagine one scenario where you need a knife to cut your bread and maybe put some butter on it. Would you buy a Katana to do so?

Collapse
vinicius77 profile image
Vinicius Cerqueira Bonifácio Author

It was the very first analogy that came to my mind, Ken. 🤣 💦 😂 💦

Thanks for interacting with the post. I really appreciate that. 🙏

Collapse
upupkenchoong profile image
Ken Choong

Keep it up bro.. Is fun to read..hahaha

Thread Thread
vinicius77 profile image
Vinicius Cerqueira Bonifácio Author

I don't know if it means anything but I'll try my best. 🤣 💦