Agent Skill
2/7/2026

graphql-query

Write and debug Gatsby GraphQL queries for this portfolio site. Use this skill when fetching painting data, images, site configuration, or any content from the data layer. Covers page queries, static queries, and schema exploration.

O
our
2GitHub Stars
1Views
npx skills add our-nature/lulutracy.com

SKILL.md

Namegraphql-query
DescriptionWrite and debug Gatsby GraphQL queries for this portfolio site. Use this skill when fetching painting data, images, site configuration, or any content from the data layer. Covers page queries, static queries, and schema exploration.

name: graphql-query description: Write and debug Gatsby GraphQL queries for this portfolio site. Use this skill when fetching painting data, images, site configuration, or any content from the data layer. Covers page queries, static queries, and schema exploration. allowed-tools: Read, Write, Edit, Bash(make dev), Bash(make clean)

Gatsby GraphQL Queries

Assist with writing and debugging GraphQL queries for this Gatsby site.

GraphQL Playground

Access the GraphQL explorer during development:

http://localhost:8000/___graphql

Use this to explore the schema and test queries.

Data Sources

This site has these data sources configured in gatsby-config.js:

SourceContentGraphQL Type
content/paintings/paintings.yamlPainting metadataallPaintingsYaml
content/paintings/images/Painting imagesallFile (filtered)
content/about/{lang}.mdAbout pages (i18n)allMarkdownRemark
content/site/site.yamlSite configsiteYaml
locales/{lang}/*.jsonUI translationsallLocale
src/images/Static imagesallFile

Common Queries

Fetch All Paintings

query AllPaintings {
  allPaintingsYaml {
    nodes {
      paintings {
        id
        title
        description
        dimensions {
          width
          height
          unit
        }
        substrate
        substrateSize {
          width
          height
          unit
        }
        medium
        year
        alt
        order
      }
    }
  }
}

Fetch Painting Images

query PaintingImages {
  allFile(
    filter: {
      sourceInstanceName: { eq: "paintingImages" }
      extension: { regex: "/(jpg|jpeg|png|webp)/" }
    }
  ) {
    nodes {
      relativePath
      childImageSharp {
        gatsbyImageData(
          width: 800
          placeholder: BLURRED
          formats: [AUTO, WEBP, AVIF]
        )
      }
    }
  }
}

Fetch About Page (with i18n)

query AboutPage($locale: String!) {
  markdownRemark(
    frontmatter: { locale: { eq: $locale } }
    fileAbsolutePath: { regex: "/content/about/" }
  ) {
    frontmatter {
      title
      artistName
      photo
      locale
    }
    html
  }
}

Fetch Site Configuration

query SiteConfig {
  siteYaml {
    site {
      name
      author
      email
      url
    }
  }
}

Fetch Single Image by Name

query SingleImage {
  file(relativePath: { eq: "logo.png" }) {
    childImageSharp {
      gatsbyImageData(width: 200, placeholder: BLURRED)
    }
  }
}

Fetch Localized Strings

query Locales($language: String!) {
  locales: allLocale(filter: { language: { eq: $language } }) {
    edges {
      node {
        ns
        data
        language
      }
    }
  }
}

Query Types

Page Queries

Used in page components. Has access to page context variables.

// src/pages/index.tsx
import { graphql, PageProps } from 'gatsby'

const IndexPage = ({ data }: PageProps<Queries.IndexPageQuery>) => {
  // Use data here
}

export const query = graphql`
  query IndexPage {
    allPaintingsYaml {
      nodes {
        paintings {
          id
          title
          dimensions {
            width
            height
            unit
          }
        }
      }
    }
  }
`

export default IndexPage

Static Queries

Used in non-page components. Cannot accept variables.

import { useStaticQuery, graphql } from 'gatsby'

const Header = () => {
  const data = useStaticQuery(graphql`
    query HeaderQuery {
      siteYaml {
        site {
          name
        }
      }
    }
  `)

  return <h1>{data.siteYaml.site.name}</h1>
}

Template Queries with Context

Used in templates created by gatsby-node.ts. Receives context variables.

// src/templates/painting.tsx
import { graphql, PageProps } from 'gatsby'

const PaintingTemplate = ({ data }: PageProps<Queries.PaintingQuery>) => {
  // data.paintingsYaml contains the specific painting
}

export const query = graphql`
  query Painting($id: String!) {
    paintingsYaml(paintings: { elemMatch: { id: { eq: $id } } }) {
      paintings {
        id
        title
        dimensions {
          width
          height
          unit
        }
        # ... other fields
      }
    }
  }
`

Image Query Options

gatsbyImageData Parameters

childImageSharp {
  gatsbyImageData(
    width: 800                    # Max width
    height: 600                   # Max height (optional)
    layout: CONSTRAINED           # FIXED, FULL_WIDTH, or CONSTRAINED
    placeholder: BLURRED          # BLURRED, DOMINANT_COLOR, TRACED_SVG, NONE
    formats: [AUTO, WEBP, AVIF]   # Output formats
    quality: 80                   # Compression quality (1-100)
    transformOptions: {
      fit: COVER                  # COVER, CONTAIN, FILL, INSIDE, OUTSIDE
      cropFocus: CENTER           # Where to crop
    }
  )
}

Layout Options

LayoutUse Case
CONSTRAINEDMost images - scales down but not up
FIXEDIcons, thumbnails with exact size
FULL_WIDTHHero images spanning container

Debugging Queries

Query Returns Empty

  1. Check source file exists and has correct format
  2. Verify gatsby-source-filesystem config in gatsby-config.js
  3. Run make clean && make dev to rebuild schema
  4. Check GraphQL playground for available fields

Field Not Found

  1. Check exact field name in playground
  2. YAML fields become camelCase in GraphQL
  3. Nested fields (like dimensions) need explicit selection of child fields

Image Not Processing

  1. Image must be in a sourced directory
  2. File extension must be supported (jpg, png, webp, etc.)
  3. Sharp must be installed: npm rebuild sharp

Combining Paintings with Images

The index page combines painting data with image files:

export const query = graphql`
  query IndexPage {
    allPaintingsYaml {
      nodes {
        paintings {
          id
          title
          alt
          dimensions {
            width
            height
            unit
          }
          # ... other fields
        }
      }
    }
    allFile(filter: { sourceInstanceName: { eq: "paintingImages" } }) {
      nodes {
        relativePath
        childImageSharp {
          gatsbyImageData(width: 800, placeholder: BLURRED)
        }
      }
    }
  }
`

// Image filename is derived from painting title (kebab-case)
// e.g., "Night Hours" → "night-hours.jpg"
const getImageForPainting = (painting, imageNodes) => {
  const expectedFilename = painting.id // id is kebab-case of title
  return imageNodes.find((node) =>
    node.relativePath.startsWith(expectedFilename)
  )
}

Schema Reference

Run this in GraphQL playground to see full schema:

{
  __schema {
    types {
      name
      fields {
        name
      }
    }
  }
}

i18n Query Patterns

For pages with i18n support, use the language from page context:

export const query = graphql`
  query AboutPage($language: String!) {
    locales: allLocale(filter: { language: { eq: $language } }) {
      edges {
        node {
          ns
          data
          language
        }
      }
    }
    markdownRemark(
      frontmatter: { locale: { eq: $language } }
      fileAbsolutePath: { regex: "/content/about/" }
    ) {
      frontmatter {
        title
        artistName
        photo
      }
      html
    }
  }
`
Skills Info
Original Name:graphql-queryAuthor:our