Gatsby: Facebook Share not picking up OpenGraph meta tags from Gatsby site via React Helmet.

Created on 8 Apr 2020  ·  24Comments  ·  Source: gatsbyjs/gatsby

Description

Facebook Share not picking up OpenGraph meta tags from Gatsby site via React Helmet.

Steps to reproduce

I have an SEO component that renders React Helmet meta tags like so:

# seo.js

import React from 'react'
import PropTypes from 'prop-types'
import { Helmet } from 'react-helmet'
import { useStaticQuery, graphql } from 'gatsby'

function SEO({ description, lang, meta, title, pageUrl, image, post, children }) {
  const { site } = useStaticQuery(
    graphql`
      query {
        site {
          siteMetadata {
            title
            description
            siteUrl
            author
          }
        }
      }
    `
  )

  const metaDescription = description || site.siteMetadata.description
  const metaTitle = title || site.siteMetadata.title
  const metaUrl = pageUrl || site.siteMetadata.siteUrl

  return (
    <Helmet
      defer={false}
      htmlAttributes={{
        lang,
      }}
      defaultTitle={metaTitle}
      titleTemplate={`%s`}
      meta={meta}
    >
      {/* General tags */}
      <title>{metaTitle}</title>
      <meta name="image" content={image} />
      <meta name="description" content={metaDescription} />

      {/* OpenGraph tags */}
      <meta property="og:title" content={metaTitle} />
      <meta property="og:type" content={post ? `article` : `website`} />
      <meta property="og:url" content={metaUrl} />
      <meta property="og:image" content={image} />
      <meta property="og:description" content={metaDescription} />

      {/* Twitter Card tags */}
      <meta name="twitter:card" content="summary" />
      <meta name="twitter:creator" content="{site.siteMetadata.author}" />
      <meta name="twitter:title" content={metaTitle} />
      <meta name="twitter:image" content={image} />
      <meta name="twitter:description" content={metaDescription} />

      {children}
    </Helmet>
  )
}

SEO.defaultProps = {
  lang: `en`,
  meta: [],
  description: ``,
}

SEO.propTypes = {
  description: PropTypes.string,
  lang: PropTypes.string,
  title: PropTypes.string,
}

export default SEO

And a blog page teamplate that uses the SEO component like so:

# blogs.js

import React from 'react'
import { graphql, Link } from 'gatsby'
import { Container, Row, Col, useScreenClass, Visible } from 'react-grid-system'

import SEO from '../components/seo'
import Layout from '../components/layout'
import Main from '../components/main'
import BlogList from '../components/insights/blogList'
import Pagination from '../components/pagination'

const Blog = (props) => {
  const {
    seoTitle,
    seoDescription,
    seoHelmet,
  } = props.data.contentfulPage
  const posts = props.data.allContentfulInsightsPage.edges
  const { currentPage } = props.pageContext
  const screenClass = useScreenClass()

  return (
    <Layout>
      <SEO
        title={`${seoTitle} ${currentPage > 1 ?  `- Page ${currentPage}` : `` }`}
        description={seoDescription?.seoDescription ? seoDescription.seoDescription : false}
      >
        {seoHelmet ? seoHelmet.seoHelmet : ''}
      </SEO>
      <Main>
        <h1 className={`headline`}>Blog</h1>
        <BlogList posts={posts} />
        <Pagination context={props.pageContext} />
      </Main>
    </Layout>
  )
}

export const query = graphql`
  query($skip: Int!, $limit: Int!) {
    contentfulPage(slug: {eq: "blog"}) {
      id
      slug
      seoTitle
      seoDescription {
        seoDescription
      }
      seoHelmet {
        seoHelmet
      }
    }
    allContentfulBlogs(
      sort: { fields: [date], order: DESC }
      limit: $limit
      skip: $skip
    ) {
      edges {
        node {
          id
          title
          slug
          date
          preview
          text {
            json
          }
          image {
            localFile {
              ...blogThumbnail
            }
          }
          category {
            name
            slug
          }
        }
      }
    }
  }
`

export default Blog

Expected result

Meta tags should be generated properly on static site and should be accessible by Facebook share scraper.

