Categories
Gatsby.js

Gatsby.js — Display a Single Image

Gatsby is a static web site framework that’s based on React.

We can use it to create static websites from external data sources and more.

In this article, we’ll look at how to create a site with Gatsby.

Get and Display a Single Image

We can get and display a single image with Gatsby.

We use the gatsby-image to get and add an image.

To install the packages required packages, we run:

npm i gatsby-plugin-sharp gatsby-transformer-sharp

To do this, we write:

gatsby-config.js

const path = require('path');

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: path.join(__dirname, `src`, `images`),
      },
    },
    `gatsby-plugin-sharp`,
    `gatsby-transformer-sharp`,
  ],
}

Then we can get the image on our page by writing:

src/pages/index.js

import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"

const IndexPage = () => {
  const data = useStaticQuery(graphql`
    query {
      file(relativePath: { eq: "laptop.jpg" }) {
        childImageSharp {
          fluid {
            base64
            aspectRatio
            src
            srcSet
            sizes
          }
        }
      }
    }
  `)

  return (
    <div>
      <Img fluid={data.file.childImageSharp.fluid} alt="laptop" />
    </div>
  )
}
export default IndexPage

We specify that we want to get laptop.jpg in our GraphQL query.

Then we get the fields and put them into the Img component in the JSX.

We can simplify this by writing:

import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"

const IndexPage = () => {
  const data = useStaticQuery(graphql`
    query {
      file(relativePath: { eq: "laptop.jpg" }) {
        childImageSharp {
          fluid(maxWidth: 200, quality: 75) {
            ...GatsbyImageSharpFluid
          }
        }
      }
    }
  `)

  return (
    <div>
      <Img
        fluid={data.file.childImageSharp.fluid}
        alt="laptop"
        style={{ border: "2px solid purple", borderRadius: 5, height: 250 }}
      />
    </div>
  )
}
export default IndexPage

We simplify the query with the GatsbyImageSharpField fragment, which is equivalent to what we have in the previous example.

And we add the style into our Img component.

We can set the fluid prop to force an aspect ratio by overriding the aspectRatio field:

import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"

const IndexPage = () => {
  const data = useStaticQuery(graphql`
    query {
      file(relativePath: { eq: "laptop.jpg" }) {
        childImageSharp {
          fluid(maxWidth: 200, quality: 75) {
            ...GatsbyImageSharpFluid
          }
        }
      }
    }
  `)

  return (
    <div>
      <Img
        fluid={data.file.childImageSharp.fluid}
        alt="laptop"
        fluid={{
          ...data.file.childImageSharp.fluid,
          aspectRatio: 1.6,
        }}
      />
    </div>
  )
}
export default IndexPage

Also, we can set the image with a fixed-width with the following query:

import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"

const IndexPage = () => {
  const data = useStaticQuery(graphql`
    query {
      file(relativePath: { eq: "laptop.jpg" }) {
        childImageSharp {
          fixed(width: 250) {
            ...GatsbyImageSharpFixed
          }
        }
      }
    }
  `)

  return (
    <div>
      <Img fixed={data.file.childImageSharp.fixed} alt="laptop" />
    </div>
  )
}
export default IndexPage

We have the fixed field with the width set to 250.

So the image will be displayed with 250px width.

Conclusion

We can display a single image in various ways by using various queries with Gatsby.

Categories
Gatsby.js

Gatsby.js — Filtering and Images

Gatsby is a static web site framework that’s based on React.

We can use it to create static websites from external data sources and more.

In this article, we’ll look at how to create a site with Gatsby.

Filtering with GraphQL

We can filter items in our results with our GraphQL queries.

For example, we can write:

{
  allSitePage(filter: {path: {eq: "/pokemon"}}) {
    edges {
      node {
        id
        path
      }
    }
  }
}

Then we get the path that equals to to /pokemon .

eq means equals.

GraphQL Query Aliases

We can add GraphQL query aliases.

For example, we can write:

{
  fileCount: allFile {
    totalCount
  }
  filePageInfo: allFile {
    pageInfo {
      currentPage
    }
  }
}

fileCount and filePageInfo are the aliases.

And the expression after the colon are the queries.

GraphQL Query Fragments

GraphQL query fragments are shareable chunks of a query that can be reused.

For example, we can create a fragment and make a query with it by writing:

src/pages/index.js

import React from "react"
import { graphql } from "gatsby"

export const query = graphql`
  fragment SiteInformation on SiteSiteMetadata {
    title
    description
  }
`

export const pageQuery = graphql`
  query SiteQuery {
    site {
      siteMetadata {
        ...SiteInformation
      }
    }
  }
`

