Twitter 卡片图片不适用于 Gatsby 应用程序
Twitter Card Images not working on Gatsby app
我正在使用 Netlify CMS(并托管在 Netlify 上)开发 Gatsby 应用程序。尝试让元数据正常工作,以便 Twitter 卡片正确显示图像。
元数据通常没问题,但图像未显示在 Twitter 验证器上,或者如果我尝试 post 到 Twitter。问题显然出在图像本身,这些图像托管在使用 Gatsby 和 Gatsby Image Sharp 渲染的网站上。
事实上,the validator似乎没有显示出任何基本问题。很简单,图像没有显示:
相关元数据示例:
<meta name="twitter:url" content="https://example.com/" data-react-helmet="true">
<meta name="twitter:image" content="https://example.com/static/12345/c5b20/blah.jpg" data-react-helmet="true">
<meta data-react-helmet="true" name="twitter:title" content="Site title">
<meta data-react-helmet="true" name="twitter:card" content="summary_large_image">
我知道图像的问题,因为如果我用外部 URL 替换我的图像 URL(这是完整图像 URL),它工作正常,显示带图片的完整卡片。
知道是什么原因造成的吗?我正在缩小图像的尺寸以便快速加载,而且它似乎直接加载就很好 (eg)。 (我的意思是,那张图片有什么 weird/off 吗?)
注意: 在此问题的先前版本中,我引用了 Cloudinary 和 Uploadcare,但后来在一个分支中删除了这两个以简化问题。 (它们似乎是我使用的入门应用程序的不必要保留。)您现在可以看到该分支 here and the associated image in the twitter:image
tag here 的示例页面。我使用 React Helmet(和 Gatsby React Helmet)将此 pre-processed/shrunk 图像输入 header,并在我的 GraphQL 调用中使用以下代码来获取与特定博客 post 关联的图像, 较小的格式:
featuredimage {
childImageSharp {
fixed(width: 480, quality: 75) {
src
}
}
第二个 Note/thought: 我是否应该担心生产中的页面在每次重新加载时似乎都是 re-rendering? SSR 不是应该确保 不会 发生吗?我通过在页面中隐藏对 Math.random()
的调用来对此进行测试。您可以通过 运行 document.getElementsByClassName('document')[0].children[0].innerText
查看结果,并注意它在每次重新加载页面时产生不同的数字。这对我来说意味着整个页面都被客户re-rendered。是不是错了?为什么会这样?这可能与客户端对每个请求的图像进行某种处理有关,这可能会搞砸 Twitter 卡片?
第三次更新:我整理了一个更简单的复现here. It's based off of this starter template, with Uploadcare/Cloudinary removed and Twitter card metadata added to the header. Other than that, and removing unnecessary pages, I didn't make any other changes. I used this starter for a repro rather than a vanilla starter app, because I'm unsure whether the issue is caused by the interaction of Netlify CMS and the Gatsby Sharp Image plugin. I might try to put together a second reproduction. For now, the code for this repo is here, and the pages that should show Twitter cards are the blog posts, such as this one。
ACTUALLY,似乎 super basic 复制品,使用 Gatsby 3 而没有 Netlify CMS 或任何东西,有同样的问题。 Here's the minimal reproduction, with the image taken from src/images
using an allImageSharp
query and inserted into the metadata for each page. Code here.
最终更新
根据下面 Derek 的回答,我删除了 @reach/router
内容,并从 Netlify 构建环境变量中获取了站点 URL。似乎 @reach/router
仅在 JS 为 运行 时提供此信息,这排除了 Twitterbot,导致 undefined
基础 URL,从而破坏了 Twitter 图像。包括来自 Netlify 的 URL(在 Gatsby 配置中使用 process.env.URL
并通过 siteMetadata 查询将其拉入)解决了问题!
更新:
我想我可能已经找到了问题所在。在禁用脚本的情况下打开最小生产时,twitter:image
的 url 无效:
<meta data-react-helmet="true" name="twitter:image" content="undefined/static/03475800ca60d2a62669c6ad87f5fda0/58026/energy.jpg">
所以由于某些原因,在构建过程中,主机名丢失了,但是当 JS 启动时,它出现了(可能与您获取主机名的方式有关)。 Twitter 爬虫可能没有启用 JS 并且无法获取图像。
确保您的 opengraph 图像是 absolute urls with https://
or http://
protocols. 我检查了您的示例 link 并发现它是亲戚 link (/static/etc.)
对于推特,似乎要求社交卡是2:1
Images for this Card support an aspect ratio of 2:1 with minimum dimensions of 300x157 or maximum of 4096x4096 pixels.
如果您使用的是最新的 Gatsby 图片插件,您可以使用 aspectRatio 裁剪图片。
另请注意,如果您的 og:image
已经满足 Twitter 的卡片要求,您可以跳过 twitter:image
标签。
SSR 并不意味着永远不会 运行 客户端中的 JS,React 将在客户端呈现您的页面,而不管 SSR。
已在此处解决:https://github.com/gatsbyjs/gatsby/discussions/32100。
"location
,因此 origin
在 gatsby build
期间不可用,因此生成的 HTML 在那里未定义。"
我通过更改我在 seo.js
中创建图像 URL 的方式来实现它:
let origin = "";
if (typeof window !== "undefined") {
origin = window.location.origin;
}
const image = origin + imageSrc;
对此:
const imageSrc = thumbnail && thumbnail.childImageSharp.fixed.src;
const image = site.siteMetadata?.siteUrl + imageSrc;
您需要使用 siteMetadata
中的 siteUrl
。
下面是我的 pageQuery
来自 blog-post.js
:
export const pageQuery = graphql`
query BlogPostBySlug(
$id: String!
$previousPostId: String
$nextPostId: String
) {
site {
siteMetadata {
title
siteUrl
}
}
markdownRemark(id: { eq: $id }) {
id
excerpt(pruneLength: 160)
html
frontmatter {
title
date(formatString: "MMMM DD, YYYY")
description
thumbnail {
childImageSharp {
fixed(width: 1200) {
...GatsbyImageSharpFixed
}
}
}
}
}
}
`
我正在使用 Netlify CMS(并托管在 Netlify 上)开发 Gatsby 应用程序。尝试让元数据正常工作,以便 Twitter 卡片正确显示图像。
元数据通常没问题,但图像未显示在 Twitter 验证器上,或者如果我尝试 post 到 Twitter。问题显然出在图像本身,这些图像托管在使用 Gatsby 和 Gatsby Image Sharp 渲染的网站上。
事实上,the validator似乎没有显示出任何基本问题。很简单,图像没有显示:
相关元数据示例:
<meta name="twitter:url" content="https://example.com/" data-react-helmet="true">
<meta name="twitter:image" content="https://example.com/static/12345/c5b20/blah.jpg" data-react-helmet="true">
<meta data-react-helmet="true" name="twitter:title" content="Site title">
<meta data-react-helmet="true" name="twitter:card" content="summary_large_image">
我知道图像的问题,因为如果我用外部 URL 替换我的图像 URL(这是完整图像 URL),它工作正常,显示带图片的完整卡片。
知道是什么原因造成的吗?我正在缩小图像的尺寸以便快速加载,而且它似乎直接加载就很好 (eg)。 (我的意思是,那张图片有什么 weird/off 吗?)
注意: 在此问题的先前版本中,我引用了 Cloudinary 和 Uploadcare,但后来在一个分支中删除了这两个以简化问题。 (它们似乎是我使用的入门应用程序的不必要保留。)您现在可以看到该分支 here and the associated image in the twitter:image
tag here 的示例页面。我使用 React Helmet(和 Gatsby React Helmet)将此 pre-processed/shrunk 图像输入 header,并在我的 GraphQL 调用中使用以下代码来获取与特定博客 post 关联的图像, 较小的格式:
featuredimage {
childImageSharp {
fixed(width: 480, quality: 75) {
src
}
}
第二个 Note/thought: 我是否应该担心生产中的页面在每次重新加载时似乎都是 re-rendering? SSR 不是应该确保 不会 发生吗?我通过在页面中隐藏对 Math.random()
的调用来对此进行测试。您可以通过 运行 document.getElementsByClassName('document')[0].children[0].innerText
查看结果,并注意它在每次重新加载页面时产生不同的数字。这对我来说意味着整个页面都被客户re-rendered。是不是错了?为什么会这样?这可能与客户端对每个请求的图像进行某种处理有关,这可能会搞砸 Twitter 卡片?
第三次更新:我整理了一个更简单的复现here. It's based off of this starter template, with Uploadcare/Cloudinary removed and Twitter card metadata added to the header. Other than that, and removing unnecessary pages, I didn't make any other changes. I used this starter for a repro rather than a vanilla starter app, because I'm unsure whether the issue is caused by the interaction of Netlify CMS and the Gatsby Sharp Image plugin. I might try to put together a second reproduction. For now, the code for this repo is here, and the pages that should show Twitter cards are the blog posts, such as this one。
ACTUALLY,似乎 super basic 复制品,使用 Gatsby 3 而没有 Netlify CMS 或任何东西,有同样的问题。 Here's the minimal reproduction, with the image taken from src/images
using an allImageSharp
query and inserted into the metadata for each page. Code here.
最终更新
根据下面 Derek 的回答,我删除了 @reach/router
内容,并从 Netlify 构建环境变量中获取了站点 URL。似乎 @reach/router
仅在 JS 为 运行 时提供此信息,这排除了 Twitterbot,导致 undefined
基础 URL,从而破坏了 Twitter 图像。包括来自 Netlify 的 URL(在 Gatsby 配置中使用 process.env.URL
并通过 siteMetadata 查询将其拉入)解决了问题!
更新:
我想我可能已经找到了问题所在。在禁用脚本的情况下打开最小生产时,twitter:image
的 url 无效:
<meta data-react-helmet="true" name="twitter:image" content="undefined/static/03475800ca60d2a62669c6ad87f5fda0/58026/energy.jpg">
所以由于某些原因,在构建过程中,主机名丢失了,但是当 JS 启动时,它出现了(可能与您获取主机名的方式有关)。 Twitter 爬虫可能没有启用 JS 并且无法获取图像。
确保您的 opengraph 图像是 absolute urls with https://
or http://
protocols. 我检查了您的示例 link 并发现它是亲戚 link (/static/etc.)
对于推特,似乎要求社交卡是2:1
Images for this Card support an aspect ratio of 2:1 with minimum dimensions of 300x157 or maximum of 4096x4096 pixels.
如果您使用的是最新的 Gatsby 图片插件,您可以使用 aspectRatio 裁剪图片。
另请注意,如果您的 og:image
已经满足 Twitter 的卡片要求,您可以跳过 twitter:image
标签。
SSR 并不意味着永远不会 运行 客户端中的 JS,React 将在客户端呈现您的页面,而不管 SSR。
已在此处解决:https://github.com/gatsbyjs/gatsby/discussions/32100。
"location
,因此 origin
在 gatsby build
期间不可用,因此生成的 HTML 在那里未定义。"
我通过更改我在 seo.js
中创建图像 URL 的方式来实现它:
let origin = "";
if (typeof window !== "undefined") {
origin = window.location.origin;
}
const image = origin + imageSrc;
对此:
const imageSrc = thumbnail && thumbnail.childImageSharp.fixed.src;
const image = site.siteMetadata?.siteUrl + imageSrc;
您需要使用 siteMetadata
中的 siteUrl
。
下面是我的 pageQuery
来自 blog-post.js
:
export const pageQuery = graphql`
query BlogPostBySlug(
$id: String!
$previousPostId: String
$nextPostId: String
) {
site {
siteMetadata {
title
siteUrl
}
}
markdownRemark(id: { eq: $id }) {
id
excerpt(pruneLength: 160)
html
frontmatter {
title
date(formatString: "MMMM DD, YYYY")
description
thumbnail {
childImageSharp {
fixed(width: 1200) {
...GatsbyImageSharpFixed
}
}
}
}
}
}
`