Gatsby useStaticQuery Hook: The Quick Guide

4 min read

Gatsby useStaticQuery Hook: The Quick Guide

Previously, to fetch data in Gatsby, we were only able to do so at the page level, which meant that even if a child component nested deep in a page component needed that data, then we would need to pass the data through the component trees.

However, Gatsby V2 introduced a staticQuery API that allows data to be fetched at a component level.

Introduction

In this post, we will be looking into Gatsby new API which introduced useStaticQuery hook in V2 and how we can run multiple queries using GraphQl aliases inside components. Additionally, we will look at how to create a custom hook that can be reused in different components.

How to use useStaticQuery hook in Components

To fetch data inside a component, we need to import graphql and useStaticQuery. We then need to setup the hook inside our component by passing the GraphQL query to useStaticQuery, as you can see highlighted in the example below.

1
import { graphql, useStaticQuery } from "gatsby";
2
3
const SampleComponent = () => {
4
const data = useStaticQuery(graphql`
5
query {
6
allMdx {
7
nodes {
8
frontmatter {
9
title
10
path
11
date
12
summary
13
images
14
tags
15
}
16
timeToRead
17
}
18
}
19
}
20
`);
21
22
return <div>{/* your component logic */}</div>;
23
};

GraphQL Aliases

To run multiple queries we can use GraphQl aliases, which allow us to rename the returned dataset to anything we want. In the following example, we can see how we renamed the 2 queries to post and siteMetaData as highlighted in the code snippet.

1
import { graphql, useStaticQuery } from "gatsby";
2
3
const SampleComponent = () => {
4
const data = useStaticQuery(graphql`
5
query {
6
post: allMdx {
7
nodes {
8
frontmatter {
9
title
10
path
11
date
12
summary
13
images
14
tags
15
}
16
timeToRead
17
}
18
}
19
siteMetaData: site {
20
siteMetadata {
21
title
22
}
23
}
24
}
25
`);
26
27
return <div>{/* your component logic */}</div>;
28
};

Custom Hook

Say we have a query that we want to reuse in more than one component, we can do that by creating a custom hook that can then be imported into any component to fetch the data. This will allow reuse without the need to pass the data around as props or copying the same query in different components.

To do that, we need to import graphql and useStaticQuery. We then need to setup the custom hook by creating a function called useSiteBlogData which will return the data by using the useStaticQuery hook we imported and pass the query to it. Then we can specify how the data is returned, in this case by returning all nodes from the query as an array.

useSiteBlogdata.js

1
import { graphql, useStaticQuery } from "gatsby";
2
3
const useSiteBlogdata = () => {
4
const data = useStaticQuery(graphql`
5
query {
6
allMdx(sort: { order: DESC, fields: frontmatter___date }) {
7
nodes {
8
frontmatter {
9
title
10
path
11
date
12
summary
13
images
14
tags
15
}
16
timeToRead
17
}
18
}
19
}
20
`);
21
22
return data.allMdx.nodes;
23
};
24
25
export default useSiteBlogdata;

To use the newly created custom hook to fetch the data as follows which will return the posts array.

blog.js

1
import useSiteBlogdata from "@hooks/useSiteBlogdata";
2
3
const Blog = () => {
4
const posts = useSiteBlogdata();
5
return <div>{/* your component logic */}</div>;
6
};
7
8
export default Blog;

While useStaticQuery can do most of the things that page query can, it has a few limitations:

  • It does not accept variables (via pageContext) like page query, hence why it is called static.
  • useStaticQuery can only be used once per component, but you can run as many queries through it as you want using GraphQl aliases.

Conclusion

In this post, we looked at how to use useStaticQuery, how to run multiple queries inside a hook and how to create a custom hook to reuse in any component.

As you can see, the built-in useStaticQuery Hook in Gatsby is an extremely useful and easy-to-use feature to incorporate into your site.