Skip to content

Instantly share code, notes, and snippets.

@JohnAlbin
Forked from clarkdave/createPages.ts
Last active March 18, 2024 09:25
Show Gist options
  • Save JohnAlbin/2fc05966624dffb20f4b06b4305280f9 to your computer and use it in GitHub Desktop.
Save JohnAlbin/2fc05966624dffb20f4b06b4305280f9 to your computer and use it in GitHub Desktop.
TypeScript + Gatsby config and node API

README

  1. When Gatsby starts up, it will read gatsby-config.js first.
  2. As you can see below, we use that file to require('ts-node').register() which registers a TypeScript evaluator that will be used when Gatsby reads all other API Javascript files. In other words, we only need to do this once in our entire codebase and not in other Gatsby files like gatsby-node.js.
  3. Our gatsby-config.js re-exports all the exported variables available in gatsby-config.ts.
  4. Later, since the ts-node evaluator is still active, Gatsby will load gatsby-node.ts instead of gatsby-node.js.
  5. The same thing is true of other gatsby files; e.g. gatsby-browser.ts can be used instead of gatsby-browser.js.

Credits

I didn't come up with all of this on my own. I mentioned all the sources in the original gist.

// We register the TypeScript evaluator in gatsby-config so we don't need to do
// it in any other .js file. It automatically reads TypeScript config from
// tsconfig.json.
require('ts-node').register();
// Use a TypeScript version of gatsby-config.js.
module.exports = require('./gatsby-config.ts');
// All exported variables in this file will also used in gatsby-config.js.
export const siteMetadata = {
title: `My Gatsby Site`,
description: `An example site.`,
};
export const plugins = [
'gatsby-plugin-typescript',
'gatsby-plugin-postcss',
);
// Because we used ts-node in gatsby-config.js, this file will automatically be
// imported by Gatsby instead of gatsby-node.js.
// Use the type definitions that are included with Gatsby.
import { GatsbyNode } from 'gatsby';
import { resolve } from 'path';
export const createPages: GatsbyNode['createPages'] = async ({
actions,
graphql,
}) => {
const { createPage } = actions;
const allMarkdown: {
errors?: any;
data?: { allMarkdownRemark: { nodes: { fields: { slug?: string } }[] } };
} = await graphql(`
query allMarkdownQuery {
allMarkdownRemark(limit: 1000) {
nodes {
fields {
slug
}
}
}
}
`);
allMarkdown.data?.allMarkdownRemark.nodes.forEach(node => {
const { slug } = node.fields;
if (!slug) return;
// Type-safe `createPage` call.
createPage({
path: slug,
component: resolve(__dirname, '../src/templates/index.tsx'),
context: {
slug,
},
});
});
};
@dandv
Copy link

dandv commented Jun 8, 2020

So I've just learned that there's a plugin gatsby-plugin-ts-config that "write all of your config files in Typescript", and has gotten quite a bit of exposure in the issue about native TypeScript support for Gatsby.

@isaac-martin
Copy link

Anyone have this working with path aliases? I keep getting build errors because it can't resolve some stuff

@henricazottes
Copy link

It seems promising but can't get it working, I have this error running gatsby develop:

  TSError: ⨯ Unable to compile TypeScript:
  gatsby-node.ts:29:53 - error TS7006: Parameter 'node' implicitly has an 'any' type.
  29   allMarkdown.data?.allMarkdownRemark.nodes.forEach(node => {
                                                         ~~~~
  gatsby-node.ts:29:20 - error TS1109: Expression expected.
  29   allMarkdown.data?.allMarkdownRemark.nodes.forEach(node => {
                        ~
  gatsby-node.ts:41:5 - error TS1005: ':' expected.
  41   });
         ~

Which is weird cause VSCode shows me the inferred type when I move the pointer over the node argument:
image

@thepedroferrari
Copy link

Thank you, it works!

@bsgreenb
Copy link

bsgreenb commented Oct 5, 2020

Hey @JohnAlbin , wondering if you have any insight into this issue? I think it may be related to using ts-node/commonjs as required in this setup? https://stackoverflow.com/questions/64202523/exporting-global-styles-with-font-assets-from-a-typescript-commonjs-module

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