Blazing fast modern site generator for React with GraphQL data layer and plugin ecosystem
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
GraphQL utilities, type definitions, and data layer integration for querying data from Gatsby's unified data layer.
Template tag function for defining GraphQL queries in pages, templates, and static queries.
/**
* Template tag for GraphQL queries
* @param query - GraphQL query template string
* @param args - Template literal arguments
* @returns Query string identifier for Gatsby's query processing
*/
function graphql(query: TemplateStringsArray, ...args: any[]): string;Usage Examples:
import React from "react";
import { graphql, useStaticQuery } from "gatsby";
import type { PageProps } from "gatsby";
// Page query (automatically injected as props.data)
export const query = graphql`
query BlogPostQuery($id: String!) {
markdownRemark(id: { eq: $id }) {
id
html
frontmatter {
title
date(formatString: "MMMM DD, YYYY")
tags
author {
name
avatar {
childImageSharp {
gatsbyImageData(width: 48, height: 48, placeholder: BLURRED)
}
}
}
}
excerpt(pruneLength: 160)
timeToRead
}
}
`;
// Static query with useStaticQuery hook
const SiteHeader = () => {
const data = useStaticQuery(graphql`
query SiteHeaderQuery {
site {
siteMetadata {
title
description
author
social {
twitter
github
}
}
}
logo: file(relativePath: { eq: "logo.png" }) {
childImageSharp {
gatsbyImageData(width: 200, placeholder: BLURRED)
}
}
}
`);
return (
<header>
<h1>{data.site.siteMetadata.title}</h1>
<img src={data.logo.childImageSharp.gatsbyImageData.images.fallback.src} alt="Logo" />
</header>
);
};
// Fragment definition and usage
export const AuthorFragment = graphql`
fragment AuthorInfo on Author {
name
bio
email
avatar {
childImageSharp {
gatsbyImageData(width: 100, height: 100, placeholder: BLURRED)
}
}
social {
twitter
github
linkedin
}
}
`;
// Using fragments in queries
export const AuthorPageQuery = graphql`
query AuthorPageQuery($id: String!) {
author(id: { eq: $id }) {
...AuthorInfo
posts {
id
title
slug
date
excerpt
}
}
}
`;Legacy and modern approaches to static GraphQL queries in components.
/**
* Legacy StaticQuery component - prefer useStaticQuery hook
* @deprecated Use useStaticQuery hook instead
*/
class StaticQuery<TData = any> extends React.Component<StaticQueryProps<TData>> {}
interface StaticQueryProps<TData = any> {
query: string;
render?: (data: TData) => React.ReactNode;
children?: (data: TData) => React.ReactNode;
}
/**
* Type-safe static query documents
*/
class StaticQueryDocument<TData = any> {
constructor(query: string);
data: TData;
}Usage Examples:
import React from "react";
import { StaticQuery, graphql } from "gatsby";
// Legacy StaticQuery component (deprecated)
const LegacyComponent = () => (
<StaticQuery
query={graphql`
query LegacyQuery {
site {
siteMetadata {
title
}
}
}
`}
render={(data) => <h1>{data.site.siteMetadata.title}</h1>}
/>
);
// Modern approach with useStaticQuery (preferred)
const ModernComponent = () => {
const data = useStaticQuery(graphql`
query ModernQuery {
site {
siteMetadata {
title
}
}
}
`);
return <h1>{data.site.siteMetadata.title}</h1>;
};Complete GraphQL.js library available through the gatsby/graphql import.
/**
* Complete GraphQL.js library and utilities
* Available through: import { ... } from "gatsby/graphql"
*/
// Core GraphQL types and functions from graphql-js
export {
// Type system
GraphQLSchema,
GraphQLObjectType,
GraphQLInterfaceType,
GraphQLUnionType,
GraphQLEnumType,
GraphQLInputObjectType,
GraphQLScalarType,
// Scalars
GraphQLString,
GraphQLInt,
GraphQLFloat,
GraphQLBoolean,
GraphQLID,
// List and Non-null wrappers
GraphQLList,
GraphQLNonNull,
// Execution
execute,
subscribe,
// Validation
validate,
ValidationContext,
// Language
parse,
print,
visit,
// Utilities
buildSchema,
buildClientSchema,
introspectionFromSchema,
getIntrospectionQuery,
} from "graphql";
// Additional GraphQL utilities
export {
/**
* JSON scalar type for arbitrary JSON data
*/
GraphQLJSON,
} from "graphql-compose";Usage Examples:
// gatsby-node.js - Using GraphQL.js directly
const { GraphQLObjectType, GraphQLString, GraphQLList } = require("gatsby/graphql");
exports.createSchemaCustomization = ({ actions, schema }) => {
const { createTypes } = actions;
// Create custom GraphQL type
const AuthorType = new GraphQLObjectType({
name: "Author",
fields: {
name: { type: GraphQLString },
email: { type: GraphQLString },
posts: {
type: new GraphQLList(schema.getType("BlogPost")),
resolve: async (source, args, context) => {
const { entries } = await context.nodeModel.findAll({
type: "BlogPost",
query: {
filter: { author: { id: { eq: source.id } } },
},
});
return entries;
},
},
},
});
createTypes([AuthorType]);
};
// Plugin using GraphQL utilities
const { parse, visit } = require("gatsby/graphql");
const transformQuery = (query) => {
const ast = parse(query);
const transformedAst = visit(ast, {
Field(node) {
// Transform field names
if (node.name.value === "oldField") {
return {
...node,
name: { ...node.name, value: "newField" },
};
}
},
});
return print(transformedAst);
};Type definitions for various GraphQL query contexts and results.
/**
* GraphQL function available in gatsby-node.js createPages
*/
type GraphQLFunction = <TData = any>(
query: string,
variables?: Record<string, any>
) => Promise<{
errors?: any;
data?: TData;
}>;
/**
* Page query props injected into page components
*/
interface PageQueryProps<TData = any> {
data: TData;
errors?: any;
}
/**
* Static query result from useStaticQuery
*/
type StaticQueryResult<TData = any> = TData;Frequently used GraphQL query patterns and field selections.
Usage Examples:
// Common site metadata query
const siteMetadataQuery = graphql`
query SiteMetadata {
site {
siteMetadata {
title
description
author
siteUrl
social {
twitter
github
}
}
}
}
`;
// File system queries
const allPagesQuery = graphql`
query AllPages {
allSitePage {
nodes {
path
component
componentChunkName
context {
# Context variables passed to page
}
}
}
}
`;
// Image queries with gatsby-plugin-image
const heroImageQuery = graphql`
query HeroImage {
heroImage: file(relativePath: { eq: "hero.jpg" }) {
childImageSharp {
gatsbyImageData(
width: 1200
height: 600
placeholder: BLURRED
formats: [AUTO, WEBP, AVIF]
quality: 95
)
}
}
}
`;
// Markdown/MDX queries
const blogPostsQuery = graphql`
query BlogPosts($limit: Int, $skip: Int) {
allMarkdownRemark(
limit: $limit
skip: $skip
sort: { frontmatter: { date: DESC } }
filter: { frontmatter: { published: { eq: true } } }
) {
totalCount
nodes {
id
slug
excerpt(pruneLength: 200)
frontmatter {
title
date(formatString: "MMMM DD, YYYY")
tags
featuredImage {
childImageSharp {
gatsbyImageData(width: 400, height: 200)
}
}
}
timeToRead
}
}
}
`;
// Aggregation queries
const tagStatsQuery = graphql`
query TagStats {
allMarkdownRemark {
group(field: { frontmatter: { tags: SELECT } }) {
fieldValue
totalCount
}
}
}
`;
// Filtered queries with variables
const categoryPostsQuery = graphql`
query CategoryPosts($category: String!) {
allMarkdownRemark(
filter: { frontmatter: { category: { eq: $category } } }
sort: { frontmatter: { date: DESC } }
) {
nodes {
id
title: frontmatter.title
date: frontmatter.date
slug
}
}
}
`;Reusable query fragments for consistent data fetching.
Usage Examples:
// Author information fragment
export const AuthorFragment = graphql`
fragment AuthorInfo on MarkdownRemarkFrontmatter {
author {
name
bio
avatar {
childImageSharp {
gatsbyImageData(width: 64, height: 64, placeholder: BLURRED)
}
}
social {
twitter
github
website
}
}
}
`;
// SEO fragment
export const SEOFragment = graphql`
fragment SEOData on MarkdownRemarkFrontmatter {
title
description
keywords
image {
childImageSharp {
gatsbyImageData(width: 1200, height: 630)
}
}
canonicalUrl
noindex
}
`;
// Image fragment for consistent image handling
export const ResponsiveImageFragment = graphql`
fragment ResponsiveImage on File {
childImageSharp {
gatsbyImageData(
width: 800
placeholder: BLURRED
formats: [AUTO, WEBP, AVIF]
quality: 90
)
}
}
`;
// Using fragments in queries
export const BlogPostQuery = graphql`
query BlogPost($id: String!) {
markdownRemark(id: { eq: $id }) {
id
html
excerpt
timeToRead
frontmatter {
...SEOData
...AuthorInfo
date(formatString: "MMMM DD, YYYY")
tags
featuredImage {
...ResponsiveImage
}
}
}
}
`;Common GraphQL node types available in Gatsby's data layer.
/**
* Core Gatsby node types available in GraphQL schema
*/
// Site metadata
interface Site {
siteMetadata: SiteMetadata;
buildTime: string;
pathPrefix: string;
}
// Page nodes
interface SitePage {
path: string;
component: string;
componentChunkName: string;
context: Record<string, any>;
pluginCreator: SitePlugin;
}
// File system nodes
interface File {
absolutePath: string;
relativePath: string;
name: string;
extension: string;
size: number;
birthTime: string;
modifiedTime: string;
childImageSharp?: ImageSharp;
childMarkdownRemark?: MarkdownRemark;
}
// Image processing
interface ImageSharp {
gatsbyImageData: IGatsbyImageData;
fixed: ImageSharpFixed;
fluid: ImageSharpFluid;
}
// Markdown processing
interface MarkdownRemark {
id: string;
html: string;
excerpt: string;
frontmatter: Record<string, any>;
timeToRead: number;
rawMarkdownBody: string;
}