Refactor your Gatsby website to use Typescript

February 2, 2020

If you are a big fan of Typescript (like me 🙋‍♂️), and you have a Gatsby website, then you are in the right place.

Here, I want to show you how to refactor your Gastby website to use Typescript.

If you just want to see code, it's fair. Here is the change I made for this website.

Otherwise, if you are curious and want to understand what is going on under the hood, keep reading.


  • Have a Gatsby Website.
  • You have a good understanding of what Typescript is.


First, you need to install:

  • Typescript: The compiler.
  • gatsby-plugin-typescript: Which provides drop-in support for Typescript and TSX (more info).
npm install typescript gatsby-plugin-typescript

Then, add the plugin into Gatsby's configuration file gatsby-config.js.

module.exports = {
plugins: [

Last but not least, install the @types/ packages needed:

npm install @types/node @types/react @types/react-dom --save-dev

In my specific case, I'm using styled-compoents and react-helmet, so I needed to install more @types/ packages.

npm install @types/react-helmet @types/styled-components --save-dev

If that is not your case, you don't need to.

Refactoring components

Updating file extensions

Rename your files to replace the extension to be .ts if they don't use JSX and .tsx if they do.

mv ./components/Footer.js ./components/Footer.tsx

Resolve return types

Specify the return type of your component.

function Footer(): JSX.Element {
return ...

Typing your Queries

By using Typescript, you can make sure your components are aware of the type of data running through them.

We are going to create a file called types/schema.ts, in which we are going to place our query schema types.

Let's have a look at one of our pages query, the homepage, where we show the first five blog posts.

A query for that will look like this:

query getPageData {
posts: allMdx(
limit: 5
sort: { order: DESC, fields: [frontmatter___date] }
filter: { fileAbsolutePath: { regex: "/(/data/blog)/.*.md$/" } }
) {
edges {
node {
fields {
excerpt(truncate: false, pruneLength: 240)
frontmatter {
date(formatString: "DD/MM/YYYY")

And its type, something like this:

export interface PostsQuery {
edges: {
node: {
id: string
fields: {
slug: string
excerpt: string
frontmatter: {
title: string
date: string

Then, all you need to do is to cover your Props with the corresponding Query type.

import { PostsQuery } from '../types/schema'
type Props = {
data: {
posts: PostsQuery
function Index({ data }: Props): JSX.Element {

That's it!

In review, all you need to do is:

  • Install typescript, gatsby-plugin-typescript and the @types/... you need for your website.
  • Configure Gatsby to use gatsby-plugin-typescript.
  • Refactor your components and types to use Typescript.

Read more about

View all posts →