Using UseStaticQuery Hook in a Gatsby Site

Note: This post is part 2 of three-parts Understanding react hooks post series. This learning post is still in active development and updated regularly.

In the previous learning post (part 1 in this series), an overview of three basic react hooks: useState(), useEffect() and useContext() was discussed with simple use case examples.

Learning series
Part 1: React Hooks – An Overview
Part 2: Using UseStaticQuery Hook in a Gatsby Site (this post)
Part 3: Using React Context API in Gatsby site

The objective this part 2 of this learning series is to get an overview of how UseStaticQuery React hook is used in a Gatsby Site.

Using Gatsby useStaticQuery Hook

The react hooks were introduced in Gatsbyjs v2.1.0 as a new Gatsby feature. The newly introduced useStaticQuery feature allows to query with GraphQL at build time. The Gatsby blog describes the useStaticQuery as follows:

  • The useStaticQuery hook takes a GraphQL query and returns your data, without the use of render prop.
  • Because there is no more Render Props necessary to use a Static Query, thus simplifying data access in components.
Installing Working Example Site

To start fresh, a new site named ‘hello-plugin‘ was setup with the Gatsby default starter hello-world as described previously.

Starting Point

As a starting point, the site setup described in the An Overview of Gatsby Plugins & GraphQL post was used. Using the site’s setup the Header and Layout components were refactored using Gatsby’s useStaticQuery hook as described below.

Step 1: Editing gatsby-config.js File
//gatsby-config.js
module.exports = {
  siteMetadata: {
    title: `Gatsby Default`,
    pagetitle: `Title from siteMetadata`,
    description: `Start your Gatsby project with this default starter.`,
    author: `TinjureWP`,
    phone: `(123) 456-6789`,
    email: `info@mysite.com`,
  }
// ..
}

The site metadata property objects described above will be used below in Step 4 to create a UseSiteMetadata component.

Step 2: Refactoring Header Component

The Header.js component described in the or starting point site also references hook version – useStaticQuery to site title data stored at siteMetadata object by referencing in src/components/header.js component, as described in the Gatsby tutorial. In the example below the useStaticQuery section is refactored by creating custom hook (Step 4).

// src/components/header.js
import React from "react"
import { Link } from "gatsby"
import useSiteMetadata from '../components/siteMetadata';
import "../styles/header.css"

export default ( ) => {
  const { title } = useSiteMetadata();

    return (
      <section className="header">
      <div className="site-title wrapper">
        <Link to="/">
          <h3>{title}</h3>
        </Link>
        <ul className="menu">
          <Link to="/">Home</Link>
          <Link to="/about/">About</Link>
          <Link to="/resources/">Resources</Link>
          <Link to="/contact/">Contact</Link>
        </ul>
      </div>
      </section>
    )
}
Step 3: Refactoring Layout  Component

Because in the example used in this learning post refers  useStaticQuery from site title data stored at siteMetadata object the useSiteMetadata hook should be imported in the Layout component (line 4).

// src/components/layout.js
import React from "react"
import PropTypes from "prop-types"
import useSiteMetadata from '../components/siteMetadata';

import Header from "./header"
import Footer from "./footer"
import "../styles/layout.css"
import "../styles/main.css"

const Layout = ({ children }) => {
  const { title } = useSiteMetadata();
    
  return (
    <section>
      <Header siteTitle={title} />
      <div className="site-main">
       <div className="site-content">
        {children}
       </div>
      </div>
      <Footer />
    </section>
  )
}

Layout.propTypes = {
  children: PropTypes.node.isRequired,
}

export default Layout

Just like in the previous section ( header.js ) the useSiteMetadata hook was imported & used, the same could be done here in Layout component and re-used again (lines: 12 & 16).

Step 4: Creating custom SiteMetaData Component

The useSiteMetaData hook described in Step 2 looks like below:

// src/components/siteMetadata.js
import { graphql, useStaticQuery } from "gatsby"

const siteMetadata = () => {
  const { site } = useStaticQuery(
    graphql`
      query siteMetadata {
        site {
          siteMetadata {
            title
            pagetitle
            description
            author
            phone
            email
          }
        }
      }
    `
   )
  return site.siteMetadata
}

export default siteMetadata

The above re-usable useSiteMetadata hook can be used in as many as components by reverencing in required fields (lines: 10-15) in useStaticQuery as cons / var as shown below in About page (Step 5) and Contact page (step 6).

Step 5: Refactoring about.js component

In the example below the useSiteMetadata hook is imported first in the about.js component (line 4).

// src/pages/about.js
import React from "react"
import { Link } from "gatsby"
import useSiteMetadata from '../components/siteMetadata';
import Layout from "../components/layout"

export default () => {
  const { pagetitle } = useSiteMetadata();
   return (
  <Layout>
    <SEO title="Page two" />
    <h1 className="page-title">This {pagetitle}</h1>  
    <p>Content for about page. A react way!</p>
    <img src="https://source.unsplash.com/600x300/?cat" alt="" />
    <Link to="/">Go back to the homepage</Link>
  </Layout>
   )
}

In the example above, pagetitle field in useStaticQuery stored as const in line 8 and reference in line 12 as variable.

Step 6: Viewing <About /> Page in A browser

Restart the development server and open up the browser at localhost:8000 and view output from above queries.

Screenshot showing result about page with useStaticQuery to display site title data from siteMetadata.
Step 7: Adding siteMetadata Hook to contact.js Component

Just like in the previous section (Step 6), the useSiteMetadata hook is imported first (line 4), and the metadata fields phone & email were similarly used as shown below:

//src/pages/contact.js
import React from "react"
import { Link } from "gatsby"
import useSiteMetadata from '../components/siteMetadata';

import Layout from "../components/layout"
import SEO from "../components/seo"

const Contact = () => {
  const { phone, email } = useSiteMetadata();
  return (
  <Layout>
    <SEO title="contact us" />
    <h1 className="page-title">Contact Us</h1>
    <p>Welcome! We can be reached through this page</p>
    <p>Phone: {phone}</p>
    <p>Email: <a href={`mailto:${email}`}>{email}</a></p>
    <Link to="/">Go back to the homepage</Link>
  </Layout>
  )
}

export default Contact
Step 8: Viewing Contact Page in Browser

Restart the development server and open up the browser at localhost:8000 and view output from above queries.

Screenshot showing result of contact page with useStaticQuery to display phone & email data from siteMetadata.
Wrapping up

In this Part 2 of this learning note post series, using useStaticQuery react hook in react site with simple use case examples were discussed. In the next a simple case of using Context API in Gatsby site will be discussed.

Next Post: Using Context API in Gatsby site

Useful Resources

While preparing this post, I have referred the following references extensively. Please refer to original posts for more detailed information.