我刚刚开始学习 Gatsby,我刚刚从 gatsby 模板导入了一个 gatsby 项目。我的 og:image
显示不同的 Open graph 标签有问题,我想显示文章的缩略图。
例如这篇文章 - https://www.armanism.com/blog/install-nginx-on-ubuntu 当我尝试从 Twitter 卡验证器获取数据时,它显示重定向到“https://www.armanism.com/blog/install-nginx-on-ubuntu”到“https://www.armanism.com/博客/install-nginx-on-ubuntu/"
有人可以帮我解决这个问题吗?
这是我的 gatsby SEO 配置
/* Vendor imports */
import React from 'react';
import PropTypes from 'prop-types';
import { Helmet } from 'react-helmet';
import { StaticQuery, graphql } from 'gatsby';
/* App imports */
import Config from '../../../config';
import Utils from '../../utils/pageUtils';
const detailsQuery = graphql`
query DefaultSEOQuery {
file(name: { eq: "facebook-icon" }) {
childImageSharp {
fixed(width: 600) {
...GatsbyImageSharpFixed_noBase64
}
}
}
}
`;
function SEO({
title,
description,
path,
lang,
keywords,
contentType,
imageUrl,
translations,
meta,
}) {
return (
<StaticQuery
query={detailsQuery}
render={(data) => {
const metaKeywords = keywords && keywords.length > 0
? { name: 'keywords', content: keywords.join(', ') }
: [];
const pageUrl = Utils.resolvePageUrl(
Config.siteUrl,
Config.pathPrefix,
path,
);
const fixpageUrl = pageUrl.replace('/https://', 'https://');
const metaImageUrl = Utils.resolveUrl(
Config.siteUrl,
imageUrl || data.file.childImageSharp.fixed.src,
);
const fixmetaImageUrl = metaImageUrl.replace('/https://', 'https://');
return (
<Helmet
title={title} // Page title
titleTemplate={`%s – ${Config.siteTitle}`}
meta={
[
{ name: 'description', content: `${description.substring(0, 160)}...` }, // Page description
/* Open Graph */
{ property: 'og:title', content: title },
{ property: 'og:type', content: contentType || 'website' },
{ property: 'og:url', content: fixpageUrl },
{ property: 'og:description', content: `${description.substring(0, 160)}...` },
{ property: 'og:image', content: fixmetaImageUrl },
{ property: 'og:image:alt', content: title },
{ property: 'og:site_name', content: Config.siteTitle },
{ property: 'og:locale', content: lang || 'en_US' },
/* Twitter card */
{ name: 'twitter:card', content: 'summary_large_image' },
{ name: 'twitter:title', content: title },
{ name: 'twitter:description', content: `${description.substring(0, 160)}...` },
{ name: 'twitter:image', content: fixmetaImageUrl },
{ name: 'twitter:image:alt', content: title },
{ name: 'twitter:site', content: Config.author },
{ name: 'twitter:creator', content: Config.author },
]
.concat(metaKeywords) // Keywords
.concat(meta || []) // Other provided metadata
}
link={[
{ rel: 'canonical', href: fixpageUrl }, // Canonical url
]
// Translated versions of page
.concat(
translations
? translations.map((obj) => ({
rel: 'alternate',
hreflang: obj.hreflang,
href: Utils.resolvePageUrl(
Config.siteUrl,
Config.pathPrefix,
obj.path,
),
}))
: [],
)}
/>
);
}}
/>
);
}
SEO.propTypes = {
title: PropTypes.string.isRequired,
description: PropTypes.string.isRequired,
path: PropTypes.string.isRequired,
lang: PropTypes.string,
contentType: PropTypes.oneOf(['article', 'website']),
imageUrl: PropTypes.string,
keywords: PropTypes.arrayOf(PropTypes.string),
translations: PropTypes.arrayOf(
PropTypes.shape({
hreflang: PropTypes.string.isRequired,
path: PropTypes.string.isRequired,
}),
),
meta: PropTypes.arrayOf(
PropTypes.shape({
property: PropTypes.string.isRequired,
content: PropTypes.string.isRequired,
}),
),
};
SEO.defaultProps = {
lang: 'en_US',
contentType: 'website',
imageUrl: null,
keywords: [],
translations: [],
meta: [],
};
export default SEO;
这是我的 PageUtils 代码
/* eslint-disable no-param-reassign */
const Config = require('../../config');
const Utils = {
/**
* Join provided url paths.
* @param {...string} paths Provided paths. It doesn't matter if they have trailing slash.
* @return {string} Resolved url without trailing slash.
*/
resolveUrl: (...paths) => paths.reduce((resolvedUrl, path) => {
const urlPath = path.toString().trim();
if (urlPath) {
// eslint-disable-next-line no-param-reassign
resolvedUrl
+= (resolvedUrl === '' ? '' : '/') + urlPath.replace(/^\/|\/$/g, '');
}
resolvedUrl = resolvedUrl[0] !== '/' ? `/${resolvedUrl}` : resolvedUrl;
return resolvedUrl;
}, ''),
/**
* Resolve a page url adding a trailing slash.
* Needed to prevent 301 redirects cause of Gatsby.js' folder structure.
* @param {...string} path Provided paths. It doesn't matter if they have trailing slash.
* @return {string} Resolved url with trailing slash.
*/
resolvePageUrl: (...path) => {
const resolvedUrl = Utils.resolveUrl(...path);
return resolvedUrl;
},
/**
* Get an ordered list of suggested posts for a single post.
* @param {Object} post The single post of which to find the related posts.
* It's the returned object from Graphql's query `markdownRemark`
* @param {Array} postList The list where find related posts. It's the returned
* object from Graphql's query `allMarkdownRemark`
* @param {number} limit The maximum number of suggested posts to get
* @return {Array} The `postList` object sorted according to the best match with the `post` object
*/
getSuggestedPosts: (post, postList, limit) => {
// Get the number of common tags with provided post.
const getTagScore = (edge) => {
let commonTags = 0;
edge.node.frontmatter.tags.forEach((tag) => {
commonTags += post.frontmatter.tags.indexOf(tag) !== -1 ? 1 : 0;
});
return commonTags;
};
return postList.edges
.sort((edgeA, edgeB) => getTagScore(edgeB) - getTagScore(edgeA))
.slice(0, limit);
},
/**
* Pass a post and retrieve a list of related translations.
* @param {Object} post The post of which retrieve its translations.
* It accepts a `node` object from Graphql's query `allMarkdownRemark`
* @param {Object} postList The list of posts where search translations.
* It accepts a `edges` array from Graphql's query `allMarkdownRemark`
* @return {Object} An array of objects with languages as keys (ISO 639-1) and
* translated post's paths as values.
*/
getRelatedTranslations: (post, postList) => postList
.filter(({ node }) =>
// Get posts in the same folder of provided post
// eslint-disable-next-line implicit-arrow-linebreak
(
node.fileAbsolutePath.split('/').slice(-2, -1)[0]
=== post.fileAbsolutePath.split('/').slice(-2, -1)[0]
))
.map(({ node }) => {
const lang = node.fileAbsolutePath.split('.').slice(-2, -1)[0];
return {
hreflang: lang.slice(-5) !== 'index' ? lang : Config.defaultLanguage,
path: Utils.resolvePageUrl(node.frontmatter.path),
};
}),
/**
* Capitalize passed string
* @param {string} str string to capitalize
* @return {string} string with first letter to uppercase
*/
capitalize: (str) => str[0].toUpperCase() + str.slice(1),
};
module.exports = Utils;
如果您需要任何其他信息,请告诉我
提前致谢
答案 0 :(得分:0)
我认为您的问题与您的 SEO
组件或您的项目功能本身无关。我认为您的问题依赖于文章创建 (gatsby-node.js
),因为它使用尾部斜杠创建 URL,因此附加到该逻辑的所有配置和参数都会继承它。
检查如何在 path
参数中创建文章:
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({
path: node.fields.slug.replace(/\/$/, ''); // original code: node.fields.slug,
component: path.resolve(`./src/templates/blog-post.js`),
context: {
slug: node.fields.slug.replace(/\/$/, '')
},
})
})
注意:基于 Gatsby's tutorial。调整它以适应您的需求。
替代 replace
函数,您可以使用多种字符串操作函数之一,例如:
(node.fields.slug.charAt(node.fields.slug.length - 1) === '/') ? node.fields.slug.slice(0, -1) : node.fields.slug;
或者:
node.fields.slug.endsWith('/') ? node.fields.slug.slice(0, -1) : node.fields.slug;
此外,您还可以使用 gatsby-plugin-remove-trailing-slashes
插件。