decap-cms: Netlify cms with GatsbyJs image upload path problems

Hi!

Kudos on this excellent project, I’m having so much fun trying this out! However I’m experiencing some slight difficulty getting the upload image function working, and it seems to be related to the image path of the config.yml settings.

If I manually upload images to the src/posts/img folder, and name the image manually in the frontmatter as such:

thumbnail: "./img/testimage.jpg"

it works! Notice the ./img, I’m finding the images in the folder “img” which is in the same folder as my markdown files.

When I upload an image from the Netlify CMS admin UI, it receives the following path:

thumbnail: "/img/testimage.jpg"

Notice the relative "/img path. My GraphQL query fails miserably when trying to find this image:

TypeError: Cannot read property 'childImageSharp' of null

I’ve exhausted testing different paths and solutions in config.yml, and I can’t seem to override the behaviour of public_folder, adding a “/” before the path name. If I do:

public_folder: "./img"

it just adds “/./img”, and the query continues to fail.

Here are the rest of my settings, and my GraphQL query: config settings:

media_folder: "src/posts/img"
public_folder: "img"
    collections:
      - name: "post"
        label: "Post"
        folder: "src/posts"
        create: true
        slug: "{{slug}}"
        fields:
          - {label: "Image", name: "thumbnail", widget: "image"}

gatsby-config:

    {
      resolve: `gatsby-source-filesystem`,
      options: {
        path: `${__dirname}/src/posts/img`,
        name: 'images'
      }
    },
    {
      resolve: "gatsby-transformer-remark",
      options: {
        plugins: [
          {
            resolve: "gatsby-remark-images",
            options: {
              maxWidth: 690,
              linkImagesToOriginal: false
           }
         }
       }
     }

file structure:


Root:
  gatsby-config.js
  gatsby-node.js
  package.json
  data {
    siteconfig.js
  }
  static {
    config.yml // FOR CMS
  }
  src {
     html.jsx
     components {}
   css {}
   layouts {}
   pages {}
   templates {}
   posts {
     img {
        // Image folder for all post uploads via CMS
     }
     testpost1.md
     testpost2.md
  }
}

GraphQL-query:

export const pageQuery = graphql`
  query IndexQuery {
    allMarkdownRemark(
      limit: 6
      sort: { fields: [frontmatter___date], order: ASC }
      filter: { frontmatter: { category: { eq: "upcoming"} } }
    ) {
      edges {
        node {
          fields {
            slug
          }
          excerpt(pruneLength: 75)
          timeToRead
          frontmatter {
            title
            description
            tags
            startTime
            cover
            date
            category
            location
            thumbnail {
              childImageSharp {
                responsiveSizes(quality: 50, cropFocus: CENTER, toFormat: JPG) {
                  src
                  srcSet
                  sizes
                  base64
                }
              }
            }
          }
        }
      }
    }
  }
`;

Truly hope some of you may spot my rookie-mistake! Thanks in advance.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 9
  • Comments: 20 (12 by maintainers)

Most upvoted comments

Alright, so good news: I figured it out; bad news: you can’t use Gatsby plugins on static resources.

First, the CMS needs to exist entirely in the static folder. See the Gatsby starter and cms docs for reference.

  1. Migrate the CMS from src/pages/admin.jsx to static/admin/index.html.
  2. Move the config from static/config.yml to static/admin/config.yml.

At this point your static/admin folder should look something like this.

  1. Update your config:
media_folder: static/img
public_folder: img

Next, treat image fields as simple strings, since they won’t be converted to Sharp nodes by Gatsby any longer - so your thumbnail field, for example, should not include any selections, just the field name:

query BlogPostBySlug($slug: String!) {
  markdownRemark(
    fields: { slug: { eq: $slug } }
  ) {
    html
    timeToRead
    excerpt
    frontmatter {
      title
      date
      category
      concertDate
      location
      startTime
      tags
      thumbnail
    }
    fields {
      slug
    }
  }
}

If you really want the image processing, here’s a third way that should work:

  1. Still do steps 1 and 2 from above.
  2. Update your config:
media_folder: src/img
# public folder is omitted because it won't matter
  1. Update image fields in your config to use the string widget, which is the default widget:
      - {label: "Image", name: "thumbnail"}

Now you can upload images to the media library, but you’ll enter the text path to use an image, rather than inserting the image from the library. You could probably also use a custom preview to show the final Gatsby image in the preview pane, not certain what hooks Gatsby provides for that.

Hope this helps!

Hi @stephaniedavidson, the CMS no longer prefixes a / to public_path and the recommended way with Gatsby is to use relative media folders: https://www.netlifycms.org/docs/beta-features/#folder-collections-media-and-public-folder

I would suggest opening a new issue based on the issue template and describe a reproduction scenario

@tech4him1 Hi, thanks for answering.

Yes, I did try to set it to “posts/img”. Also to “./img” and “/img” but it keeps failing.

I don’t really need a relative folder, I just need to be able to set the same folder for image uploads as my image folder. With the following folder structure, how do I config my config.yml for the Netlify cms:

 src {
   posts {
     testpost1.md
     testpost2.md
     img {
        // Image folder for all post uploads via CMS, and all the other images of the site.
     }
  }

If it helps, you may find the github repo here: