On a Gatsby site I have an SEO component seo.js
using React Helmet that is called inside a blog template blog.js
. However Facebook Share does not recognize the opengraph tags. The site is hosted on Gatsby Cloud, not Netlify.
I’ve searched the webs for answers but can’t find anything. This post did not pan out. It does not appear to be caching and re-scraping does nothing.
Tags appear of course when viewing page source directly. At a total loss here. Other sites with similar setups work fine. ¯_(ツ)_/¯
If anyone has had similar issues, I’d love to hear how they fixed this. Thoughts? Thanks.
Code and error examples below:
# 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
# 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: March 26, 2020, order: DESC }
limit: $limit
skip: $skip
) {
edges {
node {
id
title
slug
date
preview
text {
json
}
image {
localFile {
...blogThumbnail
}
}
category {
name
slug
}
}
}
}
}
`
export default Blog
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
Facebook Sharing Debugger scraped URL result:
<!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>
Edit Here are some other fixes I tried…
- checked for .htaccess issues
- checked if caching issue
- using
gatsby-plugin-react-helmet
by default - tried disabling other plugins such as
material-ui
Edit 2 from my 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.18.12",
"gatsby-background-image": "^0.9.12",
"gatsby-cli": "^2.9.0",
"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.3.5",
"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"
},
3
Answers
Have you tried something similar? It seems that your
Helmet
component is closed before setting up your metadata.We’ve stumbled upon this issue recently. We’ve fixed this, please check if:
I think Google and Facebook both have issues with helmet because of the extra property
data-react-helmet
that helmet add, see: https://github.com/nfl/react-helmet/issues/79to solve this issue you can add this code to your
gatsby-ssr.js