<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Deznit]]></title><description><![CDATA[Deznit]]></description><link>https://blog.deznit.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1621003515459/bR9viVvND.png</url><title>Deznit</title><link>https://blog.deznit.com</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 15 May 2026 19:06:36 GMT</lastBuildDate><atom:link href="https://blog.deznit.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Adding SEO in Gatsby Site]]></title><description><![CDATA[With the help of this blog post you can add basic SEO for your gatsby website, and set data for social sharing cards 
Originally posted on my blog  Deznit 

Introduction
You are here reading this blog so you probably know about SEO and its importance...]]></description><link>https://blog.deznit.com/adding-seo-in-gatsby-site</link><guid isPermaLink="true">https://blog.deznit.com/adding-seo-in-gatsby-site</guid><category><![CDATA[Gatsby]]></category><category><![CDATA[SEO]]></category><dc:creator><![CDATA[Anoop Nair]]></dc:creator><pubDate>Wed, 12 May 2021 06:58:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1620802170191/VtG0SfD8t.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>With the help of this blog post you can add basic SEO for your gatsby website, and set data for social sharing cards </p>
<p>Originally posted on my blog  <a target="_blank" href="https://deznit.com/adding-seo-in-gatsby">Deznit</a> </p>
</blockquote>
<h2 id="introduction">Introduction</h2>
<p>You are here reading this blog so you probably know about SEO and its importance. So let's jump right in to the fun stuff.</p>
<p>The default starter already have some SEO setup, you only have to enhance it for social sharing cards, but here we will start from scratch so that it can be used in any site. The first thing we want to add is <a target="_blank" href="https://www.npmjs.com/package/react-helmet">React Helmet</a>. This is a react component where we add our meta tags, and it adds our tags to the document head tag.</p>
<pre><code>yarn <span class="hljs-keyword">add</span> react-helmet
</code></pre><blockquote>
<p>I will be using typescript in blog posts.</p>
</blockquote>
<h2 id="default-config">Default Config</h2>
<p>First we have to specify global meta data defaults in gatsby-config.js file which we will later query in our seo component using <a target="_blank" href="https://www.gatsbyjs.com/docs/use-static-query/">useStaticQuery</a> hook.</p>
<pre><code class="lang-js"><span class="hljs-comment">// gatsby-config.js</span>

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">siteMetadata</span>: {
    <span class="hljs-attr">title</span>: <span class="hljs-string">`Deznit`</span>,
    <span class="hljs-attr">description</span>: <span class="hljs-string">`Blog posts on issue I faced while programming and how I solved it. We all can learn something new.`</span>,
    <span class="hljs-attr">author</span>: <span class="hljs-string">`@deznit`</span>,
    <span class="hljs-attr">image</span>: <span class="hljs-string">`/images/header_image.png`</span>,
    <span class="hljs-attr">url</span>: <span class="hljs-string">"https://deznit.com"</span>,
  },
  plugins[
      ...
    <span class="hljs-comment">//   all other plugins here</span>
      ]
}
</code></pre>
<h2 id="seo-component">SEO Component</h2>
<p>We can create a SEO component, where we will specify the meta tags data and data for social sharing cards.</p>
<pre><code><span class="hljs-comment">// components/SEO.tsx</span>

<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>
<span class="hljs-keyword">import</span> { Helmet } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-helmet"</span>
<span class="hljs-keyword">import</span> { useStaticQuery, graphql } <span class="hljs-keyword">from</span> <span class="hljs-string">"gatsby"</span>

<span class="hljs-keyword">const</span> SEO = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Helmet</span> /&gt;</span></span>
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> SEO
</code></pre><p>With initial setup done we can now query the data that we specified in gatsby-config use useStaticQuery hook inside the SEO function</p>
<pre><code><span class="hljs-section">const</span> { <span class="hljs-attribute">site</span> } = useStaticQuery(
  graphql`
    query {
      <span class="hljs-section">site</span> {
        <span class="hljs-section">siteMetadata</span> {
          <span class="hljs-attribute">title</span>
          description
          author
          image
          url
        }
      }
    }
  `
)
</code></pre><p>We have to add some props to the SEO component so that we can use it in post component and add seo data for individual posts dynamically. And then we will use data if props available then from there or the default value to add meta data and other head tags like title.</p>
<p>All the meta tags that have name starting with og(Open Graph) is used by fb social sharing card and other ones are for twitter sharing card.</p>
<pre><code><span class="hljs-comment">// components/SEO.tsx</span>

<span class="hljs-keyword">type</span> ImageType = {
  src: <span class="hljs-built_in">string</span>
  height: <span class="hljs-built_in">number</span>
  width: <span class="hljs-built_in">number</span>
}

<span class="hljs-keyword">type</span> SeoProps = {
  description?: <span class="hljs-built_in">string</span>
  lang?: <span class="hljs-built_in">string</span>
  image?: ImageType
  title: <span class="hljs-built_in">string</span>
}