export default function Home({ data }) {
  return <div>{data.site.siteMetadata.title}</div>
}

We create the fragment with the query query.

We create the fragment for the SiteSiteMetadata type, which has the website’s metadata fields.

Then the pageQuery uses the fragment we just created.

Querying Data Client-Side with fetch

We can query data on the client-side with the Fetch API.

For instance, we can write:

import React, { useState, useEffect } from "react"

const IndexPage = () => {
  const [starsCount, setStarsCount] = useState(0)
  useEffect(() => {
    fetch(`https://api.github.com/repos/gatsbyjs/gatsby`)
      .then(response => response.json())
      .then(resultData => {
        setStarsCount(resultData.stargazers_count)
      })
  }, [])

  return (
    <section>
      <p>Gatsby start count: {starsCount}</p>
    </section>
  )
}
export default IndexPage

to get the number of Github stars for the Gatsby project and display it.

Images

We can add images into our Gatsby project.

For example, we can write:

src/pages/index.js

import React from "react"
import LaptopImg from "../assets/laptop.jpg"

const IndexPage = () => {
  return (
    <section>
      <img src={LaptopImg} alt="laptop" />
    </section>
  )
}
export default IndexPage

We import the image from the /assets folder and set the src prop to the imported image.

Reference an Image from the static Folder

Also, we can reference an image from the static folder by its path.

For example, we can write:

import React from "react"

const IndexPage = () => {
  return (
    <section>
      <img src={`laptop.jpg`} alt="laptop" />
    </section>
  )
}
export default IndexPage

given that we have the image in the static folder.

Optimizing and Querying Local Images with gatsby-image

We can use the gatsby-image to add an image.

To install the packages required packages, we run:

npm i gatsby-plugin-sharp gatsby-transformer-sharp

To do this, we write:

gatsby-config.js

const path = require('path');

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: path.join(__dirname, `src`, `images`),
      },
    },
    `gatsby-plugin-sharp`,
    `gatsby-transformer-sharp`,
  ],
}

Then we can get the images on our page by writing:

src/pages/index.js

import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"

const IndexPage = () => {
  const data = useStaticQuery(graphql`
    query {
      allFile(
        filter: {
          extension: { regex: "/(jpg)|(png)|(jpeg)/" }
          relativeDirectory: { eq: "" }
        }
      ) {
        edges {
          node {
            base
            childImageSharp {
              fluid {
                ...GatsbyImageSharpFluid
              }
            }
          }
        }
      }
    }
  `)

  return (
    <div>
      {data.allFile.edges.map(image => (
        <Img
          fluid={image.node.childImageSharp.fluid}
          alt={image.node.base.split(".")[0]}
        />
      ))}
    </div>
  )
}
export default IndexPage

We get the files with the allFile query.

We get the images from the src/images folder as we specified in gatsby-config.js .

Conclusion

We can filter items with GraphQL and we can get images and display them with a query with GraphQL.

Categories
Gatsby.js

Gatsby.js — Queries

Gatsby is a static web site framework that’s based on React.

We can use it to create static websites from external data sources and more.

In this article, we’ll look at how to create a site with Gatsby.

Page Query

We can query the site’s data and display it on our page.

To do this, we write:

gatsby-config.js

module.exports = {
  plugins: [],
  siteMetadata: {
    title: `Gatsby`,
    siteUrl: `https://www.gatsbyjs.com`,
    description: `Blazing fast modern site generator for React`,
  },
}

src/pages/index.js

import React from "react"
import { graphql } from "gatsby"

export const query = graphql`
  query HomePageQuery {
    site {
      siteMetadata {
        title
      }
    }
  }
`

export default function Home({ data }) {
  return <div>{data.site.siteMetadata.title}</div>
}

We set the site’s metadata in gatsby-config.js .

Then we can get the data with the graphql tag in our page.

Then in the page component, we get the data from the data prop.

Querying Data with the StaticQuery Component

We can also query data with the StaticQuery component.

This is useful for getting data on non-page components.

For example, we can write:

gatsby-config.js

module.exports = {
  plugins: [],
  siteMetadata: {
    title: `Gatsby`,
    siteUrl: `https://www.gatsbyjs.com`,
    description: `Blazing fast modern site generator for React`,
  },
}

src/pages/index.js

import React from "react"
import { StaticQuery, graphql } from "gatsby"

const NonPageComponent = () => (
  <StaticQuery
    query={graphql`
      query NonPageQuery {
        site {
          siteMetadata {
            title
          }
        }
      }
    `}
    render={(
      data
    ) => (
        <h1>
          {data.site.siteMetadata.title}
        </h1>
      )}
  />
)