Actual result

Facebook share debugging tool shows no such result.

The error on FB Sharing Debugger:

⚠️ Warnings That Should Be Fixed

Inferred Property

The 'og:image' property should be explicitly provided, even if a value can be inferred from other tags.

Missing Properties

The following required properties are missing: og:url, og:type, og:title, og:image, og:description, fb:app_id

And here is the scraped page:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<style data-href="/styles.13d4056a8a600210f038.css">a,abbr, ... </style>
<meta name="generator" content="Gatsby 2.19.49">
<title data-react-helmet="true"></title>
<link as="font" href=" ... " rel="preload" crossorigin="anonymous">
<style id="jss-server-side"></style>
<style data-styled="" data-styled-version="4.4.1"></style>
<script>window.dataLayer = window.dataLayer || []; ... </script>
<link rel="sitemap" type="application/xml" href="/sitemap.xml">
<link rel="canonical" href=" ... " data-baseprotocol="https:" data-basehost=" ... ">
<link rel="icon" href="/icons/icon-48x48.png?v=4b382095dbd38c63f79bce6052737f30">
<link rel="manifest" href="/manifest.webmanifest">
<meta name="theme-color" content="#3FB6E8">
<link rel="apple-touch-icon" sizes="48x48" href="/icons/icon-48x48.png?v=4b382095dbd38c63f79bce6052737f30">
<link rel="apple-touch-icon" sizes="72x72" href="/icons/icon-72x72.png?v=4b382095dbd38c63f79bce6052737f30">
<link rel="apple-touch-icon" sizes="96x96" href="/icons/icon-96x96.png?v=4b382095dbd38c63f79bce6052737f30">
<link rel="apple-touch-icon" sizes="144x144" href="/icons/icon-144x144.png?v=4b382095dbd38c63f79bce6052737f30">
<link rel="apple-touch-icon" sizes="192x192" href="/icons/icon-192x192.png?v=4b382095dbd38c63f79bce6052737f30">
<link rel="apple-touch-icon" sizes="256x256" href="/icons/icon-256x256.png?v=4b382095dbd38c63f79bce6052737f30">
<link rel="apple-touch-icon" sizes="384x384" href="/icons/icon-384x384.png?v=4b382095dbd38c63f79bce6052737f30">
<link rel="apple-touch-icon" sizes="512x512" href="/icons/icon-512x512.png?v=4b382095dbd38c63f79bce6052737f30">
<link as="script" rel="preload" href="/component---src-templates-insight-js-0b3261c291dd76b6e32d.js">
<link as="script" rel="preload" href="/commons-0606cae2f0bba83915df.js">
<link as="script" rel="preload" href="/app-595ec14f594e84b72fc9.js">
<link as="script" rel="preload" href="/styles-9336dff5557f552f77fc.js">
<link as="script" rel="preload" href="/webpack-runtime-5af2f2a5f9a736a820a9.js">
<link as="fetch" rel="preload" href="/page-data/insights/key-strategies-for-building-websites-that-capture-and-convert/page-data.json" crossorigin="anonymous">
<link as="fetch" rel="preload" href="/page-data/app-data.json" crossorigin="anonymous">
</head>
<body>
<noscript><iframe src="https://www.googletagmanager.com/ns.html? ... " height="0" width="0" style="display: none; visibility: hidden"></iframe></noscript>
<div id="___gatsby">
<div style="outline:none" tabindex="-1" id="gatsby-focus-wrapper"></div>
<div id="gatsby-announcer" style="position:absolute;top:0;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0" aria-live="assertive" aria-atomic="true"></div>
</div>
<script id="gatsby-script-loader">/*<![CDATA[*/ ... /*]]>*/</script>
<script id="gatsby-chunk-mapping">/*<![CDATA[*/ ... /*]]>*/</script>
<script src="/webpack-runtime-5af2f2a5f9a736a820a9.js" async=""></script>
<script src="/styles-9336dff5557f552f77fc.js" async=""></script>
<script src="/app-595ec14f594e84b72fc9.js" async=""></script>
<script src="/commons-0606cae2f0bba83915df.js" async=""></script>
<script src="/component---src-templates-insight-js-0b3261c291dd76b6e32d.js" async=""></script>
</body>
</html>

Here are some other fixes I tried...

Environment

Run gatsby info --clipboard in your project directory and paste the output here.

System:
    OS: Linux 4.4 Ubuntu 18.04.4 LTS (Bionic Beaver)      
    CPU: (8) x64 Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz 
    Shell: 5.4.2 - /usr/bin/zsh
  Binaries:
    Node: 10.16.3 - /usr/local/bin/node
    Yarn: 1.21.1 - /usr/bin/yarn
    npm: 6.14.2 - /usr/local/bin/npm
  Languages:
    Python: 2.7.17 - /usr/bin/python
  npmPackages:
    gatsby: ^2.19.25 => 2.20.8
    gatsby-background-image: ^0.9.12 => 0.9.19
    gatsby-cli: ^2.11.3 => 2.11.3
    gatsby-image: ^2.2.34 => 2.3.1
    gatsby-plugin-canonical-urls: ^2.1.20 => 2.2.1        
    gatsby-plugin-google-tagmanager: ^2.1.24 => 2.2.1     
    gatsby-plugin-manifest: ^2.2.31 => 2.3.3
    gatsby-plugin-material-ui: ^2.1.6 => 2.1.6
    gatsby-plugin-offline: ^3.1.1 => 3.1.2
    gatsby-plugin-preload-fonts: ^1.0.34 => 1.1.1
    gatsby-plugin-react-helmet: ^3.2.1 => 3.2.1
    gatsby-plugin-robots-txt: ^1.5.0 => 1.5.0
    gatsby-plugin-sass: ^2.1.26 => 2.2.1
    gatsby-plugin-sharp: ^2.4.0 => 2.5.3
    gatsby-plugin-sitemap: ^2.2.26 => 2.3.1
    gatsby-plugin-smoothscroll: ^1.0.4 => 1.1.0
    gatsby-plugin-styled-components: ^3.1.16 => 3.2.1     
    gatsby-plugin-transition-link: ^1.17.7 => 1.18.0 
    gatsby-plugin-typography: ^2.3.20 => 2.4.1
    gatsby-source-contentful: ^2.1.73 => 2.2.5
    gatsby-source-filesystem: ^2.1.40 => 2.2.2
    gatsby-transformer-sharp: ^2.3.7 => 2.4.2
  npmGlobalPackages:
    gatsby-cli: 2.8.19
needs reproduction

Most helpful comment

I have discovered that wrapping the Seo component with context providers inside wrapRootElement (exported from gatsby-ssr.js) causes this issue for me.

My current setup is something like this:

// gatsby-ssr.js

export const wrapRootElement = ({ element }) => (
  <ThemeProvider>
    {element}
  </ThemeProvider>
)
// some-page.jsx

const SomePage = () => (
  <Layout>
    <Seo
      title="some title"
      description="some description"
    />
   // other components here...
  </Layout>
)

Building the above app results in the index.html missing all the meta tags that are defined inside the Seo component.


If I render the Seo component inside wrapRootElement but still as a child of the provider, I get the same result.

Still doesn't work:

// gatsby-ssr.js

export const wrapRootElement = ({ element }) => (
  <ThemeProvider>
    <Seo title="some title" description="some description">
      {element}
    </Seo>
  </ThemeProvider>
)

However, if I render the Seo component outside the providers, then my index.html is built with all the meta tags defined in Seo.

This works:

// gatsby-ssr.js

export const wrapRootElement = ({ element }) => (
  <Seo title="some title" description="some description">
    <ThemeProvider>
      {element}
    </ThemeProvider>
  </Seo>
)

The problem is, I want different meta tags based on the current page.

Does anyone know how to solve this?

UPDATE:

I discovered that my ThemeProvider was skipping first render (in order to load dark vs light theme based on a localStorage value and prevent showing the incorrect color theme), and therefore the Seo component was not being rendered on the server.

All 24 comments

Hi! I am currently having exactly the same issue with Facebook. After some debugging, it seems that Facebook is not correctly detecting <meta> tags after the inline <style> tag.

To be more concrete, when checking the Facebook debug output at https://developers.facebook.com/tools/debug/echo/?q= it seems that it only shows this for me:

<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<style data-href="/styles.e6844be74391cfe76f6e.css">SOME_LONG_CSS</style>
</head>
</html>

Same issue for me too. meta tags seems to be right after the inline style tag

Note: it specifically seems to occur with pages having a lot of CSS inline (due to libraries, ...). The only way to resolve this would be to have the Meta tags being injected ABOVE the style tag.

Note: After utilizing gatsby-plugin-purgecss and turning on tailwind: true for my use case, the CSS went down by quite a lot allowing Facebook to load this!

16:17:19.575   Previous CSS Size: 1022.38 KB
16:17:19.576   New CSS Size: 20.94 KB (-97.95%)
16:17:19.576   Removed ~1001.44 KB of CSS

Can your try the workaround mentioned in description of this issue - https://github.com/gatsbyjs/gatsby/issues/22206 (which should put all the react-helmet tags first in <head>) and see if that helps?

@pieh thank you for your reply. While the meta tags has moved to the top when i do the view source, they do not appear at all when I see the https://developers.facebook.com/tools/debug/echo/?q= ... tool.

I tried doing few checks on gatsbyjs.org and it doesn't seem to happen there, which leads me to believe there is particular trigger for this behaviour. Are you able to share site - ideally with source, but just being able to see/inspect built one if you can't share source - that would be helpful

Good catch @thebillkidy - but it appears in my FB-scraped output from OP that other meta, links, and whatnot are loading after that same big <style> chunk as seen with <style data-href="/styles.13d4056a8a600210f038.css">a,abbr, ... </style> above and what follows. I could understand a special character or similar that throws off the FB scraper, but that doesn't appear to be the case here.

@pieh same same. I looked at Gatsby site, and several starter templates, and even other sites I have worked on and this is not an issue there. We tried a stripped down version of the current site being worked on tho and still not working. So I am starting to think this is more of a conflict issue with some other package perhaps? But then again, we tried removing packages to see if that had any effect on our stripped down version and nothin'. From package.json:

  "dependencies": {
    "@contentful/rich-text-react-renderer": "^13.4.0",
    "@fullpage/react-fullpage": "^0.1.17",
    "@material-ui/core": "^4.9.3",
    "@material-ui/styles": "^4.9.0",
    "@vimeo/player": "^2.10.0",
    "babel-eslint": "^10.0.3",
    "babel-plugin-styled-components": "^1.10.6",
    "eslint": "^6.8.0",
    "eslint-plugin-graphql": "^3.1.1",
    "gatsby": "^2.19.25",
    "gatsby-background-image": "^0.9.12",
    "gatsby-cli": "^2.11.5",
    "gatsby-image": "^2.2.34",
    "gatsby-plugin-canonical-urls": "^2.1.20",
    "gatsby-plugin-google-tagmanager": "^2.1.24",
    "gatsby-plugin-manifest": "^2.2.31",
    "gatsby-plugin-material-ui": "^2.1.6",
    "gatsby-plugin-offline": "^3.1.1",
    "gatsby-plugin-preload-fonts": "^1.0.34",
    "gatsby-plugin-react-helmet": "^3.2.1",
    "gatsby-plugin-robots-txt": "^1.5.0",
    "gatsby-plugin-sass": "^2.1.26",
    "gatsby-plugin-sharp": "^2.4.0",
    "gatsby-plugin-sitemap": "^2.2.26",
    "gatsby-plugin-smoothscroll": "^1.0.4",
    "gatsby-plugin-styled-components": "^3.1.16",
    "gatsby-plugin-transition-link": "^1.17.7",
    "gatsby-plugin-typography": "^2.3.20",
    "gatsby-source-contentful": "^2.1.73",
    "gatsby-source-filesystem": "^2.1.40",
    "gatsby-transformer-sharp": "^2.3.7",
    "gh-pages": "^2.2.0",
    "gsap": "^3.0.5",
    "intersection-observer": "^0.7.0",
    "node-sass": "^4.13.0",
    "polished": "^3.4.2",
    "prop-types": "^15.7.2",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-formio": "^4.2.4",
    "react-grid-system": "^6.0.7",
    "react-helmet": "^6.0.0-beta",
    "react-hook-form": "^4.9.6",
    "react-icons": "^3.8.0",
    "react-intersection-observer": "^8.25.2",
    "react-player": "^1.15.2",
    "react-redux": "^7.1.3",
    "react-remove-scroll": "^2.2.0",
    "react-scroll": "^1.7.15",
    "react-scroll-to": "^3.0.0-beta.3",
    "react-scrollmagic": "^2.1.1",
    "react-slick": "^0.25.2",
    "react-typography": "^0.16.19",
    "redux": "^4.0.5",
    "styled-components": "^4.4.1",
    "typography": "^0.16.19",
    "uuid": "^3.4.0"
  },
  "devDependencies": {
    "prettier": "^1.19.1"
  },

