One place for hosting & domains

      Gatsby

      How To Boost SEO Using Gatsby’s SEO Component and Gatsby React Helmet


      The author selected /dev/color to receive a donation as part of the Write for DOnations program.

      Introduction

      When a user codes and deploys a website, they often want an online audience to find and read the website they’ve created. Search engine optimization (SEO) is the practice of making a website discoverable by this online audience. Optimizing search involves making changes to your Gatsby app so that it will show up in the results for search engines like Google, Bing, and DuckDuckGo. This is often done by fine-tuning the metadata that ends up in the HTML for your site.

      In this tutorial, you will configure Gatsby’s SEO component that comes with SEO tooling right out of the box. You will add meta tags to your site using Gatsby React Helmet. Meta tags are important because they give search engines information about your site. Usually the better understanding Google has about your site, the more accurately it can index your webpage. You will also create social media cards for Twitter, and Open Graph meta tags in Facebook. There are over one billion people using some form of social media, so optimizing for social media is an efficient way to get your website in front of many internet users.

      Prerequisites

      Step 1 — Creating an Empty Project

      In this section, you are going to create a new project based on the Gatsby starter default template. You are going to create a whale-watching website, and in the following steps you will improve its SEO. This will give you a solid project that you can optimize with meta tags and social media assets.

      First, use the CLI tool to start a new project named gatsby-seo-project:

      • gatsby new gatsby-seo-project https://github.com/gatsbyjs/gatsby-starter-default

      This creates a new website from the starter template in the gatsby-starter-default GitHub repository from Gatsby.

      Once the project is created, move into the src/images folder of the project:

      • cd gatsby-seo-project/src/images

      Once you are in the images folder, download a picture of a whale from the stock photography website Unsplash:

      • wget 'https://unsplash.com/photos/JRsl_wfC-9A/download?force=true&w=640'

      Wget is a Gnu command that downloads files from the internet.

      Next, list all of the images in the same images directory with the ls command:

      You will receive the following output:

      Output

      'download?force=true&w=640' gatsby-astronaut.png gatsby-icon.png

      'download?force=true&w=640' is a hard name to remember, so rename it to whale-watching.png:

      • mv 'download?force=true&w=640' whale-watching.png

      Now that you have your whale image, go to the root of your project and open src/pages/index.js. Make the highlighted change in the following code to customize your website:

      gatsby-seo-project/src/pages/index.js

      import * as React from "react"
      import { Link } from "gatsby"
      import { StaticImage } from "gatsby-plugin-image"
      
      import Layout from "../components/layout"
      import SEO from "../components/seo"
      
      const IndexPage = () => (
        <Layout>
          <SEO title="Home" />
          <h1>Whale watching for all</h1>
          <p>Come see extraordinary whales!</p>
          <StaticImage
            src="https://www.digitalocean.com/community/tutorials/images/whale-watching.png"
            width={300}
            quality={95}
            formats={["AUTO", "WEBP", "AVIF"]}
            alt="A surfacing whale"
            style={{ marginBottom: `1.45rem` }}
          />
          <p>
            <Link to="/page-2/">Go to page 2</Link> <br />
            <Link to="/using-typescript/">Go to "Using TypeScript"</Link>
          </p>
        </Layout>
      )
      
      export default IndexPage
      

      Save the file. To try out the code, start a local development server with the following command:

      Once the server is running, check localhost:8000 in your browser. You will find your new site rendered in the browser:

      Gatsby site with whale image and text.

      You are now finished setting up your project. Next, you will add meta tags to your site header with React Helmet.

      Step 2 — Creating an SEO Component with React Helmet

      In this section, you are going to learn how to control the technical SEO aspects of your site with the help of Gatsby’s React Helmet plugin and an SEO component. The Helmet plugin provides server side rendering to all of the metadata found in the head of the Gatsby site. This is important because, without server side rendering, there is a chance that server engine bots might not be able to scrape and record metadata before the site is rendered, making it more difficult to index the site for search.

      When you use gatsby-starter-default as a base for your website, it already comes with everything you need to start tweaking SEO. To do this, you will be working with the following files:

      • gatsby-config.js: Gatsby config includes metadata values that GraphQL will query and place in the SEO file.

      • src/components/seo.js: This file contains the Helmet and the SEO component.

      You are first going to open the gatsby-config.js file, which is located at the root of your project:

      Before you make any changes to the file, examine the plugins key in the exported object. The Gatsby default starter already has the Helmet plugin installed, as shown in the following highlighted line:

      gatsby-seo-project/gatsby-config.js

      module.exports = {
        siteMetadata: {
          title: `Gatsby Default Starter`,
          description: `Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.`,
          author: `@gatsbyjs`,
        },
        plugins: [
          `gatsby-plugin-react-helmet`,
          `gatsby-plugin-image`,
          {
            resolve: `gatsby-source-filesystem`,
            options: {
              name: `images`,
              path: `${__dirname}/src/images`,
            },
          },
          `gatsby-transformer-sharp`,
          `gatsby-plugin-sharp`,
          {
            resolve: `gatsby-plugin-manifest`,
            options: {
              name: `gatsby-starter-default`,
              short_name: `starter`,
              start_url: `/`,
              background_color: `#663399`,
              theme_color: `#663399`,
              display: `minimal-ui`,
              icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
            },
          },
          `gatsby-plugin-gatsby-cloud`,
          // this (optional) plugin enables Progressive Web App + Offline functionality
          // To learn more, visit: https://gatsby.dev/offline
          // `gatsby-plugin-offline`,
        ],
      }
      

      Next, direct your attention to the siteMetadata key. This contains an object that holds the metadata for your site. You are going to change the title, the description, and the author. You will also add keywords to help users search for your site:

      gatsby-seo-project/gatsby-config.js

      module.exports = {
        siteMetadata: {
          title: `Wondrous World of Whale Watching`,
          description: `Come and enjoy an experience of a lifetime! Watch whales with us!`,
          author: `@digitalocean`,
          keywords: `whales, marine life, trip, recreation`,
        },
      ...
      

      The keywords metadata is instrumental in optimizing for search. While the topic of choosing keywords is beyond the scope of this tutorial, you can learn more about the basics of SEO at Google’s search documentation website. Here you have added specific search terms that users might use when searching for a site like the sample whale-watching site.

      Save and close this file.

      Next, proceed to open the SEO component:

      • nano src/components/seo.js

      There is a lot going on in the SEO component. Focus your attention on the SEO function. In this function you are using GraphQL to query the siteMetadata object. Remember that you have added keywords to your siteMetadata object, so make the following highlighted change to your query:

      gatsby-seo-project/src/components/seo.js

      ...
      function SEO({ description, lang, meta, title}) {
        const { site } = useStaticQuery(
          graphql`
            query {
              site {
                siteMetadata {
                  title
                  description
                  author
                  keywords
                }
              }
            }
          `
        )
      ...
      

      Below the SEO function, add a reference to this queried data in a keywords constant to make the data easier to work with:

      gatsby-seo-project/src/components/seo.js

      ...
        const keywords = site.siteMetadata.keywords
        const metaDescription = description || site.siteMetadata.description
        const defaultTitle = site.siteMetadata?.title
      ...
      

      The variable keywords has all of the keywords you created in the gatsby-config.js file. The variable metaDescription is a description that you can pass as a prop on a page or query from the siteMetadata object in gatsby-config.js. Finally, defaultTitle is set to the value of title in the siteMetadata object. The ? in the siteMetadata attribute checks for a null value and returns undefined for a null or nullish value.

      Next, inspect what the SEO component is returning, and add an object for keywords:

      gatsby-seo-project/src/components/seo.js

      ...
        return (
          <Helmet
            htmlAttributes={{
              lang,
            }}
            title={title}
            titleTemplate={defaultTitle ? `%s | ${defaultTitle}` : null}
            meta={[
              {
                name: `description`,
                content: metaDescription,
              },
              {
                name: `keywords`,
                content: keywords,
              },
              {
                property: `og:title`,
                content: title,
              },
              {
                property: `og:description`,
                content: metaDescription,
              },
              {
                property: `og:type`,
                content: `website`,
              },
              {
                name: `twitter:card`,
                content: `summary`,
              },
              {
                name: `twitter:creator`,
                content: site.siteMetadata?.author || ``,
              },
              {
                name: `twitter:title`,
                content: title,
              },
              {
                name: `twitter:description`,
                content: metaDescription,
              },
            ].concat(meta)}
          />
        )
      ...
      

      You are returning a Helmet component. Helmet populates the head of an HTML document using server side rendered data, which makes it easier for Google to crawl and record the metadata. htmlAttributes={{lang,}} specifies the language of the element’s content, and title is the title found in the metadata, which comes from siteMetadata. titleTemplate creates the title tag, which is important, since Google penalizes sites that are missing a title tag.

      After this section, you’ll find the meta object, which contains the metadata. Most of the values here come from siteMetadata.

      Finally, examine the SEO.defaultProps and SEO.propTypes objects:

      gatsby-seo-project/src/components/seo.js

      ...
      SEO.defaultProps = {
        lang: `en`,
        meta: [],
        description: ``,
      }
      
      SEO.propTypes = {
        description: PropTypes.string,
        lang: PropTypes.string,
        meta: PropTypes.arrayOf(PropTypes.object),
        title: PropTypes.string.isRequired,
      }
      

      SEO.defaultProps are the default values of the SEO props. SEO.propTypes passes the correct value type and acts as a light typing system.

      Save your file with the new keywords entry and start the local server in your terminal:

      After the server has starter, enter localhost:8000 in the browser. Open up the view of the HTML in your browser; for Chrome, right click the window and open DevTools. Choose Elements and open the <head></head> tag. In this tag, you will find the following line:

      ...
      <meta name="keywords" content="whales, marine life, trip, recreation" data-react-helmet="true">
      ...
      

      You have now successfully set the header data with React Helmet.

      In this section, you created metadata to improve the SEO of your whale-watching site. In the next section, you’ll add an image and make this site easier to share on social media.

      Step 3 — Adding Images to Enhance Social Sharing

      Social networks play an important role in attracting attention to your content. In this section, you are going to add an image to two features that optimize sharing your site on social: your Twitter card and the Open Graph protocol for Facebook. You will also learn which tools to use to ensure that your metadata is appearing on these two social network platforms.

      Open up gatsby-config in a text editor:

      You are going to add images/whale-watching.png into the siteMetadata:

      gatsby-seo-project/gatsby-config.js

      module.exports = {
        siteMetadata: {
          title: `Wondrous World of Whale Watching`,
          description: `Come and enjoy an experience of a lifetime! Watch whales with us!`,
          author: `@digitalocean`,
          keywords: `whales, marine life, trip, recreation`,
          image: `src/images/whale-watching.png`
        },
        plugins: [
          `gatsby-plugin-react-helmet`,
          `gatsby-plugin-image`,
          {
            resolve: `gatsby-source-filesystem`,
            options: {
              name: `images`,
              path: `${__dirname}/src/images`,
            },
          },
          `gatsby-transformer-sharp`,
          `gatsby-plugin-sharp`,
          {
            resolve: `gatsby-plugin-manifest`,
            options: {
              name: `gatsby-starter-default`,
              short_name: `starter`,
              start_url: `/`,
              background_color: `#663399`,
              theme_color: `#663399`,
              display: `minimal-ui`,
              icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
            },
          },
          `gatsby-plugin-gatsby-cloud`,
          // this (optional) plugin enables Progressive Web App + Offline functionality
          // To learn more, visit: https://gatsby.dev/offline
          // `gatsby-plugin-offline`,
        ],
      }
      

      GraphQL will now be able to query the image. Close and save the file.

      Next, open up seo.js in the text editor:

      • nano src/components/seo.js

      Now that your image is in the site metadata, it’s time to add it to the SEO component. Add the following highlighted lines to seo.js:

      gatsby-seo-project/src/components/seo.js

      ...
      function SEO({ description, lang, meta, title}) {
        const { site } = useStaticQuery(
          graphql`
            query {
              site {
                siteMetadata {
                  title
                  description
                  author
                  keywords
                  image
                }
              }
            }
          `
        )
        const image = site.siteMetadata.image
        const keywords = site.siteMetadata.keywords
        const metaDescription = description || site.siteMetadata.description
        const defaultTitle = site.siteMetadata?.title
      
        return (
          <Helmet
            htmlAttributes={{
              lang,
            }}
            title={title}
            titleTemplate={defaultTitle ? `%s | ${defaultTitle}` : null}
            meta={[
              {
                name: `description`,
                content: metaDescription,
              },
              {
                name: `keywords`,
                content: keywords,
              },
              {
                property: `og:title`,
                content: title,
              },
              {
                property: `og:description`,
                content: metaDescription,
              },
              {
                property: `og:type`,
                content: `website`,
              },
              {
                property: `og:image`,
                content: image,
              },
              {
                name: `twitter:card`,
                content: `summary`,
              },
              {
                name: `twitter:image`,
                content: image,
              },
              {
                name: `twitter:creator`,
                content: site.siteMetadata?.author || ``,
              },
              {
                name: `twitter:title`,
                content: title,
              },
              {
                name: `twitter:description`,
                content: metaDescription,
              },
            ].concat(meta)}
          />
        )
      }
      
      SEO.defaultProps = {
        lang: `en`,
        meta: [],
        description: ``,
      }
      
      SEO.propTypes = {
        description: PropTypes.string,
        image: PropTypes.string,
        lang: PropTypes.string,
        meta: PropTypes.arrayOf(PropTypes.object),
        title: PropTypes.string.isRequired,
      }
      
      export default SEO
      

      In this code, you:

      • Added the image to the GraphQL query
      • Created an image variable and set the value to the image found in siteMetadata
      • Added og:image to the meta object
      • Added twitter:image to the meta object
      • Added image to SEO.propTypes

      Save your changes and close seo.js.

      The final step in this process is to test these changes on Twitter and Facebook. This cannot be done from a local development server; in order to test your site, you must first deploy it. There are many ways to do this, including using DigitalOcean’s App Platform, which you can read about in the How To Deploy a Gatsby Application to DigitalOcean App Platform tutorial.

      This tutorial will use a Gatsby app hosted on App Platform as an example. You can find this app at https://digital-ocean-gatsby-seo-xkmfq.ondigitalocean.app/, and it includes the SEO changes you made to your site in this tutorial.

      If you want to test if social media objects show up on Twitter, head over https://cards-dev.twitter.com/validator. This validator is maintained by Twitter, and requires a Twitter account to use. Put the URL for the sample deployed site into the validator:

      Twitter card validator

      Notice that the custom image will now show when users tweet about your website.

      Next, head over to Facebook’s Open Graph validator at https://developers.facebook.com/tools/debug/. This is maintained by Facebook, and requires a Facebook account to use. Add the URL for the sample app into the URL field. The debugger will provide you with more detail about which og objects are present and which ones are missing:

      Facebook open graph validator

      Notice that the image appears with a title and a description in the Link Preview section.

      You’ve now added an image to your metadata, a Twitter card, and a Facebook Open Graph.

      Conclusion

      In this tutorial, you boosted the SEO of your site using Gatsby’s React Helmet and the SEO component. You’ve also learned how to add images to social media cards to make your site more shareable.

      With the basics of SEO covered, you can now read more about optimizing search for Gatsby at the official Gatsby documentation.





      Source link

      How To Deploy a Gatsby Application to DigitalOcean App Platform


      The author selected /dev/color to receive a donation as part of the Write for DOnations program.

      Introduction

      In this tutorial, you will deploy a Gatsby application to DigitalOcean’s App Platform. App Platform is a Platform as a Service that builds, deploys, and manages apps automatically. When combined with the speed of a static site generator like Gatsby, this provides a scalable JAMStack solution that doesn’t require server-side programming.

      In this tutorial, you will create a sample Gatsby app on your local machine, push your code to GitHub, then deploy to App Platform.

      Prerequisites

      Step 1 — Creating a Gatsby Project

      In this section, you are going to create a sample Gatsby application, which you will later deploy to App Platform.

      First, clone the default Gatsby starter from GitHub. You can do that with the following command in your terminal:

      • git clone https://github.com/gatsbyjs/gatsby-starter-default

      The Gatsby starter site provides you with the boilerplate code you need to start coding your application. For more information on creating a Gatsby app, check out How To Set Up Your First Gatsby Website.

      When you are finished with cloning the repo, cd into the gatsby-starter-default directory:

      • cd gatsby-starter-default

      Then install the Node dependencies:

      After you’ve downloaded the app and installed the dependencies, open the following file in a text editor:

      You have just opened Gatsby’s config file. Here you can change metadata about your site.

      Go to the title key and change Gatsby Default Starter to Save the Whales, as shown in the following highlighted line:

      gatsby-starter-default/gatsby-config.js

      module.exports = {
        siteMetadata: {
          title: `Save the Whales`,
          description: `Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.`,
          author: `@gatsbyjs`,
        },
        plugins: [
          `gatsby-plugin-react-helmet`,
          {
            resolve: `gatsby-source-filesystem`,
            options: {
              name: `images`,
              path: `${__dirname}/src/images`,
            },
          },
          `gatsby-transformer-sharp`,
          `gatsby-plugin-sharp`,
          {
            resolve: `gatsby-plugin-manifest`,
            options: {
              name: `gatsby-starter-default`,
              short_name: `starter`,
              start_url: `/`,
              background_color: `#663399`,
              theme_color: `#663399`,
              display: `minimal-ui`,
              icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
            },
          },
          // this (optional) plugin enables Progressive Web App + Offline functionality
          // To learn more, visit: https://gatsby.dev/offline
          // `gatsby-plugin-offline`,
        ],
      }
      

      Close and save the file. Now open the index file in your favorite text editor:

      To continue with the “Save the Whales” theme, replace Hi people with Adopt a whale today, change Welcome to your new Gatsby site. to Whales are our friends., and delete the last <p> tag:

      gatsby-starter-default/src/pages/index.js

      import React from "react"
      import { Link } from "gatsby"
      import { StaticImage } from "gatsby-plugin-image"
      
      import Layout from "../components/layout"
      import SEO from "../components/seo"
      
      const IndexPage = () => (
        <Layout>
          <SEO title="Home" />
          <h1>Adopt a whale today</h1>
          <p>Whales are our friends.</p>
          <StaticImage
            src="https://www.digitalocean.com/community/tutorials/images/gatsby-astronaut.png"
            width={300}
            quality={95}
            formats={["AUTO", "WEBP", "AVIF"]}
            alt="A Gatsby astronaut"
            style={{ marginBottom: `1.45rem` }}
          />
          <Link to="/page-2/">Go to page 2</Link> <br />
          <Link to="/using-typescript/">Go to "Using TypeScript"</Link>
        </Layout>
      )
      
      export default IndexPage
      

      Save and close the file. You are going to swap out the Gatsby astronaut image with a GIF of a whale. Before you add the GIF, you will first need to create a GIF directory and download it.

      Go to the src directory and create a gifs file:

      Now navigate into your newly created gifs folder:

      Download a whales GIF from Giphy:

      • wget https://media.giphy.com/media/lqdJsUDvJnHBgM82HB/giphy.gif

      Wget is a utilty that allows you to download files from the internet. Giphy is a website that hosts GIFs.

      Next, change the name from giphy.gif to whales.gif:

      After you have changed the name of the GIF, move back to the root folder of the project and open up the index file again:

      • cd ../..
      • nano src/pages/index.js

      Now you will add the GIF to your site’s homepage. Delete the StaticImage import and element, then replace with the following highlighted lines:

      gatsby-starter-default/src/pages/index.js

      import React from "react"
      import { Link } from "gatsby"
      
      import whaleGIF from "../gifs/whales.gif"
      import Layout from "../components/layout"
      import SEO from "../components/seo"
      
      const IndexPage = () => (
        <Layout>
          <SEO title="Home" />
          <h1>Adopt a whale today</h1>
          <p>Whales are our friends.</p>
          <div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
              <img src={whaleGIF} alt="Picture of Whale from BBC America" />
          </div>
          <Link to="/page-2/">Go to page 2</Link> <br />
          <Link to="/using-typescript/">Go to "Using TypeScript"</Link>
        </Layout>
      

      Here you imported the whales GIF and included it in an image tag between the <div> element. The alt tag informs the reader where the GIF originated.

      Close and save the index file.

      Now you will run your site locally to make sure it works. From the root of your project, run the development server:

      After your site has finished building, put localhost:8000 into your browser’s search bar. You will find the following rendered in your browser:

      Front page of a Save the Whales website

      In this section, you created a sample Gatsby app. In the next section, you are going to push your code to GitHub so that it is accessible to App Platform.

      Step 2 — Pushing Your Code to GitHub

      In this section of the tutorial, you are going to commit your code to git and push it up to GitHub. From there, DigitalOcean’s App Platform will be able to access the code for your website.

      Go to the root of your project and create a new git repository:

      Next, add any modified files to git:

      Finally, commit all of your changes to git with the following command:

      • git commit -m "Initial Commit"

      This will commit this version of your app to git version control. The -m takes a string argument and uses it as a message about the commit.

      Note: If you have not set up git before on this machine, you may receive the following output:

      *** Please tell me who you are.
      
      Run
      
        git config --global user.email "you@example.com"
        git config --global user.name "Your Name"
      
      to set your account's default identity.
      Omit --global to set the identity only in this repository.
      

      Run the two git config commands to provide this information before moving on. If you would like to learn more about git, check out our How To Contribute to Open Source: Getting Started with Git tutorial.

      You will receive output like the following:

      Output

      [master 1e3317b] Initial Commit 3 files changed, 7 insertions(+), 13 deletions(-) create mode 100644 src/gifs/whales.gif

      Once you have committed the file, go to GitHub and log in. After you log in, create a new repository called gatsby-digital-ocean-app-platform. You can make the repository either private or public:

      Creating a new github repo

      After you’ve created a new repo, go back to the command line and add the remote repo address:

      • git remote set-url origin https://github.com/your_name/gatsby-digital-ocean-app-platform

      Make sure to change your_name to your username on GitHub.

      Next, declare that you want to push to the main branch with the following:

      Finally, push your code to your newly created repo:

      Once you enter your credentials, you will receive output similar to the following:

      Output

      Counting objects: 3466, done. Compressing objects: 100% (1501/1501), done. Writing objects: 100% (3466/3466), 28.22 MiB | 32.25 MiB/s, done. Total 3466 (delta 1939), reused 3445 (delta 1926) remote: Resolving deltas: 100% (1939/1939), done. To https://github.com/your_name/gatsby-digital-ocean-app-platform * [new branch] main -> main Branch 'main' set up to track remote branch 'main' from 'origin'.

      You will now be able to access your code in your GitHub account.

      In this section you pushed your code to a remote GitHub repository. In the next section, you will deploy your Gatsby app from GitHub to App Platform.

      Step 3 — Deploying your Gatsby App on DigitalOcean App Platform

      In this step, you are going to deploy your app onto DigitalOcean App Platform. If you haven’t done so already, create a DigitalOcean account.

      Open your DigitalOcean control panel, select the Create button at the top of the screen, then select Apps from the dropdown menu:

      Go to drop down menu and select Apps

      After you have selected Apps, you are going to retrieve your repository from GitHub. Click on the GitHub icon and give DigitalOcean permission to access your repositories. It is a best practice to only select the repository that you want deployed.

      Choose the repo you want deployed

      You’ll be redirected back to DigitalOcean. Go to the Repository field and select the project and branch you want to deploy, then click Next:

      Selecting your GitHub repository on the DigitalOcean website

      Note: Below Branch there is a pre-checked box that says Autodeploy code changes. This means if you push any changes to your GitHub repository, DigitalOcean will automatically deploy those changes.

      On the next page you’ll be asked to configure your app. In your case, all of the presets are correct, so you can click on Next:

      Configuring your app

      When you’ve finished configuring your app, give it a name like save-the-whales:

      Name your app

      Once you select your name and click Next, you will go to the payment plan page. Since your app is a static site, you can choose the Starter plan, which is free:

      Choose starter plan

      Now click the Launch Starter App button. After waiting a couple of minutes, your app will be deployed.

      Navigate to the URL listed beneath the title of your app. You will find your Gatsby app successfully deployed.

      Conclusion

      In this tutorial, you created a Gatsby site with GIFs and deployed the site onto DigitalOcean App Platform. DigitalOcean App Platform is a convenient way to deploy and share your Gatsby projects. If you would like to learn more about this product, check out the official documentation for App Platform.



      Source link

      How To Set Up a Gatsby Project with TypeScript


      The author selected the Diversity in Tech Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      TypeScript is a superset of JavaScript that adds optional static typing at build time, which cuts down on debugging runtime errors. It has grown into a powerful alternative to JavaScript over the years. At the same time, Gatsby has emerged as a useful front-end framework for creating static websites. TypeScript’s static-typing abilities go well with a static-site generator like Gatsby, and Gatsby has built-in support for coding in TypeScript.

      In this tutorial, you’re going to use Gatsby’s built-in capabilities to configure a Gatsby project for TypeScript. After this tutorial, you will have learned how to integrate TypeScript into your Gatsby project.

      Prerequisites

      • You will need to have both Node and npm installed in order to run a development environment and handle TypeScript- or Gatsby-related packages, respectively. This tutorial was tested with Node.js version 14.13.0 and npm version 6.14.8. To install on macOS or Ubuntu 18.04, follow the steps in How to Install Node.js and Create a Local Development Environment on macOS or the Installing Using a PPA section of How To Install Node.js on Ubuntu 18.04.
      • To create a new Gatsby project, you will need the Gatsby CLI command line tool installed on your computer. To set this up, follow Step 1 in How to Set Up Your First Gatsby Site. This step will also show you how to create a new Gatsby project with the gatsby new command.
      • You will need some familiarity with GraphQL queries and using GraphiQL to query for local image data. If you’d like a refresher on the query sandbox in GraphiQL, read How to Handle Images with GraphQL and the Gatsby Image API.
      • You will need sufficient knowledge of JavaScript, especially ES6+ syntax such as destructuring and imports/exports. You can find more information on these topics in Understanding Destructuring, Rest Parameters, and Spread Syntax in JavaScript and Understanding Modules and Import and Export Statements in JavaScript.
      • Since Gatsby is a React-based framework, you will be refactoring and creating components in this tutorial. You can learn more about this in How to Create Custom Components in React.
      • Additionally, you will need TypeScript installed on your machine. To do this, refer to the official TypeScript website. If you are using an editor besides Visual Studio Code, you may need to go through a few extra steps to make sure you have TypeScript performing type-checks at build time and showing any errors. For example, if you’re using Atom, you’ll need to install the atom-typescript package to be able to achieve a true TypeScript experience. If you would like to download TypeScript only for your project, do so after the Gatsby project folder has been set up.

      Step 1 — Creating a New Gatsby Site and Removing Boilerplate

      To get started, you’re going to create your Gatsby site and make sure that you can run a server and view the site. After that, you will remove some unused boilerplate files and code. This will set your project up for edits in later steps.

      Open your computer’s console/terminal and run the following command:

      • gatsby new gatsby-typescript-tutorial

      This will take a few seconds to run as it sets up the necessary boilerplate files and folders for the Gatsby site. After it is finished, cd into the project’s directory:

      • cd gatsby-typescript-tutorial

      To make sure the site’s development environment can start properly, run the following command:

      After a few seconds, you will receive the following message in the console:

      Output

      ... You can now view gatsby-starter-default in the browser. http://localhost:8000

      Usually, the default port is :8000, but you can change this by running gatsby develop -p another_number instead.

      Head over to your preferred browser and type http://localhost:8000 in the address bar to find the site. It will look like this:

      Gatsby Default Starter Site

      Next, you’ll remove all unnecessary files. This includes gatsby-node.js, gastby-browser.js, and gatsby-ssr.js:

      • rm gatsby-node.js
      • rm gastby-browser.js
      • rm gatsby-ssr.js

      Next, to finish setup, you’re going to remove some boilerplate code from your project’s index page. In your project’s root directory, head to the src directory, followed by pages and then open the index.js file.

      For this tutorial, you are only going to work with an <Image /> component, so you can delete code related to the <Link /> component, along with the h1 and p elements. Your file will then look like the following:

      gatsby-typescript-tutorial/src/pages/index.js

      import React from "react"
      
      import Layout from "../components/layout"
      import Image from "../components/image"
      import SEO from "../components/seo"
      
      const IndexPage = () => (
        <Layout>
          <SEO title="Home" />
          <div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
            <Image />
          </div>
        </Layout>
      )
      
      export default IndexPage
      

      Save and close the file.

      Now that you’ve created your project and completed some initial setup, you are ready to install the necessary plugins.

      Step 2 — Installing Dependencies

      In order to set up support for TypeScript in Gatsby, you’ll need some additional plugins and dependencies, which you will install in this step.

      The gatsby-plugin-typescript plugin already comes with a newly created Gatsby site. Unless you want to change any of its default options, you don’t have to add this plugin to your gatsby-config.js file explicitly. This Gatsby plugin makes writing .ts and .tsx files in TypeScript possible.

      Since your app can read TypeScript files, you will now change Gatsby’s JavaScript files to a TypeScript file extension. In particular, change header.js, image.js, layout.js, and seo.js in src/components and index.js in src/pages to header.tsx, image.tsx, layout.tsx, seo.tsx, and index.tsx:

      • mv src/components/header.js src/components/header.tsx
      • mv src/components/image.js src/components/image.tsx
      • mv src/components/layout.js src/components/layout.tsx
      • mv src/components/seo.js src/components/seo.tsx
      • mv src/pages/index.js src/pages/index.tsx

      You are using the mv command to rename the files to the second argument. .tsx is the file extension, since these files use JSX.

      There is one important caveat about the gatsby-plugin-typescript plugin, however: it doesn’t include type-checking at build time (a core function of TypeScript). If you’re using VS Code, this won’t be an issue because TypeScript is a supported language in Visual Studio. But if you’re using another editor, like Atom, you will need to do some extra configurations to achieve a full TypeScript development experience.

      Since Gatsby is a React-based framework, adding some additional React-related typing is also recommended. To add type-checking for types specific to React, run the following command:

      To add type-checking for types related to the React DOM, use this command:

      Now that you’ve become familiar with the plugin gatsby-plugin-typescript, you are ready to configure your Gatsby site for TypeScript in the next step.

      Step 3 — Configuring TypeScript for Gatsby with the tsconfig.json File

      In this step, you will create a tsconfig.json file. A tsconfig.json file has two primary purposes: establishing the root directory of the TypeScript project (include) and overriding the TypeScript compiler’s default configurations (compilerOptions). There are a couple of ways to create this file. If you have the tsc command line tool installed with npm, you could create a new tsconfig file with tsc --init. But the file is then populated with many default options and comments.

      Instead, create a new file at the root of your directory (gatsby-typescript-project/) and name it tsconfig.json.

      Next, create an object with two properties, compilerOptions and include, populated with the following code:

      gatsby-typescript-tutorial/tsconfig.json

       {
        "compilerOptions": {
          "module": "commonjs",
          "target": "es6",
          "jsx": "preserve",
          "lib": ["dom", "es2015", "es2017"],
          "strict": true,
          "noEmit": true,
          "isolatedModules": true,
          "esModuleInterop": true,
          "skipLibCheck": true,
          "noUnusedLocals": true,
          "noUnusedParameters": true,
          "removeComments": false
        },
        "include": ["./src/**/*"]
      }
      

      Note:
      This configuration is partially based on the gatsby-starter-typescript-plus starter.

      Save this file and close it when you are done.

      The include property points to an array of filenames or paths that the compiler knows to convert from TypeScript to JavaScript.

      Here is a brief explanation of each option used in compilerOptions:

      • module - Sets the module system for the project; commonjs is used by default.
      • target - Depending on what version of JavaScript you’re using, this option determines which features to downlevel and which to leave alone. This can be helpful if your project is deployed to older environments vs. newer environments.
      • jsx - Setting for how JSX is treated in .tsx files. The preserve option leaves the JSX unchanged.
      • lib - An array of specified type-definitions of different JS libraries/APIs (dom, es2015, etc.).
      • strict - When set to true, this enables TypeScript’s type-checking abilities at build-time.
      • noEmit - Since Gatsby already uses Babel to compile your code to readable JavaScript, you change this option to true to leave TypeScript out it.
      • isolatedModules - By choosing Babel as your compiler/transpiler, you are opting for compilation one file at a time, which may cause potential problems at runtime. Setting this option to true allows TypeScript to warn you if you are about to run into this problem.
      • esModuleIterop - Enabling this option allows your use of CommonJS (your set module) and ES modules (importing and exporting custom variables and functions) to better work together and allow namespace objects for all imports.
      • noUnusedLocals and noUnusedParamters - Enabling these two options disables the errors TypeScript would normally report if you were to create an unused local variable or parameter.
      • removeComments - Setting this to false (or not setting it at all) allows there to be comments present after any TypeScript files have been converted to JavaScript.

      You can learn more about these different options and many more by visiting TypeScript’s reference guide for tsconfig.

      Now that TypeScript is configured for Gatsby, you are going to complete your TypeScript integration by refactoring some of your boilerplate files in src/components and src/pages.

      Step 4 — Refactoring seo.tsx for TypeScript

      In this step, you’re going to add some TypeScript syntax to the seo.tsx file. This step goes in depth to explain some concepts of TypeScript; the next step will show how to refactor other boilerplate code in a more abbreviated manner.

      One feature of TypeScript is its flexibility with its syntax. If you don’t want to add typing to your variables explicitly, you don’t have to. Gatsby believes that adopting TypeScript in your workflow “can and should be incremental”, and so this step will concentrate on three core TypeScript concepts:

      • basic types
      • defining types and interfaces
      • working with build-time errors

      Basic Types in TypeScript

      TypeScript supports basic datatypes including: boolean, number, and string. The major syntactical difference with TypeScript, compared to JavaScript, is that variables can now be defined with an associated type.

      For example, the following code block shows how to assign the basic types with the highlighted code:

      let num: number;
      num = 0
      
      let str: string;
      str = "TypeScript & Gatsby"
      
      let typeScriptIsAwesome: boolean;
      typeScriptIsAwesome = true;
      

      In this code, num must be a number, str must be a string, and typeScriptIsAwesome must be a boolean.

      Now you will examine the defaultProps and propTypes declarations in the seo.tsx file, found in the src/components directory. Open the file in your editor and look for the following highlighted lines:

      gatsby-typescript-tutorial/src/components/seo.tsx

      ...
      import React from "react"
      import PropTypes from "prop-types"
      import { Helmet } from "react-helmet"
      import { useStaticQuery, graphql } from "gatsby"
      
      ...
            ].concat(meta)}
          />
        )
      }
      
      
      SEO.defaultProps = {
        lang: `en`,
        meta: [],
        description: ``,
      }
      
      SEO.propTypes = {
        description: PropTypes.string,
        lang: PropTypes.string,
        meta: PropTypes.arrayOf(PropTypes.object),
        title: PropTypes.string.isRequired,
      }
      
      export default SEO
      

      By default, a Gatsby site’s SEO component comes with a weak typing system using PropTypes. The defaultProps and propTypes are explicitly declared, using the imported PropsTypes class. For example, in the meta prop (or alias) of the propTypes object, its value is an array of objects, each of which is itself a prop of the PropTypes component. Some props are marked as required (isRequired) while others are not, implying they are optional.

      Since you are using TypeScript, you will be replacing this typing system. Go ahead and delete defaultProps and propTypes (along with the import statement for the PropTypes at the top of the file). Your file will look like the following:

      gatsby-typescript-tutorial/src/components/seo.tsx

       ...
      import React from "react"
      import { Helmet } from "react-helmet"
      import { useStaticQuery, graphql } from "gatsby"
      
      
      ...
            ].concat(meta)}
          />
        )
      }
      
      export default SEO
      

      Now that you’ve removed the default typing, you’ll write out the type aliases with TypeScript.

      Defining TypeScript Interfaces

      In TypeScript, an interface is used to define the “shape” of a custom type. These are used to represent the value type of complex pieces of data like React components and function parameters. In the seo.tsx file, you’re going to build an interface to replace the defaultProps and propTypes definitions that were deleted.

      Add the following highlighted lines:

      gatsby-typescript-tutorial/src/components/seo.ts

       ...
      import React from "react"
      import { Helmet } from "react-helmet"
      import { useStaticQuery, graphql } from "gatsby"
      
      interface SEOProps {
        description?: string,
        lang?: string,
        meta?: Array<{name: string, content: string}>,
        title: string
      }
      
      ...
      
      
      

      The interface SEOProps accomplishes what SEO.propTypes did by setting each of the properties associated data type as well as marking some as required with the ? character.

      Typing a Function

      Just like in JavaScript, functions play an important role in TypeScript applications. You can even type functions by specifying the datatype of the arguments passed into them. In the seo.tsx file, you will now work on the defined SEO function component. Under where the interface for SEOProps was defined, you’re going to explicitly declare the type of the SEO component’s function arguments, along with a return type of SEOProps right after:

      Add the following highlighted code:

      gatsby-typescript-tutorial/src/components/seo.ts

      ...
      interface SEOProps {
        description?: string,
        lang?: string,
        meta?: Array<{name: string, content: string}>,
        title: string
      }
      
      function SEO({ description='', lang='en', meta=[], title }: SEOProps) {
        ...
      }
      

      Here you set defaults for the SEO function arguments so that they adhere to the interface, and added the interface with : SEOProps. Remember that you at least have to include the title in the list of arguments passed to the SEO component because it was defined as a required property in the SEOProps interface you defined earlier.

      Lastly, you can revise the metaDescription and defaultTitle constant declarations by setting their type, which is string in this case:

      gatsby-typescript-tutorial/src/components/seo.tsx

       ...
      function SEO({ description='', lang='en', meta=[], title }: SEOProps) {
        const { site } = useStaticQuery(
          graphql`
            query {
              site {
                siteMetadata {
                  title
                  description
                  author
                }
              }
            }
          `
        )
      
        const metaDescription: string = description || site.siteMetadata.description
        const defaultTitle: string = site.siteMetadata?.title
      ...
      

      Another type in TypeScript is the any type. For situations where you’re dealing with a variable whose type is unclear or difficult to define, use any as a last resort to avoid any build-time errors.

      An example of using the any type is when dealing with data fetched from a third-party, like an API request or a GraphQL query. In the seo.tsx file, where the destructured site property is defined with a GraphQL static query, set its type to any:

      gatsby-typescript-tutorial/src/components/seo.tsx

      ...
      interface SEOProps {
        description?: string,
        lang?: string,
        meta?: Array<{name: string, content: string}>,
        title: string
      }
      
      function SEO({ description='', lang='en', meta=[], title }: Props) {
        const { site }: any = useStaticQuery(
          graphql`
            query {
              site {
                siteMetadata {
                  title
                  description
                  author
                }
              }
            }
          `
        )
        ...
      }
      

      Save and exit the file.

      It’s important to always keep the defined values consistent with their type. Otherwise, you will see build-time errors appear via the TypeScript compiler.

      Build-Time Errors

      It will be helpful to become accustomed to the errors TypeScript will catch and report at build-time. The idea is that TypeScript catches these errors, mostly type-related, at build-time, and this cuts down on the amount of debugging in the long run (in compile-time).

      One example of a build-time error occurring is when you declare a variable of one type but assign it a value that is of another type. If you were to change the value of one of the keyword arguments passed to the SEO component to one of a different type, the TypeScript compiler will detect the inconsistency and report the error. The following is an image of what this looks like in VSCode:

      A build-time error in VSCode when the description variable is set to a number.

      The error says Type 'number' is not assignable to type 'string'. This is because, when you set up your interface, you said the description property would be of type string. The value 0 is of type number. If you change the value of description back into a “string”, the error message will go away.

      Step 5 — Refactoring the Rest of the Boilerplate

      Lastly, you will refactor the remaining boilerplate files with TypeScript: layout.tsx, image.tsx, and header.tsx. Like seo.tsx, these component files are located in the src/components directory.

      Open src/components/layout.tsx. Towards the bottom, is the defined Layout.propTypes. Delete the following highlighted lines:

      gatsby-typescript-tutorial/src/components/layout.tsx

       import React from "react"
      import PropTypes from "prop-types"
      import { useStaticQuery, graphql } from "gatsby"
      ...
      
      Layout.propTypes = {
        children: PropTypes.node.isRequired,
      }
      
      export default Layout
      

      The children prop shows that its value is of type node per the PropTypes class. Plus, it’s a required prop. Since the children in the layout could be anything from simple text to React child components, use ReactNode as the associated type by importing near the top and adding it to the interface:

      Add the following highlighted lines:

      gatsby-typescript-tutorial/src/components/layout.tsx

      ...
      import React, { ReactNode } from "react"
      import { useStaticQuery, graphql } from "gatsby"
      
      import Header from "./header"
      import "./layout.css"
      
      interface LayoutProps {
        children: ReactNode
      }
      
      const Layout = ({ children }: LayoutProps) => {
        ...
      

      Next, add a type to the data variable that stores a GraphQL query that fetches site title data. Since this query object is coming from a third-party entity like GraphQL, give data an any type. Lastly, add the string type to the siteTitle variable that works with that data:

      gatsby-typescript-tutorial/src/components/layout.tsx

       ...
      const Layout = ({ children }: LayoutProps) => {
        const data: any = useStaticQuery(graphql`
        query MyQuery {
          site {
            siteMetadata {
              title
            }
          }
        }
      `)
      
      const siteTitle: string = data.site.siteMetadata?.title || `Title`
      
        return (
          <>
            <Header siteTitle={siteTitle} />
            <div
      ...
      

      Save and close the file.

      Next, open the src/components/image.tsx file.

      Here you are dealing with a similar situation as layout.tsx. There is a data variable that stores a GraphQL query that could have an any type. The image fluid data that is passed into the fluid attribute of the <Img /> component could be separated from the return statement into its own variable. It’s also a complex variable like data, so give this an any type as well:

      gatsby-typescript-tutorial/src/components/image.tsx

      ...
      const Image = () => {
        const data: any = useStaticQuery(graphql`
          query {
            placeholderImage: file(relativePath: { eq: "gatsby-astronaut.png" }) {
              childImageSharp {
                fluid(maxWidth: 300) {
                  ...GatsbyImageSharpFluid
                }
              }
            }
          }
        `)
      
        if (!data?.placeholderImage?.childImageSharp?.fluid) {
          return <div>Picture not found</div>
        }
      
        const imageFluid: any = data.placeholderImage.childImageSharp.fluid
      
        return <Img fluid={imageFluid} />
      }
      
      export default Image
      

      Save and close the file.

      Now open the src/components/header.tsx file. This file also comes with predefined prop types, using the PropTypes class. Like seo.tsx, image.tsx, and layout.tsx, replace Header.defaultProps and Header.propTypes with an interface using the same prop names:

      gatsby-typescript-tutorial/src/components/header.tsx

      import { Link } from "gatsby"
      import React from "react"
      
      interface HeaderProps {
        siteTitle: string
      }
      
      const Header = ({ siteTitle }: HeaderProps) => (
        <header
          style={{
            background: `rebeccapurple`,
            marginBottom: `1.45rem`,
          }}
        >
          <div
            style={{
              margin: `0 auto`,
              maxWidth: 960,
              padding: `1.45rem 1.0875rem`,
            }}
          >
            <h1 style={{ margin: 0 }}>
              <Link
                to="/"
                style={{
                  color: `white`,
                  textDecoration: `none`,
                }}
              >
                {siteTitle}
              </Link>
            </h1>
          </div>
        </header>
      )
      
      export default Header
      

      Save and close the file.

      With your files refactored for TypeScript, you can now restart the server to make sure everything is working. Run the following command:

      When you navigate to localhost:8000, your browser will render the following:

      Gatsby Default Development page

      Conclusion

      TypeScript’s static-typing capabilities go a long way in keeping debugging at a minimum. It’s also a great language for Gatsby sites since it’s supported by default. Gatsby itself is a useful front-end tool for creating static-sites, such as landing pages.

      You now have two popular tools at your disposal. To learn more about TypeScript and all you can do with it, head over to the official TypeScript handbook.



      Source link