export default function Home() {
  return <div>
    <NonPageComponent />
  </div>
}

We created the NonPageComponent to get the title from the site’s metadata.

We use the StaticQuery component to get the data.

Then in the render prop, we have a function that renders the title in the way we want.

Querying Data with the useStaticQuery Hook

Another way to query data is to use the useStaticQuery hook.

To do this, we write:

gatsby-config.js

module.exports = {
  plugins: [],
  siteMetadata: {
    title: `Gatsby`,
    siteUrl: `https://www.gatsbyjs.com`,
    description: `Blazing fast modern site generator for React`,
  },
}

src/pages/index.js

import React from "react"
import { useStaticQuery, graphql } from "gatsby"

const NonPageComponent = () => {
  const data = useStaticQuery(graphql`
    query NonPageQuery {
      site {
        siteMetadata {
          title
        }
      }
    }
  `)
  return (
    <h1>
      {data.site.siteMetadata.title}
    </h1>
  )
}

export default function Home() {
  return <div>
    <NonPageComponent />
  </div>
}

We call the useStaticQuery hook with our GraphQL query object, which is created from the graphql tag.

It returns the data and we can render it.

Limiting with GraphQL

We can limit the number of results returned with the GraphQL API/

To do this, we can run the following query:

{
  allSitePage(limit: 3) {
    edges {
      node {
        id
        path
      }
    }
  }
}

in http://localhost:8000/__graphql, then the results are limited to 3 entries.

Also, we can add sorting by running:

{
  allSitePage(sort: {fields: path, order: ASC}) {
    edges {
      node {
        id
        path
      }
    }
  }
}

Now we sort the path field in the response in ascending order.

Conclusion

We can query our site metadata and configure queries in various ways with Gatsby.

Categories
Gatsby.js

Gatsby.js — Render Data from WordPress and REST API

Gatsby is a static web site framework that’s based on React.

We can use it to create static websites from external data sources and more.

In this article, we’ll look at how to create a site with Gatsby.

Rendering Content form WordPress

We can render content from WordPress on our Gatsby site.

To do this, we install the gatsby-source-wordpress plugin by running:

npm install gatsby-source-wordpress

Then we add the following code into our Gatsby project:

gatsby-config.js

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-wordpress`,
      options: {
        baseUrl: `wpexample.com`,
        protocol: `https`,
        hostingWPCOM: false,
        useACF: false
      }
    },
  ]
}

The baseUrl should be set to the WordPress site’s URL.

hostingWPCOM sets whether the site is hosted on wordpress.com or self-hosted.

useACF sets whether the site uses the Advanced Custom Fields plugin.

gatsby-node.js

const path = require(`path`)
const { slash } = require(`gatsby-core-utils`)
exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions
  const result = await graphql(`
    query {
      allWordpressPost {
        edges {
          node {
            id
            slug
          }
        }
      }
    }
  `)
  const postTemplate = path.resolve(`./src/templates/post.js`)
  result.data.allWordpressPost.edges.forEach(edge => {
    createPage({
      path: edge.node.slug,
      component: slash(postTemplate),
      context: {
        id: edge.node.id,
      },
    })
  })
}

We get the data from the WordPress API by making the GraphQL query.

Then we call createPage to create the pages.

We set the path to the slug.

The component prop is set to the template path, which is src/templates/post.js

And the context has any extra data.

src/template/post.js

import React, { Component } from "react"
import { graphql } from "gatsby"
import PropTypes from "prop-types"
class Post extends Component {
  render() {
    const post = this.props.data.wordpressPost
    return (
      <>
        <h1>{post.title}</h1>
        <div dangerouslySetInnerHTML={{ __html: post.content }} />
      </>
    )
  }
}
Post.propTypes = {
  data: PropTypes.object.isRequired,
  edges: PropTypes.array,
}
export default Post
export const pageQuery = graphql`
  query($id: String!) {
    wordpressPost(id: { eq: $id }) {
      title
      content
    }
  }
`

post.js has the template component.

We render the content with post.content .

And post.title has the title.

Pulling Data from an External Source and Creating Pages without GraphQL

We can get data straight from an API and create pages from them.

To do this, we write:

gatsby-config.js

module.exports = {
  plugins: []
}

gatsby-node.js

const axios = require("axios")
const get = endpoint => axios.get(`https://pokeapi.co/api/v2${endpoint}`)
const getPokemonData = names =>
  Promise.all(
    names.map(async name => {
      const { data: pokemon } = await get(`/pokemon/${name}`)
      return { ...pokemon }
    })
  )
