【问题标题】:Gatsby images from markdown posts not displaying from graphql query来自 markdown 帖子的 Gatsby 图像未从 graphql 查询中显示
【发布时间】:2021-05-04 22:01:27
【问题描述】:

我使用 Markdown 与 Gatsby 和 Tailwind 建立了一个博客文章。使用 graphql 查询数据时,我无法显示任何图像。我的图像存储在src/ 目录中的images/ 文件夹中。我的帖子位于同一目录中的 pages/ 文件夹中。在某一时刻,该站点显示了所有图像,包括 Markdown 中的图像,但在部署到 Netlify 时无法正常工作。我已经部署了该站点,但现在我的图像都没有显示,我已经尽一切努力让它们恢复原状。我也尝试过使用 gatsby-image(固定和流体),但仍然没有。

这是我第一个使用 gatsby、markdown 和 graphql 的项目。目前,使用 devtools (../images/example.jpg) 检查时,已部署的站点 nikkipeel.netlify.app 在博客页面上显示了正确的帖子路径,但实际上仍然没有图像显示。 ????‍♀️

Github 仓库:gatsby-blog

项目结构:

|-- /public
|-- /src
    |-- /components
    |-- /pages
       |-- /post-one
          |--index.md
       |-- /post-two
          |--index.md
       |-- /post-three
          |--index.md
    |-- /templates
       |-- blog-post.js
    |-- /images

|-- /static
|-- gatsby-config.js
|-- gatsby-node.js
|-- gatsby-ssr.js
|-- gatsby-browser.js

一篇博文的主要内容 (index.md) -

---
path: "/create-a-blog-with-react-and-sanity"
date: "2021-01-10"
title: "Create a blog with React and Sanity"
description: "Create a technical blog built with React, TailwindCSS, and Sanity then deploy it using Github and Netlify"
category: "React"
author: "Nikki Peel"
authorImage:  ../images/selfie.png
image: ../images/sanity-blog-collage.jpg
---

带有 Graphql 查询的 Blog.js 用于显示所有帖子:

import React from "react"
import { graphql } from 'gatsby'
import Layout from "../components/layout"
import Link from 'gatsby-link';
import SEO from "../components/seo"

const BlogPage = ({ data }) => (
  <Layout>
    <SEO title="Blog" />
    <main className="bg-brown text-white h-auto p-12">
            <section className="container mx-auto">
                <h1 className="text-4xl mono pl-4">Latest Blog Posts</h1>
                <h2 className="text-lg mb-12 pl-4">Welcome to my page of blog posts</h2>


                <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 justify-center mx-auto md:gap-8 mb-24"> 
                {data.allMarkdownRemark.edges.map(post => (
                   <article>
                   <Link to={post.node.frontmatter.path}>
    
                   <div className="block lg:h-64 relative leading-snug" key={ post.node.id }>
                   <img src={post.node.frontmatter.image} alt="" className="lg:block w-full items-center lg:h-full lg:object-cover lg:object-top relative lg:absolute"/> 
                       <span className="block relative lg:h-full lg:flex lg:items-end ">
                           <h3 className="lg:bg-gray-800 lg:bg-opacity-75 text-white text-xl font-semibold lg:px-3 lg:py-4 rounded text-left">{post.node.frontmatter.title}</h3>
                       </span>
                      <div className="mt-4 mb-8"> 
                           <p className="text-base mb-4">{post.node.frontmatter.description}</p>
                           <span id={post.node.frontmatter.category} className="text-black font-semibold text-sm py-2 px-4 mr-2 rounded">{post.node.frontmatter.category}</span>
                           <small className="text-base ml-2">&#128197; {post.node.frontmatter.date}</small>
                       </div> 
                   </div>
                   </Link>
               </article>
     ))}

               
                </div>
            </section>
        </main>
  </Layout>
)

