Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
997 views
in Technique[技术] by (71.8m points)

graphql - Gatsby Contentful embedded image

As I see there is no json option anymore when querying the contentfulBlogPost only raw. I was able to make some changes to get everything from the body, except the image from that post.

If I made a test in GraphQL Playground I can get the image id and url but that's it.

query {
  allContentfulAsset {
    edges {
      node {
        id
        file {
          url
        }
      }
    }
  }
}

I tried to find an example how to get embedded images but no luck....

import React from 'react'
import { graphql } from 'gatsby'
import { documentToReactComponents } from '@contentful/rich-text-react-renderer'

import Layout from '../components/layout'


export const query = graphql`
  query($slug: String!) {
    contentfulBlogPost(slug: {eq: $slug}) {
      title
      publishedDate(formatString: "MMMM Do, YYYY")
      body {
        raw 
      }
    }
    allContentfulAsset {
      edges {
        node {
          id
          file {
            url
          }
        }
      }
    }
  }
`

const Blog = (props) => {
  const options = {
    renderNode: {
      "embedded-asset-block": (node) => {
        const alt = node.data.title
        const url = node.file.url
        return <img alt={alt} src={url}/>
      }
    }
  }
  return (
        <Layout>
          <h1>{props.data.contentfulBlogPost.title}</h1>
          <p>{props.data.contentfulBlogPost.publishedDate}</p>
          {documentToReactComponents(JSON.parse(props.data.contentfulBlogPost.body.raw, options))}
        </Layout>
    )
}

export default Blog

Plugins:

...
 'gatsby-plugin-sharp',
    {
      resolve:   'gatsby-transformer-remark',
      options: {
        plugins: [
          'gatsby-remark-relative-images',
          {
            resolve: 'gatsby-remark-images-contentful',
            options: {
              maxWidth: 750,
              linkImagesToOriginal: false
            }
          }
        ]
      }

    }
  ],
}
question from:https://stackoverflow.com/questions/65829246/gatsby-contentful-embedded-image

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Use something like:

import { BLOCKS, MARKS } from "@contentful/rich-text-types"
import { renderRichText } from "gatsby-source-contentful/rich-text"
?
const Bold = ({ children }) => <span className="bold">{children}</span>
const Text = ({ children }) => <p className="align-center">{children}</p>
?
const options = {
  renderMark: {
    [MARKS.BOLD]: text => <Bold>{text}</Bold>,
  },
  renderNode: {
    [BLOCKS.PARAGRAPH]: (node, children) => <Text>{children}</Text>,
    [BLOCKS.EMBEDDED_ASSET]: node => {
      return (
        <>
          <h2>Embedded Asset</h2>
          <pre>
            <code>{JSON.stringify(node, null, 2)}</code>
          </pre>
        </>
      )
    },
  },
}
?
renderRichText(node.bodyRichText, options)

Source: https://www.contentful.com/developers/docs/tutorials/general/rich-text-and-gatsby/

The return statement in BLOCKS.EMBEDDED_ASSET entry will contain your data, adapt to your needs. If you go inside the dependency, you'll see all the exposed methods, so you will have also a BLOCKS.EMBEDDED_ENTRY entry for your embedded entries. Apply it like:

[BLOCKS.EMBEDDED_ENTRY]: node => {
  // your logic to manipulate the entry here
  return (
    <>
      <div>whatever</div>
    </>
  )
},

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...