exports.createPages = async ({ actions: { createPage } }) => {
  const allPokemon = await getPokemonData(["mew", "ditto", "squirtle"])
  createPage({
    path: `/pokemon`,
    component: require.resolve("./src/templates/all-pokemon.js"),
    context: { allPokemon },
  })
}

all-pokemon.js

import React from "react"
export default function AllPokemon({ pageContext: { allPokemon } }) {
  return (
    <div>
      <ul>
        {allPokemon.map(pokemon => (
          <li key={pokemon.id}>
            <img src={pokemon.sprites.front_default} alt={pokemon.name} />
            <p>{pokemon.name}</p>
          </li>
        ))}
      </ul>
    </div>
  )
}

In gatsby-node.js , we get the data from the Pokemon API.

Then we create the createPages function by getting the data from the API.

And then we call createPage on the resolved value of the promise returned by getPokemonData .

We set the path for the page, the component to render the data in, and the context with the data that we want to render.

Then in src/templates/all-pokemon.js , we render the data that we get from the API.

Conclusion

We can render data from WordPress or from a REST API directly with Gatsby.

Categories
Gatsby.js

Gatsby.js — Rendering Markdown Data

Gatsby is a static web site framework that’s based on React.

We can use it to create static websites from external data sources and more.

In this article, we’ll look at how to create a site with Gatsby.

Markdown Data

We can get data from Markdown files and use them as a data source.

To do this, we install the gatsby-transformer-remark and gatsby-source-fulesystem plugins to get the Markdown files from a given folder.

We install gatsby-transformer-remark by running:

npm install gatsby-transformer-remark

And we install gatsby-source-filesystem by running:

npm install gatsby-source-filesystem

Then we write:

gatsby-config.js

/**
 * Configure your Gatsby site with this file.
 *
 * See: https://www.gatsbyjs.com/docs/gatsby-config/
 */

module.exports = {
  /* Your site config here */
  plugins: [
    `gatsby-transformer-remark`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `content`,
        path: `${__dirname}/src/content`,
      },
    },
  ]
}

src/content/hello-world.md

---
title: Hello World
date: 2020-07-10
path: /hello-world
---

hello world

We get the Markdown files from the src/content folder.

The top part is the front matter, which we’ll use to create our page.

And when we run gatsby develop and go to http://localhost:8000/__graphql, we can query the Markdown files by writing:

{
  allMarkdownRemark {
    edges {
      node {
        frontmatter {
          path
        }
      }
    }
  }
}

Then we get:

{
  "data": {
    "allMarkdownRemark": {
      "edges": [
        {
          "node": {
            "frontmatter": {
              "path": "/hello-world"
            }
          }
        }
      ]
    }
  },
  "extensions": {}
}

from the response.

Now we need to create the page from the Markdown file.

To do this, we write:

gatsby-node.js

const path = require(`path`)
exports.createPages = async ({ actions, graphql }) => {
  const { createPage } = actions
  const result = await graphql(`
    {
      allMarkdownRemark {
        edges {
          node {
            frontmatter {
              path
            }
          }
        }
      }
    }
  `)
  if (result.errors) {
    console.error(result.errors)
  }
  result.data.allMarkdownRemark.edges.forEach(({ node }) => {
    createPage({
      path: node.frontmatter.path,
      component: path.resolve(`src/templates/post.js`),
    })
  })
}

src/templates/post.js

import React from "react"
import { graphql } from "gatsby"
export default function Template({ data }) {
  const { markdownRemark } = data
  const { frontmatter, html } = markdownRemark
  return (
    <div className="blog-post">
      <h1>{frontmatter.title}</h1>
      <h2>{frontmatter.date}</h2>
      <div
        className="blog-post-content"
        dangerouslySetInnerHTML={{ __html: html }}
      />
    </div>
  )
}
export const pageQuery = graphql`
  query($path: String!) {
    markdownRemark(frontmatter: { path: { eq: $path } }) {
      html
      frontmatter {
        date(formatString: "MMMM DD, YYYY")
        path
        title
      }
    }
  }
`

In gatsby-node.js , we make the same query we made in GraphiQL.

And then we get the response and call createPage to create the page with the path to the file as defined in the Markdown’s front matter.

And the component has the template to render the front matter and content.

In post.js , we get the data from the data prop.

We get the title and date properties from the frontMatter object to get the front matter data and display them.

Then the content is in the markdownRemark.html property.

Now when we go to http://localhost:8000/hello-world, we see:

Hello World
July 10, 2020
hello world

displayed.

Conclusion

We can render data from Markdown in our Gatsby static site.