And from gatsby-config.js

const activeEnv = process.env.GATSBY_ACTIVE_ENV || process.env.NODE_ENV || "development"
require("dotenv").config({
  path: `.env.${activeEnv}`,
})
module.exports = {
  pathPrefix: `mysite`, // for GitHub pages
  siteMetadata: {
    title: `Site Title`,
    description: `A Gatsby site`,
    author: `@monkishtypist`,
    siteUrl: 'https://www.mysite.com'
  },
  plugins: [
    `gatsby-plugin-react-helmet`,
    `gatsby-plugin-offline`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    },
    `gatsby-plugin-preload-fonts`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `fonts`,
        path: `${__dirname}/src/fonts/`
      }
    },
    {
      resolve: `gatsby-source-contentful`,
      options: {
        spaceId: process.env.GATSBY_CONTENTFUL_SPACE_ID,
        accessToken: process.env.GATSBY_CONTENTFUL_TOKEN_ID,
        downloadLocal: process.env.GATSBY_CONTENTFUL_DOWNLOAD_LOCAL,
        useNameForId: false,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `placeholder`,
        path: `${__dirname}/gatsby-config.js`,
      },
    },
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-plugin-material-ui`,
      options: {
        stylesProvider: {
          injectFirst: true,
        },
      },
    },
    `gatsby-plugin-styled-components`,
    `gatsby-plugin-sass`,
    `gatsby-plugin-smoothscroll`,
    {
      resolve: "gatsby-plugin-google-tagmanager",
      options: {
        id: process.env.GATSBY_GOOGLE_TAGMANAGER_ID,
        includeInDevelopment: false,
        defaultDataLayer: { platform: "gatsby" },
        gtmAuth: process.env.GATSBY_GOOGLE_TAGMANAGER_ENVIRONMENT_AUTH_STRING,
        gtmPreview: process.env.GATSBY_GOOGLE_TAGMANAGER_ENVIRONMENT_PREVIEW_NAME,
        dataLayerName: process.env.GATSBY_DATA_LAYER_NAME,
      },
    },
    {
      resolve: 'gatsby-plugin-robots-txt',
      options: {
        host: 'https://www.mysite.com',
        sitemap: 'https://www.mysite.com/sitemap.xml',
        policy: [{ userAgent: '*', allow: '/' }]
      }
    },
    {
      resolve: `gatsby-plugin-sitemap`,
      options: {
        output: `/sitemap.xml`,
      }
    },
    {
      resolve: `gatsby-plugin-canonical-urls`,
      options: {
        siteUrl: `https://www.mysite.com`,
        stripQueryString: true,
      }
    },
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        start_url: `/`,
        background_color: `#3FB6E8`,
        theme_color: `#3FB6E8`,
        display: `minimal-ui`,
        icon: `src/images/favicon.png`, // This path is relative to the root of the site.
      },
    },
  ],
}

As this is a client site, I cannot share the site or source without approval. So I will see what I can share and post back.

