Gatsby 更新盖茨比博客上的发布日期
我需要一点我的网站的方向。我想在编辑博客时更新其发布日期。日期是slug的一部分,但不是完成URL的一部分。我的网址是wesite.com/blog,这很好。我只是不确定谷歌是否会选择这个日期。我在元数据中没有看到它 但是,当我更改该日期时,它将无法完成构建。它失败了,我必须恢复。另一个选择是不向谷歌提供日期。我想我可以从gatsby配置中删除它,但我不确定如何验证它。我没有在博客页面上显示发布日期,但它在meta中,并显示在SERP中。以前有人碰到过这个吗Gatsby 更新盖茨比博客上的发布日期,gatsby,Gatsby,我需要一点我的网站的方向。我想在编辑博客时更新其发布日期。日期是slug的一部分,但不是完成URL的一部分。我的网址是wesite.com/blog,这很好。我只是不确定谷歌是否会选择这个日期。我在元数据中没有看到它 但是,当我更改该日期时,它将无法完成构建。它失败了,我必须恢复。另一个选择是不向谷歌提供日期。我想我可以从gatsby配置中删除它,但我不确定如何验证它。我没有在博客页面上显示发布日期,但它在meta中,并显示在SERP中。以前有人碰到过这个吗 require("
require("dotenv").config();
const config = require("./content/meta/config");
const transformer = require("./src/utils/algolia");
const query = `{
allMarkdownRemark( filter: { fields: { slug: { ne: null } } }) {
edges {
node {
objectID: fileAbsolutePath
fields {
slug
}
internal {
content
}
frontmatter {
title
}
}
}
}
}`;
const queries = [
{
query,
transformer: ({ data }) => {
return data.allMarkdownRemark.edges.reduce(transformer, []);
}
}
];
module.exports = {
// pathPrefix: config.pathPrefix,
siteMetadata: {
title: config.siteTitle,
description: config.siteDescription,
siteUrl: config.siteUrl,
algolia: {
appId: process.env.ALGOLIA_APP_ID ? process.env.ALGOLIA_APP_ID : "",
searchOnlyApiKey: process.env.ALGOLIA_SEARCH_ONLY_API_KEY
? process.env.ALGOLIA_SEARCH_ONLY_API_KEY
: "",
indexName: process.env.ALGOLIA_INDEX_NAME ? process.env.ALGOLIA_INDEX_NAME : ""
},
facebook: {
appId: process.env.FB_APP_ID ? process.env.FB_APP_ID : ""
}
},
plugins: [
`gatsby-plugin-styled-jsx`, // the plugin's code is inserted directly to gatsby-node.js and gatsby-ssr.js files
`gatsby-plugin-styled-jsx-postcss`, // as above
{
resolve: `gatsby-plugin-layout`,
options: {
component: require.resolve(`./src/layouts/`)
}
},
{
resolve: `gatsby-plugin-algolia`,
options: {
appId: process.env.ALGOLIA_APP_ID ? process.env.ALGOLIA_APP_ID : "",
apiKey: process.env.ALGOLIA_ADMIN_API_KEY ? process.env.ALGOLIA_ADMIN_API_KEY : "",
indexName: process.env.ALGOLIA_INDEX_NAME ? process.env.ALGOLIA_INDEX_NAME : "",
queries,
chunkSize: 10000 // default: 1000
}
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images/`
}
},
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/content/posts/`,
name: "posts"
}
},
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/content/pages/`,
name: "pages"
}
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `parts`,
path: `${__dirname}/content/parts/`
}
},
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
`gatsby-plugin-sharp`,
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 800,
backgroundColor: "transparent"
}
},
{
resolve: `gatsby-plugin-google-adsense`,
options: {
googleAdClientId: "***********",
head: true // Optional
}
},
{
resolve: `gatsby-remark-responsive-iframe`,
options: {
wrapperStyle: `margin-bottom: 2em`
}
},
`gatsby-remark-prismjs`,
`gatsby-remark-copy-linked-files`,
`gatsby-remark-smartypants`,
{
resolve: "gatsby-remark-emojis",
options: {
// Deactivate the plugin globally (default: true)
active: true,
// Add a custom css class
class: "emoji-icon",
// Select the size (available size: 16, 24, 32, 64)
size: 64,
// Add custom styles
styles: {
display: "inline",
margin: "0",
"margin-top": "1px",
position: "relative",
top: "5px",
width: "25px"
}
}
}
]
}
},
`gatsby-plugin-sharp`,
`gatsby-transformer-sharp`,
`gatsby-plugin-react-helmet`,
`gatsby-plugin-catch-links`,
{
resolve: `gatsby-plugin-manifest`,
options: {
name: config.manifestName,
short_name: config.manifestShortName,
start_url: config.manifestStartUrl,
background_color: config.manifestBackgroundColor,
theme_color: config.manifestThemeColor,
display: config.manifestDisplay,
icons: [
{
src: "/icons/icon-48x48.png",
sizes: "48x48",
type: "image/png"
},
{
src: "/icons/icon-96x96.png",
sizes: "96x96",
type: "image/png"
},
{
src: "/icons/icon-144x144.png",
sizes: "144x144",
type: "image/png"
},
{
src: "/icons/icon-192x192.png",
sizes: "192x192",
type: "image/png"
},
{
src: "/icons/icon-256x256.png",
sizes: "256x256",
type: "image/png"
},
{
src: "/icons/icon-384x384.png",
sizes: "384x384",
type: "image/png"
},
{
src: "/icons/icon-512x512.png",
sizes: "512x512",
type: "image/png"
}
]
}
},
`gatsby-plugin-offline`,
{
resolve: `gatsby-plugin-google-analytics`,
options: {
trackingId: process.env.GOOGLE_ANALYTICS_ID
}
},
{
resolve: `gatsby-plugin-feed`,
options: {
query: `
{
site {
siteMetadata {
title
description
siteUrl
site_url: siteUrl
}
}
}
`,
feeds: [
{
serialize: ({ query: { site, allMarkdownRemark } }) => {
return allMarkdownRemark.edges.map(edge => {
return Object.assign({}, edge.node.frontmatter, {
description: edge.node.excerpt,
date: edge.node.fields.prefix,
url: site.siteMetadata.siteUrl + edge.node.fields.slug,
guid: site.siteMetadata.siteUrl + edge.node.fields.slug,
custom_elements: [{ "content:encoded": edge.node.html }]
});
});
},
query: `
{
allMarkdownRemark(
limit: 1000,
sort: { order: DESC, fields: [fields___prefix] },
filter: {
fields: {
prefix: { ne: null },
slug: { ne: null }
},
frontmatter: {
author: { ne: null }
}
}
) {
edges {
node {
excerpt
html
fields {
slug
prefix
}
frontmatter {
title
}
}
}
}
}
`,
output: "/rss.xml"
}
]
}
},
{
resolve: `gatsby-plugin-sitemap`
},
{
resolve: "gatsby-plugin-react-svg",
options: {
include: /svg-icons/
}
}
]
};
还有seo.js
import React from "react";
import PropTypes from "prop-types";
import Helmet from "react-helmet";
import config from "../../../content/meta/config";
const Seo = props => {
const { data, facebook } = props;
const postTitle = ((data || {}).frontmatter || {}).title;
const postDescription = ((data || {}).frontmatter || {}).description;
const postCover = ((data || {}).frontmatter || {}).cover;
const postSlug = ((data || {}).fields || {}).slug;
const title = postTitle ? `${postTitle} - ${config.shortSiteTitle}` : config.siteTitle;
const description = postDescription ? postDescription : config.siteDescription;
const image = postCover ? postCover : config.siteImage;
const url = config.siteUrl + config.pathPrefix + postSlug;
return (
<Helmet
htmlAttributes={{
lang: config.siteLanguage,
prefix: "og: http://ogp.me/ns#"
}}
>
{/* General tags */}
<title>{title}</title>
<meta name="description" content={description} />
<meta name="msvalidate.01" content="17E3A9A27963C3889459D03DA4268BA3" />
{/* OpenGraph tags */}
<meta property="og:url" content={url} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={image} />
<meta property="og:type" content="website" />
<meta property="fb:app_id" content={facebook.appId} />
{/* Twitter Card tags */}
<meta name="twitter:card" content="summary" />
<meta
name="twitter:creator"
content={config.authorTwitterAccount ? config.authorTwitterAccount : ""}
/>
</Helmet>
);
};
Seo.propTypes = {
data: PropTypes.object,
facebook: PropTypes.object.isRequired
};
export default Seo;
您的查询不包括日期-您需要修改查询,使日期显示在那里(它只在slug中,并按照代码现在读取的方式输入),日期在哪里?此外,要检查如何创建帖子的URL,需要提供
gatsby node.js
文件。谢谢,我将添加它
//const webpack = require("webpack");
const _ = require("lodash");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
const path = require("path");
const Promise = require("bluebird");
const { createFilePath } = require(`gatsby-source-filesystem`);
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions;
if (node.internal.type === `MarkdownRemark`) {
const slug = createFilePath({ node, getNode });
const fileNode = getNode(node.parent);
const source = fileNode.sourceInstanceName;
const separtorIndex = ~slug.indexOf("--") ? slug.indexOf("--") : 0;
const shortSlugStart = separtorIndex ? separtorIndex + 2 : 0;
if (source !== "parts") {
createNodeField({
node,
name: `slug`,
value: `${separtorIndex ? "/" : ""}${slug.substring(shortSlugStart)}`
});
}
createNodeField({
node,
name: `prefix`,
value: separtorIndex ? slug.substring(1, separtorIndex) : ""
});
createNodeField({
node,
name: `source`,
value: source
});
}
};
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions;
return new Promise((resolve, reject) => {
const postTemplate = path.resolve("./src/templates/PostTemplate.js");
const pageTemplate = path.resolve("./src/templates/PageTemplate.js");
const categoryTemplate = path.resolve("./src/templates/CategoryTemplate.js");
let activeEnv = process.env.ACTIVE_ENV || process.env.NODE_ENV || "development";
console.log(`Using environment config: '${activeEnv}'`);
resolve(
graphql(
`
{
allMarkdownRemark(
filter: { fields: { slug: { ne: null } } }
sort: { fields: [fields___prefix], order: DESC }
limit: 1000
) {
edges {
node {
id
fields {
slug
prefix
source
}
frontmatter {
title
category
}
}
}
}
}
`
).then(result => {
if (result.errors) {
console.log(result.errors);
reject(result.errors);
}
// Do not create draft post files in production.
const items = result.data.allMarkdownRemark.edges.filter(item => {
if (item.node.fields.source != "posts") return true;
if (activeEnv != "production") return true;
return item.node.fields.prefix.length > 0;
});
// Create category list
const categorySet = new Set();
items.forEach(edge => {
const {
node: {
frontmatter: { category }
}
} = edge;
if (category && category !== null) {
categorySet.add(category);
}
});
// Create category pages
const categoryList = Array.from(categorySet);
categoryList.forEach(category => {
createPage({
path: `/category/${_.kebabCase(category)}/`,
component: categoryTemplate,
context: {
category
}
});
});
// Create posts
const posts = items.filter(item => item.node.fields.source === "posts");
posts.forEach(({ node }, index) => {
const slug = node.fields.slug;
const next = index === 0 ? undefined : posts[index - 1].node;
const prev = index === posts.length - 1 ? undefined : posts[index + 1].node;
const source = node.fields.source;
createPage({
path: slug,
component: postTemplate,
context: {
slug,
prev,
next,
source
}
});
});
// and pages.
const pages = items.filter(item => item.node.fields.source === "pages");
pages.forEach(({ node }) => {
const slug = node.fields.slug;
const source = node.fields.source;
createPage({
path: slug,
component: pageTemplate,
context: {
slug,
source
}
});
});
})
);
});
};
exports.onCreateWebpackConfig = ({ stage, actions }, options) => {
switch (stage) {
case `build-javascript`:
actions.setWebpackConfig({
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: "static",
reportFilename: "./report/treemap.html",
openAnalyzer: true,
logLevel: "error",
defaultSizes: "gzip"
})
]
});
}
};