Categories
Gatsby.js

Gatsby.js — Videos

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.

Working with Videos

We can create our own Video component to add embedded videos.

For example, wen can write:

import React from "react"

const Video = ({ videoSrcURL, videoTitle, ...props }) => (
  <div className="video">
    <iframe
      src={videoSrcURL}
      title={videoTitle}
      allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
      frameBorder="0"
      webkitallowfullscreen="true"
      mozallowfullscreen="true"
      allowFullScreen
    />
  </div>
)

const IndexPage = () => {
  return (
    <div>
      <Video
        videoSrcURL="https://www.youtube.com/embed/Kxw2OjX0B10"
        videoTitle="Some Video"
      />
    </div >
  )
}
export default IndexPage

to add the Video component.

It renders an iframe with the embedded video.

Then in IndexPage , we set the videoSrcURL and render it.

Querying Video Data from Markdown with GraphQL

Gatsby can get a video’s URL from a Markdown file.

For example, we can write:

gatsby-config.js

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

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"

const Video = ({ videoSrcURL, videoTitle, ...props }) => (
  <div className="video">
    <iframe
      src={videoSrcURL}
      title={videoTitle}
      allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
      frameBorder="0"
      webkitallowfullscreen="true"
      mozallowfullscreen="true"
      allowFullScreen
    />
  </div>
)

export const pageQuery = graphql`
  query($path: String!) {
    markdownRemark(frontmatter: { path: { eq: $path } }) {
      html
      frontmatter {
        date(formatString: "MMMM DD, YYYY")
        path
        title
        videoSourceURL
        videoTitle
      }
    }
  }
`

export default function VlogTemplate({
  data,
}) {
  const { markdownRemark } = data
  const { frontmatter, html } = markdownRemark
  return (
    <div className="blog-post-container">
      <div className="blog-post">
        <h1>{frontmatter.title}</h1>
        <h2>{frontmatter.date}</h2>
        <Video
          videoSrcURL={frontmatter.videoSourceURL}
          videoTitle={frontmatter.videoTitle}
        />
        <div
          className="blog-post-content"
          dangerouslySetInnerHTML={{ __html: html }}
        />
      </div>
    </div>
  )
}

src/content/post.md

---
path: "/my-first-post"
date: "2020-03-27"
title: "My first blog post"
videoSourceURL: https://www.youtube.com/embed/Kxw2OjX0B10
videoTitle: "Some video"
---

hello world

In gatsby-config.js , we add the gatsby-transformer-remark and gatsby-source-filesystem plugins to read Markdown files.

Then in gatsby-node.js , we have the createPages function make a GraphQL query for the Markdown and then call createPage to create the posts from the post.js template.

The path property has the path to the post.

In src/templates/post.js , we add the VlogTemplate template to render the Markdown file.

We make the query with the pageQuery variable.

Then we get the returned data in the data prop of VlogTemplate .

And we render the front matter values that are in the frontmatter property.

html has the content.

The Video component is the one that we used before.

Now we should see the YouTube video rendered.

Conclusion

We can render videos directly with the URL or a video URL in Markdown front matter.

Categories
Gatsby.js

Gatsby.js — Static Assets

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.

Importing Assets Directly into Files

We can import images directly into component files.

For example, we can write:

import React from "react"
import laptop from "../images/laptop.jpg"

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

We import the src/images/laptop.jpg file as a module.

Then we pass that directly as the value of the src prop of our img element.

And it’ll be displayed as an image.

We can also add images with CSS:

src/pages/index.css

.laptop {
  background-image: url(../images/laptop.jpg);
  height: 200px;
  width: 200px;
}

src/pages/index.js

import React from "react"
import './index.css'

const IndexPage = () => {
  return (
    <div className='laptop'>
    </div >
  )
}
export default IndexPage

We add the laptop class with the src/images/laptop.jpg set as the background image.

In index.js , we import the CSS and apply the class to the div.

