Skip to content

Gatsby useStaticQuery Hook — Data Fetching in Any Component

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Gatsby useStaticQuery Hook. We cover key concepts, practical examples, and best practices to help you master this topic.

Learn Gatsby's useStaticQuery hook to fetch Graphql data in any component without a page-level query, enabling reusable data-driven components.

In this lesson, you'll understand how useStaticQuery works, when to use it, and how it differs from page queries.

What You'll Learn

How to use useStaticQuery in any component, query site metadata, create reusable data components, and understand the limitations of static queries.

Why It Matters

Page queries only work in page components. useStaticQuery lets any component access data, making it essential for headers, footers, SEO components, and sidebars.

flowchart LR
    A[Any Component] --> B[useStaticQuery Hook]
    B --> C[GraphQL Query]
    C --> D[Data at Build Time]
    D --> E[Component Renders]
    style B fill:#639,color:#fff

Basic useStaticQuery

Fetch site metadata in a header component:

import { graphql, useStaticQuery } from 'gatsby';
import React from 'react';

function Header() {
  const data = useStaticQuery(graphql`
    query SiteTitleQuery {
      site {
        siteMetadata {
          title
          description
        }
      }
    }
  `);

  return (
    <header>
      <h1>{data.site.siteMetadata.title}</h1>
      <p>{data.site.siteMetadata.description}</p>
    </header>
  );
}

Output: The header displays the site title and description from gatsby-config.js. The data is fetched at build time and available in every instance of the component.

useStaticQuery with Images

Create a reusable SEO image component:

import { graphql, useStaticQuery } from 'gatsby';
import { getImage, GatsbyImage } from 'gatsby-plugin-image';
import React from 'react';

function SiteLogo() {
  const data = useStaticQuery(graphql`
    query LogoQuery {
      file(relativePath: { eq: "logo.png" }) {
        childImageSharp {
          gatsbyImageData(
            width: 200
            placeholder: BLURRED
            formats: [AVIF, WEBP, AUTO]
          )
        }
      }
    }
  `);

  const image = getImage(data.file);
  return <GatsbyImage image={image} alt="Site Logo" />;
}

Output: The SiteLogo component can be placed anywhere — header, footer, sidebar. The image data is fetched once and reused across all instances.

Querying Multiple Data Sources

Combine filesystem and metadata in one query:

import { graphql, useStaticQuery } from 'gatsby';
import React from 'react';

function Footer() {
  const data = useStaticQuery(graphql`
    query FooterQuery {
      site { siteMetadata { title author } }
      allFile(
        filter: { sourceInstanceName: { eq: "content" } }
        sort: { childrenMarkdownRemark: { frontmatter: { date: DESC } } }
        limit: 5
      ) {
        nodes {
          name
          publicURL
        }
      }
    }
  `);

  return (
    <footer>
      <p>{data.site.siteMetadata.title} by {data.site.siteMetadata.author}</p>
      <ul>
        {data.allFile.nodes.map(node => (
          <li key={node.publicURL}>{node.name}</li>
        ))}
      </ul>
    </footer>
  );
}

Output: A single useStaticQuery fetches both site metadata and recent files for the footer. No prop drilling needed.

StaticQuery Limitations

Key differences from page queries:

// Page query (in page components only) — accepts variables
export const query = graphql`
  query BlogPost($slug: String!) {
    markdownRemark(fields: { slug: { eq: $slug } }) {
      html
      frontmatter { title }
    }
  }
`

// Static query (any component) — NO variables allowed
function BlogNav() {
  const data = useStaticQuery(graphql`
    query BlogNavQuery {
      allMarkdownRemark(limit: 10) {
        nodes { frontmatter { title } fields { slug } }
      }
    }
  `);
}

Output: Page queries accept variables for dynamic filtering. useStaticQuery cannot accept variables — it returns the same data every time.

Common Mistakes

  1. Using useStaticQuery inside loops or conditionals: Hooks must be called at the top level of a component. Don't call useStaticQuery inside map(), if, or useEffect.
  2. Creating duplicate queries: If a query is used in multiple components (e.g., site metadata), define it in one component and pass as props, or use a shared fragment.
  3. Forgetting to import graphql: The graphql template literal is required for queries. Without it, the string won't be parsed by Gatsby's compiler.
  4. Trying to use variables in useStaticQuery: Static queries don't support variables. Use a page query with $slug or similar for dynamic data.
  5. Over-fetching data: Query only the fields you need. Extra fields increase bundle size and build time.

Practice Questions

  1. What is the main advantage of useStaticQuery over page queries? Answer: It works in any component, not just page components. This enables reusable data-driven components like headers and footers.

  2. What limitation does useStaticQuery have compared to page queries? Answer: It cannot accept variables. The query is static and returns the same data every time.

  3. How many times is useStaticQuery evaluated per component? Answer: Once at build time. The component renders with the data without re-fetching on client navigation.

  4. Can you use useStaticQuery in non-page components? Answer: Yes. That's its primary purpose. It works in any React component.

Challenge

Create a reusable SiteMetadata component that fetches title, description, and author through useStaticQuery. Display this in the header and footer without prop drilling.

Mini Project

Build a sidebar component that uses useStaticQuery to fetch: recent blog posts (5), a tag cloud, and an author bio image. Render all three sections in the sidebar.

FAQ

Does useStaticQuery trigger re-renders on data changes?

: No. The data is fetched at build time and baked into the component. There's no runtime data fetching.

Can I use multiple useStaticQuery calls in one component?

: Yes. Each call creates a separate query. Combine them into one query for better performance if they don't need separate Caching.

Is useStaticQuery the same as StaticQuery component?

: The StaticQuery render-prop component is the older API. useStaticQuery is the modern hook version and is preferred.

Can useStaticQuery be used in layout components?

: Yes. Layout components are regular React components, so useStaticQuery works there too.

What's Next

Learn about Gatsby Page Queries for page-level data fetching and GraphQL variables for dynamic pages.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro