Gatsby Open Graph Meta Tags: The Complete Setup Guide

Learn how to add og:title, og:image, og:description, and Twitter card tags to Gatsby sites using gatsby-plugin-react-helmet, Head API, and dynamic OG images.

How Gatsby handles meta tags

Gatsby is a React-based static site generator that produces pre-rendered HTML at build time, which means social crawlers can read your <meta> tags without executing JavaScript. This is a major advantage over client-side React apps. However, you still need to inject the right tags for each page.

Gatsby offers two approaches depending on your Gatsby version: gatsby-plugin-react-helmet (Gatsby v4 and earlier) and the Gatsby Head API (Gatsby v5+). Both work well for OG tags.

Option 1: Gatsby Head API (v5+)

Gatsby v5 introduced a native Head export that replaces the need for React Helmet. Export a Head function from any page component and Gatsby injects it into the <head> of the built HTML:

// src/pages/index.js
export function Head() {
  return (
    <>
      <title>My Gatsby Site</title>
      <meta name="description" content="My page description." />
      <meta property="og:title" content="My Gatsby Site" />
      <meta property="og:description" content="My page description." />
      <meta property="og:image" content="https://example.com/og.jpg" />
      <meta property="og:url" content="https://example.com" />
      <meta property="og:type" content="website" />
      <meta name="twitter:card" content="summary_large_image" />
      <meta name="twitter:title" content="My Gatsby Site" />
      <meta name="twitter:description" content="My page description." />
      <meta name="twitter:image" content="https://example.com/og.jpg" />
    </>
  )
}

export default function IndexPage() {
  return <main>...</main>
}

For dynamic pages such as blog posts sourced from GraphQL, pass the page context into the Head component:

// src/templates/blog-post.js
export function Head({ data }) {
  const post = data.markdownRemark.frontmatter
  return (
    <>
      <title>{post.title}</title>
      <meta property="og:title" content={post.title} />
      <meta property="og:description" content={post.excerpt} />
      <meta property="og:image" content={post.featuredImage} />
      <meta property="og:type" content="article" />
      <meta name="twitter:card" content="summary_large_image" />
    </>
  )
}

export const query = graphql`
  query($id: String!) {
    markdownRemark(id: { eq: $id }) {
      frontmatter {
        title
        excerpt
        featuredImage
      }
    }
  }
`

Option 2: gatsby-plugin-react-helmet (v4 and earlier)

For Gatsby v4 projects, install react-helmet and gatsby-plugin-react-helmet:

npm install gatsby-plugin-react-helmet react-helmet

// gatsby-config.js
module.exports = {
  plugins: ['gatsby-plugin-react-helmet'],
}

Create a reusable SEO component that wraps React Helmet:

// src/components/Seo.js
import React from 'react'
import { Helmet } from 'react-helmet'

export function Seo({ title, description, image, url }) {
  return (
    <Helmet>
      <title>{title}</title>
      <meta name="description" content={description} />
      <meta property="og:title" content={title} />
      <meta property="og:description" content={description} />
      <meta property="og:image" content={image} />
      <meta property="og:url" content={url} />
      <meta property="og:type" content="website" />
      <meta name="twitter:card" content="summary_large_image" />
    </Helmet>
  )
}

// Usage in page:
export default function IndexPage() {
  return (
    <>
      <Seo
        title="My Gatsby Site"
        description="Description here."
        image="https://example.com/og.jpg"
        url="https://example.com"
      />
      <main>...</main>
    </>
  )
}

Setting a default OG image

Store a fallback OG image in your static/ folder (e.g., static/og-default.jpg). Gatsby copies this directory as-is to the build output, making it accessible at https://yoursite.com/og-default.jpg. Reference it as the default when a page doesn't have its own image.

Common Gatsby OG tag mistakes

  • Relative image URLs: og:image must be an absolute HTTPS URL. Relative paths like /images/og.jpg will not work on Twitter or LinkedIn.
  • Missing plugin for Helmet: forgetting to add gatsby-plugin-react-helmet to gatsby-config.js means Helmet tags won't render server-side.
  • Image too small: aim for 1200×630 px. Images below 200px may be ignored by Facebook and LinkedIn.
  • Stale CDN cache: use each platform's scraper tool to force a re-fetch after updating tags.

Verify your Gatsby OG tags

Run gatsby build && gatsby serve and test against your local server or staging URL. Crawlers need to reach your deployed site, so test on a public URL. Use the tools below:

Preview your OG tags free at OGFixer.com → Paste your Gatsby URL to see exactly how it appears on Twitter, LinkedIn, Discord, and Slack.

← All guides