Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
TypeScript + Gatsby node API
import { resolve } from 'path'
import { GatsbyCreatePages } from './types'
const createPages: GatsbyCreatePages = async ({
graphql,
boundActionCreators,
}) => {
const { createPage } = boundActionCreators
const allMarkdown = await graphql(`
{
allMarkdownRemark(limit: 1000) {
edges {
node {
fields {
slug
}
}
}
}
}
`)
allMarkdown.data.allMarkdownRemark.edges.forEach(edge => {
const { slug } = edge.node.fields
if (!slug) return
// type safe `createPage` call
createPage({
path: slug,
component: resolve(__dirname, '../src/templates/index.tsx'),
context: {
slug,
},
})
})
}
'use strict'
require('source-map-support').install()
require('ts-node').register({
compilerOptions: {
module: 'commonjs',
target: 'es2017',
},
})
exports.createPages = require('./createPages')
interface PageInput {
path: string
component: string
layout?: string
context?: any
}
interface BoundActionCreators {
createPage: (page: PageInput) => void
deletePage: (page: PageInput) => void
createRedirect: (
opts: {
fromPath: string
isPermanent?: boolean
redirectInBrowser?: boolean
toPath: string
}
) => void
}
export type GatsbyCreatePages = (
fns: { graphql: any; boundActionCreators: BoundActionCreators }
) => void
@clarkdave
Copy link
Author

clarkdave commented Apr 15, 2018

@subtleGradient
Copy link

subtleGradient commented Dec 14, 2018

@clarkdave Thank you so much for figuring this out and making it so easy to learn and use!

@KrisTemmerman
Copy link

KrisTemmerman commented May 20, 2019

Thank you for making this so easy, converted my project to ts in 10 minutes <3

@crhistianramirez
Copy link

crhistianramirez commented Aug 13, 2019

I had to update

const createPages: GatsbyCreatePages = async ({

to

export const createPages: GatsbyCreatePages = async ({

AND

exports.createPages = require('./createPages')

to:

exports.createPages = require('./createPages').createPages

@SimonS
Copy link

SimonS commented Sep 10, 2019

@crhistianramirez same - it fixes the TypeError: gatsbyNode[api] is not a function problems

@orta
Copy link

orta commented Oct 24, 2019

The types for Gatsby ship with Gatsby - you should be able to write code like this instead:

import { GatsbyNode } from "gatsby"
import * as path from "path"

export const createPages: GatsbyNode["createPages"] = async ({ graphql, actions }) => {
  const { createPage } = actions

  const blogPost = path.resolve(`./src/templates/blog-post.tsx`)
  const result = await graphql(`
    {
      allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }, limit: 1000) {
        edges {
          node {
            fields {
              slug
            }
            frontmatter {
              title
            }
          }
        }
      }
    }
  `)

  if (result.errors) {
    throw result.errors
  }

@JohnAlbin
Copy link

JohnAlbin commented Mar 22, 2020

@clarkdave, Thanks for sharing this and getting the conversation started.

We can simplify our Gatsby JavaScript files even more, since that JS file can re-export all the exports of a TypeScript file in one line with:

module.exports = require('./path/to/typescript/file');

That means we can have a single TypeScript file with all of our Gatsby API exports. And if we add new API calls to our TypeScript file, they get automatically exported by the JavaScript file without needing to modify it.

Also, ts-node now includes source-map-support. https://github.com/TypeStrong/ts-node/blob/be2c899ca796bd6dc54e074fdb2c5a32df51213d/src/index.ts#L407

With:

  • my comments about module.exports and source-map-support,
  • the fact that boundActionCreators are now deprecated,
  • @orta's comment that "types for Gatsby ship with Gatsby",
  • @jonnybot0's comment (from the Gatsby issue Dave pointed out above) that "ts-node automagically loads tsconfig.json",
  • @jonnybot0's comment that require('ts-node').register() can be put in gatsby-config.js and it will apply to all other gatsby API files, like gatsby-node.js.
  • @assainov's blog post about using gatsby-node.ts instead of gatsby-node.js.

I went ahead and made all those updates in this forked gist: https://gist.github.com/JohnAlbin/2fc05966624dffb20f4b06b4305280f9

@dandv
Copy link

dandv commented May 9, 2020

Thanks @JohnAlbin! I've linked to your gist from this Gatsby issue.

@dillionmegida
Copy link

dillionmegida commented Apr 15, 2021

@crhistianramirez same - it fixes the TypeError: gatsbyNode[api] is not a function problems

@crhistianramirez please, could you explain why your change fixed this error?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment