Gatsby struggles with generating Contentful pages using TypeScript

I have been working on creating dynamic pages with Contentful in Gatsby + Typescript. While I am able to fetch data successfully using GraphQL in a browser, I encounter issues when trying to fetch data in gatsby-node.ts. The pages seem to be generated partially and an error message pops up:

ERROR #12100 API.TYPESCRIPT.TYPEGEN

An error occurred while attempting to generate TypeScript types from the GraphQL queries:

Error: GraphQL Document Validation failed with 1 errors;   Error 0: This anonymous operation must be the only defined operation.
at /home/ugnius/GIT/New-webpage/gatsby-node.ts:1:1

For more information about this error, you can refer to our documentation page:

failed Generating GraphQL and TypeScript types - 0.109s

gatsby-node.ts

import type { GatsbyNode } from 'gatsby';
import * as path from 'path';

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

  const request = await graphql<Queries.Query>(`
    {
      allContentfulInsight {
        edges {
          node {
            title
            slug
          }
        }
      }
    }
  `);

  const insightTemplate = path.resolve('./src/templates/Insight.tsx');
  const insights = request?.data?.allContentfulInsight.edges;

  insights?.forEach((insight, index) => {
    createPage({
      path: `insights/${insight.node.slug}`,
      component: insightTemplate,
      context: {
        slug: insight.node.slug,
      },
    });
  });
};

src/templates/Insight.tsx

import * as React from 'react';
import { graphql } from 'gatsby';

const InsightTemplate: React.FC<Queries.InsightBySlugQuery> = (data) => {
  const title = data?.contentfulInsight?.title; // => undefined
  console.log(data); // prints correct data from Contentful but it is undefined in code

  return (
    <>
      <h1>{title}</h1>
    </>
  );
};

export default InsightTemplate;

export const query = graphql`
  query InsightBySlug($slug: String!) {
    site {
      siteMetadata {
        title
      }
    }
    contentfulInsight(slug: { eq: $slug }) {
      title
      content {
        raw
      }
    }
  }
`;

gatsby-types.dts

declare namespace Queries {
  // ...
  type Query = {
    readonly allContentfulInsight: ContentfulInsightConnection;
    // ...
  };
  // ...
  type ContentfulInsightConnection = {
    readonly edges: ReadonlyArray<ContentfulInsightEdge>;
    // ...
  };
  // ...
  type ContentfulInsightEdge = {
    readonly node: ContentfulInsight;
    // ...
  };
  // ...
  type ContentfulInsight = ContentfulEntry & ContentfulReference & Node & {
    readonly slug: Maybe<Scalars['String']>;
    readonly title: Maybe<Scalars['String']>;
    readonly content: Maybe<ContentfulInsightContent>;
    // ...
  };
  // ...
  type InsightBySlugQueryVariables = Exact<{
    slug: Scalars['String'];
  }>;

  type InsightBySlugQuery = {
    readonly site: { readonly siteMetadata: { readonly title: string | null } | null } | null;
    readonly contentfulInsight: {
      readonly title: string | null;
      readonly content: { readonly raw: string | null } | null;
    } | null;
  };
}

What could possibly be causing the issue in my configuration?

Answer №1

To resolve the issue with

ERROR #12100 API.TYPESCRIPT.TYPEGEN
, make sure to update the GraphQL query in gatsby-node.ts as follows:

const request = await graphql<Queries.Query>(`
  {
    allContentfulInsight {
      edges {
        node {
          title
          slug
        }
      }
    }
  }
`);

Additionally, for fixing Insight.tsx, you must correctly define the template props:

import * as React from 'react';
import { graphql } from 'gatsby';

interface InsightTemplateProps {
  data: {
    site: {
      siteMetadata: { title: string };
    };
    contentfulInsight: {
      title: string;
      content: { raw: string };
    };
  };
}

const InsightTemplate: React.FC<InsightTemplateProps> = ({ data }) => {
  const title = data.contentfulInsight.title;

  return (
    <>
      <h1>{title}</h1>
    </>
  );
};
export default InsightTemplate;

export const query = graphql`
  query InsightBySlug($slug: String!) {
    site {
      siteMetadata {
        title
      }
    }
    contentfulInsight(slug: { eq: $slug }) {
      title
      content {
        raw
      }
    }
  }
`;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to nullify an object and utilize nullish coalescing for handling potentially undefined constants?

In my development work with React, I often utilize a props object structured like this: const props: { id: number, name?: string} = { id: 1 }; // 'name' property not defined const { id, name } = props; // the 'name' constant is now fore ...

Creating a versatile TypeScript Record that can accommodate multiple data types

I have a question regarding the use of Record in TypeScript. When I specify Record as the parameter type in a function, I encounter an error in my code because it does not allow different types. type Keys = 'name' | 'qty'; const getVal ...

