visit
NOTE: I have opted not to use any themes or templates for this post. Instead, we're going to set this up from scratch! This gives better fine-grain control over the project and will help promote a better understanding of Gatsby and the surrounding plugin ecosystem. But, if you want to use a starter template, that's great too!
NOTE: This article assumes you have a basic to advanced understanding of Node, React, Git, and JavaScript/TypeScript. So, I won't explain how to set up your development environment. However, if you need a refresher or more information about setting things up, check the official documentation from GatsbyJS for a detailed walkthrough.
NOTE: At the time of writing (Feb. 2023), GatsbyJS is on version 5. Eventually, this series will become outdated as new versions of Gatsby are released. I will update these articles to note any changes to the framework. If you notice something obsolete or wrong, please don't hesitate to let me know in the comments!
The very first thing we need to do is install the gatsby-cli
globally:
npm install -g gatsby-cli
Next, we will create a basic project in GatsbyJS. You'll run the gatsby new
command and then answer the questions as outlined below.
I will opt-in to TypeScript and Emotion for styling. You don't have to do this, but it will make following this tutorial much easier if you keep in sync with what I do.
gatsby new
What would you like to call your site?
✔ · My Gatsby Blog
What would you like to name the folder where your site will be created?
✔ blog-related-repos/ my-gatsby-blog
✔ Will you be using JavaScript or TypeScript?
· TypeScript
✔ Will you be using a CMS?
· No (or I'll add it later)
✔ Would you like to install a styling system?
· Emotion
✔ Would you like to install additional features with other plugins?
· Add responsive images
· Generate a manifest file
Thanks! Here's what we'll now do:
🛠 Create a new Gatsby site in the folder my-gatsby-blog
🎨 Get you set up to use Emotion for styling your site
🔌 Install gatsby-plugin-image, gatsby-plugin-manifest, gatsby-plugin-mdx
Change directories into the newly created project directory and run gatsby develop
to start the development server.
The development server is fantastic! It will automatically reload your app for you as you make changes (hot reloading) and does some other optimizations on the fly to allow you to develop your project seamlessly.
cd my-gatsby-blog
gatsby develop
npm install -D prettier prettier-plugin-tailwindcss
The
prettier-plugin-tailwindcss
module will help keep our tailwind classes organized!
Create a new file named .prettierrc.json
in the root folder.
touch .prettierrc.json
// .prettierrc.json
{
"singleQuote": true,
"plugins": ["prettier-plugin-tailwindcss"]
}
If you don't like using single quotes for your quote marks, you can omit the
singleQuote
setting
We want to ignore a few folders and files. So, create a file named .prettierignore
in the root folder.
touch .prettierignore
// .prettierignore
node_modules
package.json
package-lock.json
tsconfig.json
src/styles/global.css
.cache
public
It's a good idea to have a script in your package.json
file that will execute Prettier formatting on demand.
Open up your package.json
file and add a "format"
script
// package.json
"scripts": {
"develop": "gatsby develop",
"start": "gatsby develop",
"build": "gatsby build",
"serve": "gatsby serve",
"clean": "gatsby clean",
"typecheck": "tsc --noEmit",
"format": "prettier --write ." // <-- Add this
},
npm run format
npm install -D eslint eslint-config-prettier eslint-config-react-app
touch .eslintrc.js
// .eslintrc.js
module.exports = {
globals: {
__PATH_PREFIX__: true,
},
extends: ['react-app', 'prettier'],
};
touch .eslintignore
src/styles/global.css
public
As with Prettier, having a script in the package.json
file is good practice that automates running Eslint for your project.
Open the package.json
file back up and add the "lint"
and "lint:fix"
scripts:
// package.json
"scripts": {
"develop": "gatsby develop",
"start": "gatsby develop",
"build": "gatsby build",
"serve": "gatsby serve",
"clean": "gatsby clean",
"typecheck": "tsc --noEmit",
"format": "prettier --write .",
"lint": "eslint . --ext ts,tsx,js,jsx", // <-- Add this
"lint:fix": "eslint . --ext ts,tsx,js,jsx --fix" // <-- Add this
},
The --fix flag will tell Eslint automatically fix any errors it sees if it can.
For this blog, we'll use the "Roboto" font. However, feel free to use any other font you like from
@fontsource
; install the appropriate module and then update yourgatsby-browser.ts
file appropriately.
npm install @fontsource/roboto
Then we have to create the gatsby-browser.ts
file and add the fonts we want to use.
The
gatsby-browser.ts
provides an entry point to your various pages. It wraps your page components with a global set of imports and API methods. We'll only be taking advantage of it to load global CSS files. But .
touch gatsby-browser.ts
// gatsby-browser.ts
import '@fontsource/roboto/100-italic.css';
import '@fontsource/roboto/100.css';
import '@fontsource/roboto/300-italic.css';
import '@fontsource/roboto/300.css';
import '@fontsource/roboto/400-italic.css';
import '@fontsource/roboto/400.css';
import '@fontsource/roboto/500-italic.css';
import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700-italic.css';
import '@fontsource/roboto/700.css';
import '@fontsource/roboto/900-italic.css';
import '@fontsource/roboto/900.css';
Styling and style systems are essential for any website project. I tend to prefer using tailwindcss
for my projects, and I don't think that's a particularly controversial choice, but you can choose whatever style system you like. If you prefer something else, feel free to go off the script!
I love it.
npm install -D tailwindcss autoprefixer postcss gatsby-plugin-postcss
npm install twin.macro tailwind-merge
The
twin.macro
utility helps us integrate the Emotion plugin (which we opted to use when creating the project) with tailwindcss. Thetailwind-merge
plugin is a super helpful utility that lets us merge tailwind classes intelligently and avoids class name collisions; you'll see how we use them later.
npx tailwindcss init -p
This will create a tailwind.config.js
file and a postcss.config.js
file in the project root.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./src/pages/**/*.{js,jsx,ts,tsx}',
'./src/components/**/*.{js,jsx,ts,tsx}',
'./src/templates/**/*.{js,jsx,ts,tsx}',
],
theme: {
extend: {
fontFamily: {
sans: ['Roboto', 'sans-serif'],
},
},
},
plugins: [],
};
This setup tells Tailwind where to find our source code and sets our application's default "sans" font to the "Roboto" font we added to our gatsby-browser.ts
file above.
mkdir src/styles
touch src/styles/global.css
Add the following content to the global.css
file:
@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind screens;
gatsby-browser.ts
We need to add the global CSS file to gatsby-browser.ts
so every page can use the beautiful tailwind styles we love.
// gatsby-browser.ts
// ... (other styles)
import './src/styles/global.css';
First, kill any existing
gatsby develop
processes
gatsby develop
You won't notice much difference at this point because the default pages are all styled with CSS in JS by default. But, if you want, you can tinker with the pages/index.tsx
page and add some tailwind classes. For example, something like this might be a good test:
We'll be doing something different with this file in the next part of this article, so avoid getting too attached to this basic look.
import type { HeadFC, PageProps } from 'gatsby';
import * as React from 'react';
const IndexPage: React.FC<PageProps> = () => {
return (
<main className="font-sans font-light">
<div className="container mx-auto px-4 lg:px-0">
<h1 className="my-8 text-4xl font-bold lg:text-5xl">My Gatsby Blog</h1>
<span className="text-lg">This is my Gatsby Blog home page!</span>
</div>
</main>
);
};
export default IndexPage;
export const Head: HeadFC = () => <title>Home Page</title>;