decaporg / decap-cms

A Git-based CMS for Static Site Generators
https://decapcms.org
MIT License
17.93k stars 3.04k forks source link

Error: The result of this StaticQuery could not be fetched.This is likely a bug in Gatsby and i... #4004

Closed alessioprestileo closed 4 years ago

alessioprestileo commented 4 years ago

Describe the bug Result of StaticQuery could not be fetched. This happens only in the CMS (as shown in the picture) when trying to preview the index page, but not when rendering the same page in the website. The static query causing the error is:

const useSiteMetadata = () => {
  const data: SiteMetadataQuery = useStaticQuery(
    graphql`
      query SiteMetadata {
        site {
          siteMetadata {
            title
            description
          }
        }
      }
    `,
  )
  const { site } = data

  return site?.siteMetadata
}

To Reproduce You can clone this repo: https://github.com/alessioprestileo/netlify-cms-issue.git

Expected behavior The static query should work and return the same data as when rendering the index page in the website

Screenshots image

Applicable Versions:

CMS configuration

publish_mode: simple
slug:
  encoding: unicode
  clean_accents: false
  sanitize_replacement: "-"
backend:
  name: git-gateway
  branch: master
  commit_messages:
    create: Create {{collection}} “{{slug}}”
    update: Update {{collection}} “{{slug}}”
    delete: Delete {{collection}} “{{slug}}”
    uploadMedia: "[skip ci] Upload “{{path}}”"
    deleteMedia: "[skip ci] Delete “{{path}}”"
media_folder: static/img
public_folder: /img
collections:
  - name: pages
    label: Pages
    files:
      - file: src/pages/index.md
        label: Landing Page
        name: index
        fields:
          - label: Template Key
            name: templateKey
            widget: hidden
            default: index-page
          - label: Welcome Section
            name: welcomeSection
            widget: object
            fields:
              - label: Message
                name: message
                widget: markdown
              - label: Video URL
                name: videoUrl
                widget: string
              - label: Blurbs
                name: blurbs
                widget: list
                fields:
                  - label: Image
                    name: image
                    widget: image
                  - label: Text
                    name: text
                    widget: text
          - label: Customer stories
            name: customerStories
            widget: object
            fields:
              - label: Title
                name: title
                widget: string
              - label: Feedbacks
                name: feedbacks
                widget: list
                fields:
                  - label: Author
                    name: author
                    widget: string
                  - label: Content
                    name: content
                    widget: text
              - label: Key Numbers
                name: keyNumbers
                widget: list
                fields:
                  - label: Number
                    name: number
                    widget: number
                  - label: Description
                    name: description
                    widget: string
          - label: Call To Action
            name: callToAction
            widget: object
            fields:
              - label: Header
                name: header
                widget: string
              - label: Content
                name: content
                widget: text
              - label: Image
                name: image
                widget: image
              - label: Social Media
                name: soMeList
                widget: select
                multiple: true
                options:
                  - Facebook
                  - Twitter
                  - Instagram
    publish: true
    sortableFields:
      - commit_date
      - commit_author
    view_filters: []

Additional context

erezrokah commented 4 years ago

Thanks @alessioprestileo for reporting. See more info here https://community.netlify.com/t/gatsby-and-netlify-cms-preview-error-with-rendering-staticquery/5215/2?u=erez

TLDR: You can't use static query in Netlify CMS previews as the CMS runs in browser context while static query runs during build time. The solution is to make sure the relevant shared components have their data injected as props.

Closing, as we can continue the discussion in the community thread.

AbdallahAbis commented 3 years ago

@erezrokah

The solution is to make sure the relevant shared components have their data injected as props.

Could you please explain this in other words? how can I pass data that I get from a staticQuery to a widget component as a prop?

erezrokah commented 3 years ago

Could you please explain this in other words? how can I pass data that I get from a staticQuery to a widget component as a prop?

Hi @AbdallahAbis, you can't pass data from a staticQuery to a widget component. staticQuery is evaluated during build time whereas widget components run in the browser. You should use a page query instead.

AbdallahAbis commented 3 years ago

@erezrokah cool, but still, how do I pass it the data returned from a query in general?

erezrokah commented 3 years ago

You pass it as React props, see https://github.com/netlify-templates/gatsby-starter-netlify-cms/blob/e8874f871b8b18f50f572d6250d06b512c20726d/src/templates/blog-post.js#L58

AbdallahAbis commented 3 years ago

@erezrokah But this is a template page, not a Netlify custom widget

erezrokah commented 3 years ago

Correct @AbdallahAbis, I think I missed you point. You can see here what is passed by the CMS to custom widgets. The value passed to the widget is parsed from the markdown file and is unrelated to any query done by Gatsby.

Can you clarify your use case? What are you using a custom widget for?

AbdallahAbis commented 3 years ago

@erezrokah I have a list of posts on my blog, each post has an author. I have a collection where you can add new authors or view an existing one. when viewing an existing author I have the custom widget listing all the articles a specific author posted.

So I'm using StaticQuery to get all the markdown posts on my blog from that specific author and map through them and display them.

erezrokah commented 3 years ago

Have you considered using the relation widget? Each author can have a list of relation widgets, each one referencing a post.

If that doesn't work, you can maybe mimic the way the relation widget uses the query API: https://github.com/netlify/netlify-cms/blob/65343c1238af85e9151abb6bbba3770a08091176/packages/netlify-cms-widget-relation/src/RelationControl.js#L140

AbdallahAbis commented 3 years ago

@erezrokah Mimicking the Relation widget did the trick!

For anyone facing the issue, I think using the query property method on widget component will help. https://github.com/netlify/netlify-cms/blob/65343c1238af85e9151abb6bbba3770a08091176/packages/netlify-cms-widget-relation/src/RelationControl.js#L140

import { groupBy } from 'lodash'
//...
async componentDidMount () {
    const { payload } =
      await this.props.query(
        this.props.forID,
        'articles', // Name of the collection you want to query
        ['author'], // The field/fields you want to query for on that collection.
        '',
        this.props.field.get('file')
      )
    const hits = payload.response.hits || []

    const articleGroupByAuthor = groupBy(hits, hit => {
      return hit.data.author
    })
    this.setState({
      campaignArticles: articleGroupByAuthor
    })
 }