Other similar issue ( https://github.com/gatsbyjs/gatsby/issues/22206 ) mention straight length of content in <head> tag so it might be that this is the case, but when I asked for some sources of this information author of the issue didn't have any (it was just something that he picked up in one of his projects).

So as experiment it might be worth to create dummy .html file (not even through Gatsby) with lots of content (<style>) and see how facebook open-graph debugger behaves as content gets bigger and bigger

Thank you @pieh for your responses!
Finally I managed to fix the issue.

The problem was with another plugin gatsby-plugin-intl and specifically with the redirect: true option.
What I did is to set the redirect option to false and handle the redirection to the default language of the website manually inside the gatsby-browser.js file and with the onClientEntry method.

In more detail, I noticed that previously, the .html file inside the public folder did not include the correct meta tags but for example the title tag was empty.
Now everything seems to work properly.

Thank you everyone for your responses.

Still seems to be an issue. Was able to get a demo site from client showing issue:
https://build-8dcdeb99-dcb2-4a8e-adb9-68f894b3ff54.gtsb.io/

And the FB scraper result still not showing meta:
https://developers.facebook.com/tools/debug/echo/?q=https%3A%2F%2Fbuild-8dcdeb99-dcb2-4a8e-adb9-68f894b3ff54.gtsb.io%2F

As the previous comment has shown this is most likely a problem in your project and not with Gatsby itself (e.g. a plugin changing the behavior). So we'll need to have a reproduction to best help you. And from just reading your short code snippets: The og:image is missing as you're not passing image to your <SEO /> component for example.

As the previous comment has shown this is most likely a problem in your project and not with Gatsby itself (e.g. a plugin changing the behavior). So we'll need to have a reproduction to best help you. And from just reading your short code snippets: The og:image is missing as you're not passing image to your <SEO /> component for example.

You're right, the image prop is not shown in code snippet. Additional data was being passed in seoHelmet prop, but neglected to include everything above.

Here is a reproduction from the client:
https://build-c25c29dc-ebf9-483f-87db-b7f37afa1ae3.gtsb.io/insights/insight-1/

For reference: https://github.com/EricPW/custom-gatsby-contentful-build

In templates / insight.js:

<SEO
    title={seo.title}
    description={seo.description}
    insightSEO
    pageUrl={props?.location?.href}
    image={image?.file?.url}
>
    {seoHelmet?.seoHelmet || null}
</SEO>

I have discovered that wrapping the Seo component with context providers inside wrapRootElement (exported from gatsby-ssr.js) causes this issue for me.

My current setup is something like this:

// gatsby-ssr.js

export const wrapRootElement = ({ element }) => (
  <ThemeProvider>
    {element}
  </ThemeProvider>
)
// some-page.jsx

const SomePage = () => (
  <Layout>
    <Seo
      title="some title"
      description="some description"
    />
   // other components here...
  </Layout>
)

Building the above app results in the index.html missing all the meta tags that are defined inside the Seo component.


If I render the Seo component inside wrapRootElement but still as a child of the provider, I get the same result.

Still doesn't work:

// gatsby-ssr.js

export const wrapRootElement = ({ element }) => (
  <ThemeProvider>
    <Seo title="some title" description="some description">
      {element}
    </Seo>
  </ThemeProvider>
)

However, if I render the Seo component outside the providers, then my index.html is built with all the meta tags defined in Seo.

This works:

// gatsby-ssr.js

export const wrapRootElement = ({ element }) => (
  <Seo title="some title" description="some description">
    <ThemeProvider>
      {element}
    </ThemeProvider>
  </Seo>
)

The problem is, I want different meta tags based on the current page.

Does anyone know how to solve this?

UPDATE:

I discovered that my ThemeProvider was skipping first render (in order to load dark vs light theme based on a localStorage value and prevent showing the incorrect color theme), and therefore the Seo component was not being rendered on the server.

Moving the SEO component up to wrapRootElement also made the og:tags etc. visible to Google, Twitter and Facebook for me again. Thank you!

I keep struggling though what the proper architecture should look like regarding these …

  • SeoComponent (only appears to work outside of ContextProvider for me)
  • ContextProvider (for global stuff like theme information, navigation state)
  • ContextConsumer
  • ThemeProvider
  • MDXProvider with Shortcodes

Questions I currently have:

  • Is this the correct order?
  • Which ones of these should go into wrapRootElement, which ones into wrapPageElement and which ones below that (Layout or Page component)?
  • Which ones should be part of gatsby-ssr, which ones part of gatsby-browser and which ones part of both?

I got some help on spectrum.chat ( https://spectrum.chat/gatsby-js/general/unable-to-generate-twitter-facebook-cards~852b7d81-b4fe-4843-8c6f-9917a3d5fb63?m=MTU4OTI5OTcwNTMwMw== ) and was now able to resolve the issue for me. The root cause was a mismatch between SSR and Runtime that I introduced some time ago and that led to the open graph meta tags not being rendered on the server side.

To solve it, I made sure, that gatsby-ssr.js and gatsby-browser.js are closely aligned (identical even in my case) and resolved the SSR errors which came to light while doing so (had been using window/document in some components in my case).

My architecture now looks somewhat like this:


  • wrapRootElement:

    • ContextProvider (for global stuff like theme information, navigation state)

    • ContextConsumer (for theme)

    • ThemeProvider

    • MDXProvider with Shortcodes


  • wrapPageElement:

    • ContextConsumer (for navigation state)

    • "GlobalComponents": Modals, Nav, Background and PageTransitions


  • PageTemplate / LayoutComponent

    - SeoComponent

A little note: Both, the Twitter Debugger and the Facebook Debugger didn't immediately show results after publishing the fix, so probably better to rely on checking public/index.html if the social graph/search tags there appear for debugging.

I'm going to close this as it looks like a user issue rather than a Gatsby error. Make sure you don't use clientside only paths.

Thanks so much for opening this issue! As stated, this is slightly tangential to Gatsby, and it seems like we’ve provided enough information to make an informed decision.

If this is not the case, or if we can help further--please don’t hesitate to reach out or comment on this issue, and we’d love to take another look.

Thanks for using Gatsby 💪

I'm also facing the same issue.. Metatags come after inline CSS in generated HTML. If CSS is too big, metatags are not parsed by Whatsapp (assuming they read first few KB)... How can I make sure that metatags are always printed on top with Helmet and css comes below that? Thanks?

og_problem

@jitendra-koodo check your index.html file in the build directory after running gatsby build to see if the meta tags are in there.

The tags will still appear in the HTML head when running in browser, even if they're not in index.html, but if they're not in index.html then they won't be picked up by third parties such as Twitter or Facebook.

@jitendra-koodo check your index.html file in the build directory after running gatsby build to see if the meta tags are in there.

The tags will still appear in the HTML head when running in browser, even if they're not in index.html, but if they're not in index.html then they won't be picked up by third parties such as Twitter or Facebook.

You can see it in the screenshot I attached above. Also If I remove CSS style tag manually it works.

Also this works on Twitter and FB, it does not work on whatsapp for the probable reason I mentioned above. Whatsapp probably reads first few KBs for metatags and if inline css is too big, it will not see any OG metatag.

If it works for Twitter and Facebook then this must be a WhatsApp specific issue. I'm not sure how WhatsApp handles open graph data but it doesn't look like this is a Gatsby-related error.

yes, its Whatsapp related problem and solution is to show metatags above style. My question is how can I do that? That is making sure that Helmet metatags are generated before style tags in generated index.html . Thanks for your help.

Should I open a new ticket for that?

@jitendra-koodo Not sure if it is advisable, but this comment here proposes a technique for changing the order of style and meta tags in the head section: https://github.com/gatsbyjs/gatsby/issues/9979#issuecomment-627344993
I didn‘t need nor try that technique, og: tags are picked up without it even on WhatsApp in my case

@jitendra-koodo Not sure if it is advisable, but this comment here proposes a technique for changing the order of style and meta tags in the head section: #9979 (comment)
I didn‘t need nor try that technique, og: tags are picked up without it even on WhatsApp in my case

This worked. Thanks. (This also verifies that Whatsapp reads limited first few KBs).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ferMartz picture ferMartz  ·  3Comments

jimfilippou picture jimfilippou  ·  3Comments

kalinchernev picture kalinchernev  ·  3Comments

Oppenheimer1 picture Oppenheimer1  ·  3Comments

KyleAMathews picture KyleAMathews  ·  3Comments