export const pageQuery = graphql`
    query BlogIndexQuery {
            allMarkdownRemark  (sort: { fields: [frontmatter___date], order: DESC }){
                edges {
                    node {
                        id
                    frontmatter {
                        path
                        title
                        description
                        date
                        category
                        image
                    }
                }
            }
        }
    }
`;

export default BlogPage; 

对于单个帖子 - blog-post.js:

import React from 'react';
import { graphql } from 'gatsby'
import Link from 'gatsby-link';
import Layout from '../components/layout';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faChevronLeft } from '@fortawesome/free-solid-svg-icons';

export default function Template({ data }) {
    const post = data.markdownRemark

    return (
        <Layout>
              <main className="container bg-brown min-h-screen p-4 md:p-12">
            <Link to="/blog" exact className="text-white text-base items-center"><FontAwesomeIcon icon={faChevronLeft} className="mr-4"></FontAwesomeIcon> Back to Blog</Link>
            <article className="container text-white mx-auto rounded-lg mt-4">
                <header className="relative">
                    <div className="absolute h-full w-full flex items-center justify-center p-8">
                        <div className="bg-white text-brown bg-opacity-75 rounded p-4 md:p-12">
                            <h1 className="mono text-3xl mb-4">
                                {post.frontmatter.title}
                            </h1>
                            <div className="flex justify-center text-brown">
                                <img src={post.frontmatter.authorImage} alt="" className="w-10 h-10 rounded-full"/>
                                <p className="mono flex items-center pl-4 text-xl">{post.frontmatter.author}</p>
                            </div>
                            <p className="text-base font-semibold mt-4 text-center">Published on <strong>{post.frontmatter.date}</strong></p>
                        </div>
                    </div>
                    <img src={post.frontmatter.image} alt={post.frontmatter.title} className="w-full object-cover object-left-top rounded-t" style={{ height: "400px", width: "100%"}}/>
                </header>
                <div className="break-words px-4 lg:px-16 py-12 lg:py-20 prose lg:prose-xl max-w-screen leading-normal">
                    <div dangerouslySetInnerHTML={{ __html: post.html }} />
                </div>
            </article>
        </main>
        </Layout>
    )
}

export const postQuery = graphql`
    query BlogPostByPath($path: String!) {
        markdownRemark(frontmatter: { path: { eq: $path } }){
            html
            frontmatter {
                path
                title
                date
                author
                authorImage 
                image
            }
        }
    }
`

使用 graphiql 游乐场时,会为 blog.js 检索正确的图像路径,但不会为 blog-post.js(个人帖子)检索:

blog.js 查询:

{
  "data": {
    "allMarkdownRemark": {
      "edges": [
        {
          "node": {
            "frontmatter": {
              "path": "/customizing-the-scrollbar-with-css",
              "title": "Customizing the Scrollbar with CSS",
              "description": "Learn how to apply custom styling to the scrollbar on your project with pure CSS",
              "date": "2021-01-28",
              "category": "CSS",
              "image": "../images/scrollbar.png"
            }
          }
        },

blog-post.js 查询:

{
  "errors": [
    {
      "message": "Variable \"$path\" of required type \"String!\" was not provided.",
      "locations": [
        {
          "line": 1,
          "column": 24
        }
      ],
      "stack": [
        "GraphQLError: Variable \"$path\" of required type \"String!\" was not provided.",
        "    at _loop (C:\\Users\\npeel\\Microsoft VS Code\\gatsby-blog-main\\gatsby-blog-main\\node_modules\\graphql\\execution\\values.js:92:17)",
        "    at coerceVariableValues (C:\\Users\\npeel\\Microsoft VS Code\\gatsby-blog-main\\gatsby-blog-main\\node_modules\\graphql\\execution\\values.js:119:16)",
        "    at getVariableValues (C:\\Users\\npeel\\Microsoft VS Code\\gatsby-blog-main\\gatsby-blog-main\\node_modules\\graphql\\execution\\values.js:48:19)",
        "    at buildExecutionContext (C:\\Users\\npeel\\Microsoft VS Code\\gatsby-blog-main\\gatsby-blog-main\\node_modules\\graphql\\execution\\execute.js:184:61)",
        "    at executeImpl (C:\\Users\\npeel\\Microsoft VS Code\\gatsby-blog-main\\gatsby-blog-main\\node_modules\\graphql\\execution\\execute.js:89:20)",
        "    at execute (C:\\Users\\npeel\\Microsoft VS Code\\gatsby-blog-main\\gatsby-blog-main\\node_modules\\graphql\\execution\\execute.js:64:35)",
        "    at C:\\Users\\npeel\\Microsoft VS Code\\gatsby-blog-main\\gatsby-blog-main\\node_modules\\express-graphql\\index.js:152:16",
        "    at runMicrotasks (<anonymous>)",
        "    at processTicksAndRejections (internal/process/task_queues.js:93:5)"
      ]
    }
  ],
  "extensions": {}
}

gatsby-node.js -

在此处将“image”和“authorImage”添加到 frontmatter 时收到错误消息

const path = require('path');

exports.createPages = ({actions, graphql}) => {
    const { createPage } = actions

    const postTemplate = path.resolve('src/templates/blog-post.js');

    return graphql(`
        {
            allMarkdownRemark{
                edges {
                    node {
                        html
                        id
                    frontmatter {
                        path
                        title
                        date
                        author
                        category
                        description
                    }
                    }
                }
            }
        }
    `).then(res => {
        if(res.errors) {
            return Promise.reject(res.errors)
        }

        res.data.allMarkdownRemark.edges.forEach(({node}) => {
            createPage({
                path: node.frontmatter.path,
                component: postTemplate
            })
        })
    })
}


// for RSS feed:
const { createFilePath } = require(`gatsby-source-filesystem`)
exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
}

gatsby-config.js -

module.exports = {
  siteMetadata: {
    title: `Nikki Peel - Blog`,
    description: `Technical blog created with Gatsby and Markdown`,
    author: `Nikki Peel`,
    siteUrl: `https://nikkipeel.netlify.app`,
  },
  plugins: [
    `gatsby-transformer-remark`,
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    `gatsby-plugin-react-helmet`,
    `gatsby-plugin-catch-links`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `pages`,
        path: `${__dirname}/src/pages`,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    },

    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `gatsby-starter-default`,
        short_name: `starter`,
        start_url: `/`,
        background_color: `#663399`,
        theme_color: `#663399`,
        display: `minimal-ui`,
        icon: `src/images/blog-logo.png`, // This path is relative to the root of the site.
      },
    },
    `gatsby-plugin-feed`,
    `gatsby-plugin-postcss`,
    `gatsby-plugin-fontawesome-css`,
    // this (optional) plugin enables Progressive Web App + Offline functionality
    // To learn more, visit: https://gatsby.dev/offline
    // `gatsby-plugin-offline`,
  ],
}