So we’ll see the image displayed as the background image.

Querying for a File in GraphQL Using gatsby-source-filesystem

We can query for a file with GraphQL queries using the gatsby-source-filesystem plugin.

To do this, we write:

gatsby-config.js

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `src`,
        path: `${__dirname}/src/`,
      },
    },
  ],
}

src/pages/index.js

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

const IndexPage = () => {
  const data = useStaticQuery(graphql`
    {
      allFile(filter: { extension: { eq: "pdf" } }) {
        edges {
          node {
            publicURL
            name
          }
        }
      }
    }
  `)

  return (
    <div>
      <ul>
        {data.allFile.edges.map((file, index) => {
          return (
            <li key={`pdf-${index}`}>
              <a href={file.node.publicURL} download>
                {file.node.name}
              </a>
            </li>
          )
        })}
      </ul>
    </div >
  )
}
export default IndexPage

We add the gatsby-source-filesystem plugin with the path property to look for.

Then in index.js , we make the query for searching for files with extension pdf .

And we get the publicURL and name and render them in the JSX.

Now we see a link for the PDF files found, and we can download them by clicking them.

Using the Static Folder

We can also add assets to the static folder in our Gatsby project.

For example, we can write:

import React from "react"

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

to render the static/laptop.jpg file in our component.

We should use the static folder when we want to include assets that are outside the bundled code.

It’s also good for storing images that need to be dynamically referenced.

Conclusion

We can import assets directly into our components and also read them with plugins with Gatsby.

Categories
Gatsby.js

Gatsby.js — Markdown to HTML and Grayscale 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.

Transforming Markdown into HTML

We can transform Markdown into HTML with Gatsby.

To do this, we use the gatsby-transformer-remark plugin.

For example, we write:

gatsby-config.js

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

pages/pandas-and-bananas.md

---
title: "Sweet Pandas Eating Sweets"
date: "2020-08-10"
---
Pandas are really sweet.

pages/index.js

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

export const query = graphql`
  query {
    allMarkdownRemark {
      totalCount
      edges {
        node {
          id
          frontmatter {
            title
            date(formatString: "DD MMMM, YYYY")
          }
          excerpt
        }
      }
    }
  }
`

const IndexPage = ({ data }) => {
  return (
    <div>
      {data.allMarkdownRemark.edges.map(({ node }) => (
        <div key={node.id}>
          <h3>{node.frontmatter.title}— {node.frontmatter.date}</h3>
          <p>{node.excerpt}</p>
        </div >
      ))}
    </div >
  )
}
export default IndexPage

We add the plugins in the gatsby-config.js file.

The plugins are added to the plugins array.

We need the gatsby-source-filesystem plugin to read the files.

The path property has the string of the path to read from.

The gatsby-transformer-remark plugin transforms Markdown into HTML.

Then in the IndexPage component, we make the query with the graphql tag to get the Markdown data,

And we get the data from the data prop.

The frontmatter property has the metadata and the excerpt property has the excerpt.

Transforming Images into Grayscale Using GraphQL

Also, we can transform images into grayscale with a GraphQL query.

To do this, we write:

gatsby-config.js

const path = require('path');

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

index.js

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

export const query = graphql`
  query {
    file(relativePath: { eq: "images/laptop.jpg" }) {
      childImageSharp {
        fluid(grayscale: true) {
          ...GatsbyImageSharpFluid
        }
      }
    }
  }
`

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

We add the gatsby-transformer-sharp and gatsby-plugin-sharp plugins to let us transform the images.

The gatsby-source-filesystem plugin lets us read the images from the file system.

Then in index.js , we make the query to transform the image into grayscale.

We set grayscale to true to let us transform the image to a grayscale one.

We pass in the transformed image as the value of the fluid prop.

Now we should see a grayscale image displayed.

Conclusion

We can transform Markdown to HTML and transform images to grayscale with Gatsby.

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.