<span class="hljs-keyword">const</span> SEO = <span class="hljs-function">(<span class="hljs-params">{ description, lang = <span class="hljs-string">"en"</span>, image, title }: SeoProps</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> { site } = useStaticQuery(
    graphql<span class="hljs-string">`
      query {
        site {
          siteMetadata {
            title
            description
            author
            image
            url
          }
        }
      }
    `</span>
  )

  <span class="hljs-comment">// if no props specified we use default data</span>
  <span class="hljs-comment">// that we specified in gatsby config and queried above</span>

  <span class="hljs-keyword">const</span> metaTitle = title ? title : site.siteMetadata.title

  <span class="hljs-keyword">const</span> metaDescription = description
    ? description
    : site.siteMetadata.description

  <span class="hljs-comment">// specifying height and width is needed for fb sharing card</span>
  <span class="hljs-comment">// otherwise on first share no image will be shown,</span>
  <span class="hljs-comment">//  and it complains about height and width not specified</span>
  <span class="hljs-keyword">let</span> metaImage: ImageType = image
    ? image
    : { src: site.siteMetadata.image, width: <span class="hljs-number">1200</span>, height: <span class="hljs-number">670</span> }

  <span class="hljs-comment">// concatinating site url to the image</span>
  <span class="hljs-comment">// twitter card was not showing image without it</span>
  metaImage.src = <span class="hljs-string">`<span class="hljs-subst">${site.siteMetadata.url}</span><span class="hljs-subst">${metaImage.src}</span>`</span>

  <span class="hljs-keyword">return</span> (
    &lt;Helmet
      htmlAttributes={{
        lang,
      }}
      title={metaTitle}
      titleTemplate={<span class="hljs-string">`%s | <span class="hljs-subst">${site.siteMetadata.title}</span>`</span>}
      meta={[
        {
          name: <span class="hljs-string">`description`</span>,
          content: metaDescription,
        },
        {
          property: <span class="hljs-string">`og:title`</span>,
          content: metaTitle,
        },
        {
          property: <span class="hljs-string">`og:description`</span>,
          content: metaDescription,
        },
        {
          property: <span class="hljs-string">`og:type`</span>,
          content: <span class="hljs-string">`website`</span>,
        },
        {
          name: <span class="hljs-string">`twitter:card`</span>,
          content: <span class="hljs-string">`summary_large_image`</span>,
        },
        {
          name: <span class="hljs-string">`twitter:site`</span>,
          content: site.siteMetadata.title,
        },
        {
          name: <span class="hljs-string">`twitter:creator`</span>,
          content: site.siteMetadata.author,
        },
        {
          name: <span class="hljs-string">`twitter:title`</span>,
          content: metaTitle,
        },
        {
          name: <span class="hljs-string">`twitter:description`</span>,
          content: metaDescription,
        },
        {
          property: <span class="hljs-string">"og:image"</span>,
          content: metaImage.src,
        },
        {
          property: <span class="hljs-string">"og:image:width"</span>,
          content: metaImage.width,
        },
        {
          property: <span class="hljs-string">"og:image:height"</span>,
          content: metaImage.height,
        },
      ]}
    /&gt;
  )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> SEO
</code></pre><p>Now we can use the SEO component in our index page (homepage) and post page (individual post). Here we will see the example of post page.
The post query of the page will be similar to the following code and it will differ based on your data source, markdown frontmatter or wheter you are using gatsby-transformer-sharp pluging for images or not <strong>(So dont copy below sections blindly)</strong>. </p>
<blockquote>
<p>To learn about building a blog with markdown please follow this <a target="_blank" href="https://deznit.com/using-styled-components-in-gatsby-markdown-posts">Using Styled components in gatsby post</a></p>
</blockquote>
<pre><code><span class="hljs-comment">//pages/post.tsx</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> postQuery = graphql`
  query BlogPostQuery($<span class="hljs-keyword">id</span>: String) {
    mdx(<span class="hljs-keyword">id</span>: { eq: $<span class="hljs-keyword">id</span> }) {
      <span class="hljs-keyword">id</span>
      excerpt(pruneLength: <span class="hljs-number">250</span>)
      frontmatter {
        author
        path
        title
        feature_image {
            resize(width: <span class="hljs-number">1200</span>) {
              src
              height
              width
            }
          }
        }
      }
    }
  }
`
</code></pre><p>The next step is to use the query data in the post component, and pass props to SEO component</p>
<pre><code><span class="hljs-comment">// pages/post.tsx</span>


<span class="hljs-comment">// ...</span>
<span class="hljs-keyword">import</span> Layout <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/layout"</span>
<span class="hljs-keyword">import</span> SEO <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/seo"</span>

<span class="hljs-keyword">const</span> Post = <span class="hljs-function">(<span class="hljs-params">{ data }</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Layout</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">SEO</span>
        <span class="hljs-attr">title</span>=<span class="hljs-string">{data.mdx.frontmatter.title}</span>
        <span class="hljs-attr">description</span>=<span class="hljs-string">{data.mdx.excerpt}</span>
        <span class="hljs-attr">image</span>=<span class="hljs-string">{data.mdx.frontmatter.feature_image.childImageSharp.resize}</span>
      /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Layout</span>&gt;</span></span>
  )
}
</code></pre><p>And thats it we are done with basic SEO and setting social sharing cards data. This is just the starting you should keep improving it by adding more tags like keywords etc. This is the seo setup I currently have for this blog and will update the blog when I add something to my blog SEO.</p>
<p>Below are the results for google index and social media sharing cards.</p>
<h2 id="results">Results 🎉🎉</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1620802122140/GSkpzRwHw.png" alt="result.png" /></p>
]]></content:encoded></item></channel></rss>