Closed monkishtypist closed 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=
<!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 [36m Previous CSS Size: 1022.38 KB
16:17:19.576 [36m New CSS Size: 20.94 KB (-97.95%)
16:17:19.576 [33m 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 passingimage
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?
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 …
Questions I currently have:
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.
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?
@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 runninggatsby 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 inindex.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).
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?
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
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.
I can't render meta tags in Twitter.
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
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!
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:
And a blog page teamplate that uses the SEO component like so:
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:
And here is the scraped page:
Here are some other fixes I tried...
gatsby-plugin-react-helmet
by defaultmaterial-ui
Environment
Run
gatsby info --clipboard
in your project directory and paste the output here.