Quantcast
Channel: Krzysztof Żuraw blog's RSS Feed
Viewing all articles
Browse latest Browse all 205

Customizing Gatsby Graphql schema

$
0
0

Recently I was doing redesign of my blog. As you may know, I used Gatsby.js. All in all, it is a very good static site generator but I had one problem with it. Or to be more precise the issue was with Gatsby and the TypeScript.

Problem

I try to help myself when writing frontend code so I decided that I will try to automatically generate TypeScript interfaces from GraphQL schema that Gatsby.js is using. Everything was fine until I found out that by design many fields are undefined. Take for example siteMetadata object:

{
siteMetadata:{
    siteName:'Krzysztof Żuraw',
    author:'Krzysztof Żuraw',
    description:'Krzysztof Żuraw personal site & blog',
    siteUrl:'https://krzysztofzuraw.com',
    social:{
      linkedin:'https://pl.linkedin.com/in/krzysztofzuraw',
      github:'https://github.com/krzysztofzuraw',
      email:'mailto:blog@kzuraw.com',
      pinboard:'https://pinboard.in/u:KZuraw',
      newsletter:'https://buttondown.email/krzysztof_zuraw',},}}

You can see this file here.

I tried to generate TypeScript types for this structure using GraphQL Code Generator to get:

exporttype SiteSiteMetadata ={
  __typename?:'SiteSiteMetadata';
  siteName?: Maybe<Scalars['String']>;
  author?: Maybe<Scalars['String']>;
  description?: Maybe<Scalars['String']>;
  siteUrl?: Maybe<Scalars['String']>;
  social?: Maybe<SiteSiteMetadataSocial>;};

What? All of them are undefined or null? No way - I know they will be defined in the time when I generate a static site. I asked around and Hasparus give me a hint - you can customize your GraphQL schema 🎉.

To do that I had to use createSchemaCustomization (you have to place it inside gatsby-node.js):

exports.createSchemaCustomization=({ actions })=>{const{ createTypes }= actions;const typeDefs =`
  type MarkdownRemark implements Node {
    frontmatter: Frontmatter!
  }
  type Frontmatter {
    tags: [String!]!
    title: String!
    slug: String!
    date(
      difference: String
      formatString: String
      fromNow: Boolean
      locale: String
    ): Date!
  }
  type Site implements Node {
    siteMetadata: SiteSiteMetadata!
  }
  type SiteSiteMetadata {
    siteName: String!
    author: String!
    description: String!
    siteUrl: String!
    social: SiteSiteMetadataSocial!
  }
  type SiteSiteMetadataSocial {
    linkedin: String!
    github: String!
    email: String!
    pinboard: String!
    newsletter: String!
  }
  `;createTypes(typeDefs);};

What is happening here? I added my own GraphQL types where all the fields are not nullable. Thanks to that it generated types look like follows:

exporttype SiteSiteMetadata ={
  __typename?:'SiteSiteMetadata';
  siteName: Scalars['String'];
  author: Scalars['String'];
  description: Scalars['String'];
  siteUrl: Scalars['String'];
  social: SiteSiteMetadataSocial;};

One drawback of it - right now it is on me as a developer, to make sure that all the data from e.g frontmatter will be there.

Summary

I wanted to fix autogenerated GraphQL types in Gatsby. Thanks to Hasparus suggestion I’ve used createSchemaCustomization to override guested Gatsby types.

Thank you Hasparus once again 🙇🏻‍♂️.


Viewing all articles
Browse latest Browse all 205

Trending Articles