gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.19k stars 10.33k forks source link

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

Closed monkishtypist closed 4 years ago

monkishtypist commented 4 years ago

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
XavierGeerinck commented 4 years ago

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>
vasnakos commented 4 years ago

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

XavierGeerinck commented 4 years ago

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.

XavierGeerinck commented 4 years ago

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
pieh commented 4 years ago

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?

vasnakos commented 4 years ago

@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.

pieh commented 4 years ago

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

monkishtypist commented 4 years ago

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.

pieh commented 4 years ago

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

vasnakos commented 4 years ago

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.

monkishtypist commented 4 years ago

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

LekoArts commented 4 years ago

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.

monkishtypist commented 4 years ago

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>
jmadelaine commented 4 years ago

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.

bruskowski commented 4 years ago

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 …

Questions I currently have:

bruskowski commented 4 years ago

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:




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.

wardpeet commented 4 years ago

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 💪

jitendra-koodo commented 4 years ago

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

jmadelaine commented 4 years ago

@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 commented 4 years ago

@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.

jmadelaine commented 4 years ago

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.

jitendra-koodo commented 4 years ago

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?

bruskowski commented 4 years ago

@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 commented 4 years ago

@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).

amalitsky commented 2 years ago

Folks, thanks for the discussion!

I still do not understand what is the right approach for using react-helmet with SSR and MUI ThemeProvider wrapper. Moving Seo component out of ThemeProvider is not an option for me because those meta tags are content dependent and actual content is defined in the deeply nested component.

I'd appreciate some information on how to debug this issue beyond checking html files rendered in public folder after executing gatsby build.

At this moment I don't have clear understanding on how Helmet.renderStatic works during the SSG build. I also don't understand what does it have to do with the context - I couldn't find anything context related in react-helmet, nor in gatsby-plugin-react-helmet packages source code.

In my case some pre-rendered pages have no meta tags at all (<title data-react-helmet="true"></title>) while others get stale information belonging to previously pre-rendered pages.

Some of my pages are created with createPage API calls. But "normal" pages are also affected.

My gatsby-browser and gatsby-ssr files are "in sync", meaning they are exporting same wrapPageElement and wrapRootElement (where ThemeProvider is defined) functions.

Also there is an issue with react-helmet relying on synchronous rendering - it that requirement met during SSR build via Gatsby? Looks like there is a few "async" versions of react-helmet but mb this is not supposed to be an issue with Gatsby?

amalitsky commented 2 years ago

I think concurrency (and related race condition) might be coming from here: https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/utils/worker/child/render-html.ts#L208

More on the subject in relation to helmet and MUI plugins: https://github.com/hupe1980/gatsby-plugin-material-ui/issues/80#issuecomment-965909424

mixdmark commented 2 years ago

There are multiple discussions about similar issues with meta information not showing up in Facebook scraper. Most of the discussion points to reordering tags in the page head. And solutions are offered for SSR rendering by updating gatsby-ssr.js.

How can I solve the same issue with SSG rendering, which does not use gatsby-ssr.js? My pages are created in gatsby-node.js dynamically. exports.onPreRenderHTML does not seem to work there.

animanoir commented 2 years ago

I can't render meta tags in Twitter.

1-800-jono commented 1 year ago

Having the same problem as @amalitsky

In my case some pre-rendered pages have no meta tags at all () while others get stale information belonging to previously pre-rendered pages.

I think it started happening after migrating from Gatsby v2 to v3.

Correct meta tags show up in dev tool but not when view source

PauloLuan commented 1 year ago

I faced the same issue, and I solved it by:

Check if your are properly using wrapRootElement and wrapPageElement APIs. The first is “useful to set up any Provider components that will wrap your application” and the second one ”set persistent UI elements around pages”. See Gatsby docs for more info.

If you use wrapRootElement and wrapPageElement, don’t forget to implement it both in gatsby-browser.js and gatsby-ssr.js.

An example on how to configure both wrapRootElement and wrapPageElement:

export const wrapRootElement = ({ element }) => (
  <ThemeProvider>
    {element}
  </ThemeProvider>
)

export const wrapPageElement = ({ element }) => (
  <>
    <GlobalStyles />
    <Navbar />
    <MDXStyles>
      {element}
    </MDXStyles>
    <ScrollToTop />
    <Footer />
  </>
);

I'm using Gatsby v5+, Material UI, gatsby-plugin-material-ui, gatsby-theme-material-ui and it's working!