【问题讨论】:

    标签: image graphql markdown gatsby gatsby-plugin


    【解决方案1】:

    正如您在documentation 中看到的那样,在处理降价加图像时,路径应该相对于降价文件本身,所以:

    ---
    path: "/create-a-blog-with-react-and-sanity"
    date: "2021-01-10"
    title: "Create a blog with React and Sanity"
    description: "Create a technical blog built with React, TailwindCSS, and Sanity then deploy it using Github and Netlify"
    category: "React"
    author: "Nikki Peel"
    authorImage: /gatsby-blog/images/selfie.png
    image: /gatsby-blog/images/sanity-blog-collage.jpg
    ---
    

    发帖人:https://github.com/nikkipeel/gatsby-blog/blob/main/src/pages/post-one/index.md

    应该变成:

    ---
    path: "/create-a-blog-with-react-and-sanity"
    date: "2021-01-10"
    title: "Create a blog with React and Sanity"
    description: "Create a technical blog built with React, TailwindCSS, and Sanity then deploy it using Github and Netlify"
    category: "React"
    author: "Nikki Peel"
    authorImage: ../../images/selfie.png
    image: ../../sanity-blog-collage.jpg
    ---
    

    注意两个图像的相关性 (../../images/selfie.jpg)。这将允许 Gatsby 创建一个有效的 GraphQL 节点,并将在 GraphQL 游乐场 (localhost:8000/___graphql) 中显示 childImageSharp 节点。

    字段“图像”不能有选择,因为类型“字符串”没有 子字段。这可能会发生,例如不小心将 { } 添加到 字段“图像”。如果您不希望“图像”是“字符串”类型 确保您的输入源和/或插件正确。

    不像看起来那样,这是一个很好的错误,因为它指出 Gatsby 正在尝试从您的降价文件创建节点(即:您的路径现在已被很好地引用)并且您将能够使用 gatsby-image。根据docs,我意识到您缺少一些插件。

    添加gatsby-transformer-remarkgatsby-remark-images 插件。

    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          {
            resolve: `gatsby-remark-images`,
            options: {
              maxWidth: 800,
            },
          },
        ],
      },
    },
    

    我不会将降价文件放在 Gatsby 的 /pages 文件夹中以避免潜在问题。 Gatsby 是基于文件夹结构的路由,或者换句话说,Gatsby 推断/pages 文件夹的内部结构来创建路由和路径,因此最好避免混淆。

    如果您相应地设置gatsby-source-filesystem,您的页面可以存储在任何文件夹中。这将允许 Gatsby 从这些降价文件创建 GraphQL 节点。

    【讨论】:

    • 谢谢,不幸的是更改文件路径并没有改变结果。正在加载所有其他降价内容,以及前端内容(描述、标题、类别、日期)。我遇到的唯一问题是图像显示。更改为相对路径后我还应该做些什么吗?也许我需要导入 gatsby-image 并在查询中包含 childImageSharp?
    • 您可以尝试将转换器插件(和备注)移到插件列表的顶部吗?
    • 我将这些插件移到了配置文件的顶部并更新了 github repo。部署到 Netlify 后,我的所有图像仍然收到 404 错误。对于博客页面 (blog.js),错误是:“加载资源失败:服务器响应状态为 404 ()”,无论 Markdown 文件中指定的文件路径如何。对于个别帖子,我仍然收到 404 错误,但它似乎来自“GET”请求。我尝试在图像查询中使用 childImageSharp,但随后收到错误消息,指出“图像”不能包含子字段。
    • 我认为您缺少两个插件:gatsby-transformer-remarkgatsby-remark-images。我已经用新的试验更新了这个问题(希望是最后一个)
    • 我看到图片了!我添加了插件“gatsby-remark-images”并将“gatsby-image”导入到 blog.js 和 blog-post.js。接下来,我更改了查询以包含 childImageSharp 以及“固定”和流体“属性。图像现在显示,现在只需根据我的喜好调整样式即可。解决方案是:1)确保我安装了所有必要的插件 2)将 markdown 文件中的文件路径更正为相对的,3)使用 'gatsby-image' 进行适当的查询。现在我只需要调整样式、重建和重新部署。非常感谢您的帮助!
    【解决方案2】:

    我能够通过在 markdown 文件中引用外部源来加载图像,但仍然无法通过文件路径访问它们 ?‍♀️ 我仍在研究和解决这个问题

    ---
    path: "/post-three"
    date: "2020-11-23"
    title: "My Third Gatsby Post"
    description: "This is my third markdown post with gatsby"
    category: "Tailwind"
    author: "Nikki Peel"
    authorImage: https://i.imgur.com/qyIekvV.png
    image: https://i.imgur.com/lKnOCsT.jpg
    ---
    

    【讨论】:

    • 是的,这是另一种方法。但是,我认为这个想法是使用gatsby-image
    猜你喜欢
    • 2020-06-18
    • 2020-10-22
    • 2017-04-29
    • 2018-06-16
    • 1970-01-01
    • 2019-10-26
    • 2021-05-29
    • 2021-01-15
    • 1970-01-01
    相关资源
    最近更新 更多