How to use Page Queries and Static Queries in Gatsby Application Using GraphQL
Tags: react, gatsby, graphql, webdev
Published: 2022-01-29 21:35:48

Gatsby is known for building blazing fast websites and apps by leveraging a combination of front-end technologies such as ReactJS, Webpack and GraphQL. It is also known for its massive ecosystem of plugins that use different kinds of plugins to pull data from different data sources into Gatsby. Once it gets the desired data, it uses GraphQL to query that data.

Gatsby is not just a static site generator that builds static websites (coding individual HTML pages and getting those pages ready to serve users ahead of time) but also a progressive app generator, where you can leverage all the static functionality and still be able to query the dynamic data (renders differently based on any number of changing data inputs, such as the user's location, time of day, or user actions.).

### There are two parts to any web app

Static
Dynamic

**Today, we will focus on the static part of a web app.**

## Static Data

Just as the name may be, it means data that is fixed. A fixed data set/data that remains the same after it's collected or websites that contain stable contents that are displayed using web pages. Examples like a product detail page. You don’t change product images or product attributes every few minutes.

In Gatsby, we can query this type of data with two types of queries. Static Query and Page Query. When building our website and apps with Gatsby, we sometimes don’t know when to use Page Query and Static Query. In this article, we will know the difference between Page Query and Static Query and when to use them.

Before we get started, let us know the meaning of the query.

> Query in programming means a question or request that is made by a user or another computer or device. For example, Google Search, the text you enter is known as query and each word is known as a keyword. In the Database a query is a field used to locate information within a database or another location.

Note: The action of performing a query can be referred to as querying. When looking something up in a database, you're querying the database.

## Static Query

Static Query is used to query data inside a component. In Gatsby, they are not dependent on an external value to fetch the data. We can use them anywhere, including on the pages. Examples like layouts and navbar. Gatsby handles Static GraphQL queries in two varieties. Static queries using the <StaticQuery /> component, and static queries using the useStaticQuery hook.

## Using Static Query Component

Gatsby v2 introduces the Static Query component <StaticQuery />, a new API that allows components to retrieve data via a GraphQL query.

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

export default function Navbar() {
  return (
    <StaticQuery
      query={graphql`
        query {
          site {
            siteMetadata {
              title
            }
          }
        }
      `}
      render={data => (
        <nav>
            <Link to='/'>{data.site.siteMetadata.title}</Link>
            <div className="links">
              <Link to="/">Home</Link>
              <Link to="/about">About</Link>
              <Link to="/projects">Projects</Link>
            </div>
        </nav>
      )}
    />
  )
}

```

## Using Static Query Hook

useStaticQuery is a hook that takes a GraphQL query and returns your data. That's it, no more Render Props necessary to use a Static Query It simplifies the use of a static query component <StaticQuery /> and makes it cleaner, brief and straight to the point.


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

export default function Navbar() {
  const data = useStaticQuery(graphql`
    {
      site{
        siteMetadata{
          title
        }
      }
    }
  `);
  const { title } = data.site.siteMetadata;
  return (
    <nav>
        <Link to="/">{title}</Link>
        <div className="links">
          <Link to="/">Home</Link>
          <Link to="/about">About</Link>
          <Link to="/projects">Projects</Link>
        </div>
    </nav>
  );
}
```
**Notice a few things here**:

- We're using another tagged template literal to pass on our query.

- We no longer need the name of the query (it was just MyQuery).

- We've added the constant for the data above the return of our JSX.

- We're using the data inside of our JSX to get the title (data.site.siteMetadata.title).

Another thing about using static query hooks is that you can create your own custom hooks that use useStaticQuery in them. For example, you need to query the site title several times in your app. Instead of a call to useStaticQuery in each component, you can extract it out to a custom hook. You can learn how to create [custom hooks](https://www.gatsbyjs.com/blog/2019-02-20-introducing-use-static-query/#:~:text=React%20Hooks%20are%20cool.,use%20state%20in%20functional%20components.) in Gatsby

## Page Query

Gatsby’s graphql tag enables page components to query data via a GraphQL query. If we want to query data for specific pages we generally opt for Page Query. For example, our About page will use a page query. Generally, we use Page Queries to dynamically generate templates/pages. For example, think of the project detail pages where you display all the details about your project on your portfolio website, if you have so many projects it means so many pages. We can do this by using createPages hook in your gatsby-node.js file. All we need is a path and a unique identifier for each Project.


```
const path = require('path');

exports.createPages = async ({ graphql, actions }) => {

    const { data } = await graphql(`
        query Projects {
            allMarkdownRemark(sort: {fields: frontmatter___date, order: DESC}) {
                nodes {
                    frontmatter {
                        slug
                    }
                }
            }
        }
    `);

    data.allMarkdownRemark.nodes.forEach(node => {
        actions.createPage({
            path: '/projects/' + node.frontmatter.slug,
            component: path.resolve('./src/templates/project-details.js'),
            context: { slug: node.frontmatter.slug }
        });
    });
};
```

Take a look at the above code. All we are doing is fetching a unique ID(slug) related to each project and its path alias for each project from a data source which in our case is a slug and that is the slug of that particular project. Then we are passing this data to our template file as a context value. We can access this value at **/src/templates/ProjectDetail.js**. Now in our **ProjectDetail** component, we can use the unique ID(slug) to query data for each project. Take a look at the code below.


```
import React from 'react';
import Layout from '../components/Layout';
import Img from 'gatsby-image';
import * as styles from '../styles/project-details.module.css';
import { graphql } from 'gatsby';

export default function ProjectDetails({ data }) {
    const { stack, title, featuredImg} = data.markdownRemark.frontmatter
    return (
        <Layout>
            <div className={styles.details}>
                <h2>{title}</h2>
                <h3>{stack}</h3>
                <div className={styles.featured}>
                    <Img fluid={featuredImg.childImageSharp.fluid} />
                </div>
            </div>
        </Layout>
    )
}
export const query = graphql`
query ProjectsDetails($slug: String) {
    markdownRemark(frontmatter: {slug: {eq: $slug}}) {
      frontmatter {
        stack
        title
        featuredImg {
          childImageSharp {
            fluid {
              ...GatsbyImageSharpFluid
            }
          }
        }
      }
    }
  }
```
We are using the slug variable to get a specific markdown file and then once we have that we are getting all the data from it and then we can access all of this data inside this **projectDetails** components. Gatsby uses the variable value at build time to generate the Project details for each project. To learn more about page queries, visit this [link](https://www.gatsbyjs.org/docs/page-query/).

## Difference between Page Query and Static Query

Page queries can accept variables (via pageContext) but can only be added to page components.
Static Query does not accept variables. This is because static queries are used inside specific components and can appear lower in the component tree including pages.
Depending on the use case, if we want to query data for specific pages we generally opt for Page Query whereas Static Query is used to query data inside a component.
A single component that's used throughout the application will use a static query, whereas a dynamic page like our About page will use a page query.

## Wrapping Up

Hope you now have a nice overview of how, when and where to use queries in your gatsby applications.

If you would like to chat or have any questions, drop them in the comments I’m always happy to talk.

Thanks for reading and happy coding!