Enhancing connected components in typescript with the redux dispatch method

When developing a connected component in TypeScript, I encountered an interesting design question. The issue arises with modal components, which are somewhat unique in that they are part of the DOM and are only shown or hidden. This poses a challenge where ...

Developing a Typescript "Map" type using numerical enumerations

In my Typescript project, I came across the need to create record types with numeric enums: enum AxisLabel { X = 0, Y = 1 } export const labelLookup: Record<AxisLabel, string> = { [AxisLabel.X]: "X axis", [AxisLabel.Y]: "Y Axis" }; However, I w ...

Differences in weekend start and end days vary across cultures

Looking for a solution to determine the weekend days per culture code in Typescript/Javascript? While most countries have weekends on Sat-Sun, there are exceptions like Mexico (only Sunday) and some middle-eastern countries (Fri-Sat). It would be helpful ...

The index declaration file has not been uploaded to NPM

After creating a Typescript package and publishing it on NPM, I encountered an issue with the declaration files not being included in the published version. Despite setting declaration: true in the tsconfig.json, only the JavaScript files were being publis ...

Expanding unfamiliar categories

Currently, I am working with Gutenberg blocks in a headless manner. Each Gutenberg block is defined by the following structure: type Block = { name: string; className?: string; key?: string | number; clientId: string; innerBlocks: Block ...

Utilizing activatedRoute in Angular to retrieve encoded query parameters

I am facing an issue with my Angular application, where it is loaded after being redirected from another application. I need to access query parameters when the authentication website returns to my Angular application. The URL appears as: http://localhost ...

A guide on altering the color of a badge through programming

I am curious to learn how I can dynamically change the color of a badge in Angular. My goal is to initially set the color of the badge to white, and then if the percVLRiskTotal reaches a specific value, change the color to green as an example. CSS: <sp ...

Issues with naming in Gulp, Angular2 Final, and Visual Studio: "Cannot find name" and "Duplicate identifier" errors

Recently, I updated my project to utilize the final release of Angular 2 and also upgraded Visual Studio to use TypeScript 2.0.3 from the Tool -> Extensions and Updates manager. I compile my TypeScript using Gulp, and it compiles without any errors. Ho ...

Is it possible to enter NaN in Vue3?

Is there a way to handle NaN values and keep a field blank instead when calculating margins with a formula? https://i.stack.imgur.com/JvIRQ.png Template <form> <div class="row"> <div class="mb-3 col-sm ...

Quickly retrieve product categories associated with products using GraphQL in WordPress through WPGraphQL

Currently, I am working on a headless eCommerce solution using Wordpress, Woocommerce, WooGraphQL, React, and Next. I am implementing SSG and SSR for improved SEO and performance. One area of concern for me is the performance impact of populating product ...

Encountered an error while trying to generate the Component class for the ColorlibStepIcon from Material UI in TypeScript

I am trying to convert the ColorlibStepIcon functional component into a class component for my Stepper. Unfortunately, I have not been successful and keep encountering errors. I have attempted some changes but it is still not working as expected. You can ...

Configuring the tsconfig outDir will specify where the output files will be stored

What am I missing in the tsconfig settings if I only want to output files in the root directory? If I set it as "rootDir":"src" "outDir":"build", or "rootDir":"src" "outDir":"&q ...

Angular - optional parameter in route using ngRouter

I have a question regarding using Angular (4) with the @angular/router. I want to be able to include optional parameters in a path style, but am facing some challenges. Currently, my code looks like this: { path: 'cars', component: CarComponent ...

Managing return types in functions based on conditions

Recently, I developed a function to map links originating from a CMS. However, there are instances where the link in the CMS is optional. In such cases, I need to return null. On the other hand, when the links are mandatory, having null as a return type is ...

Mapping an array in Typescript using Angular to instantiate a class

I have received data from a web API that resembles the structure below. I am looking for guidance on how to properly map the product array into individual Products. My main objective is to convert the eating_time values into JavaScript datetime format. Cu ...

Using GraphQL in React to access a specific field

Here is the code snippet I am working with: interface MutationProps { username: string; Mutation: any; } export const UseCustomMutation: React.FC<MutationProps> | any = (username: any, Mutation: DocumentNode ) => { const [functi ...

I would like to modify the text color of a disabled input field

I need to adjust the font color of V1, which is a disabled input field. I want to make it darker specifically for Chrome. Any suggestions on how I can achieve this? Here's my HTML code: <mat-form-field appearance="outline" fxFlex=" ...

Is there a TypeScript alternative to triggering a click event on a specific class using $(".class").click()?

I am currently utilizing a date range picker within an Angular project. <button type="button" class="btn btn-danger daterange-ranges"> <i class="icon-calendar22 position-left"></i> <span></span> <b class="caret"></b ...