Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Netlify cms with GatsbyJs image upload path problems #843

Closed
thomasheimstad opened this issue Nov 25, 2017 · 20 comments
Closed

Netlify cms with GatsbyJs image upload path problems #843

thomasheimstad opened this issue Nov 25, 2017 · 20 comments

Comments

@thomasheimstad
Copy link

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.

@tech4him1
Copy link
Contributor

Currently we do not support relative paths for media, although we would be glad to accept a patch if you are willing! There is more information at #325.

@tech4him1
Copy link
Contributor

tech4him1 commented Nov 25, 2017

@thomasheimstad Just wondering, did you try setting the public_folder to posts/img instead of img?

I'm not sure exactly what your site looks like when it is actually built.

@tech4him1 tech4him1 reopened this Nov 25, 2017
@thomasheimstad
Copy link
Author

@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:

@tech4him1
Copy link
Contributor

@thomasheimstad What does the directory structure look like when you build the site (I think the public folder)?

@thomasheimstad
Copy link
Author

@tech4him1 Public folder looks as such:

public {
  admin
  categories
  tags
  // all the post titles are folders in the root of the public folder, with index.html inside.
  static {
     // all images are in the root of the static site 
  }

@tech4him1
Copy link
Contributor

@thomasheimstad Try setting the public_folder: "static".

@thomasheimstad
Copy link
Author

@tech4him1 Tried before, tried again to no avail. It creates the post in the right folder with this frontmatter:

thumbnail: /static/testimage.jpg

@tech4him1
Copy link
Contributor

Are you testing it with gatsby develop? or with the built site?

@thomasheimstad
Copy link
Author

Both, and neither are working.

The error from the terminal when trying to do a gatsby build:

const postNode = this.props.data.markdownRemark;
     |                                      ^
  16 |     const post = postNode.frontmatter;
  17 |     if (!post.id) {
  18 |       post.id = slug;


  WebpackError: Cannot read property 'markdownRemark' of undefined

So whenever the frontmatter of the post = thumbnail: /static/testimage.jpg the build fails.
./img/testimage and img/testimage builds perfectly.

Uploading via Netlify CMS always returns a "/" in front of the suggested folder, and gatsby doesn't comply.

Here's the full query, if it helps:

export const pageQuery = graphql`
  query BlogPostBySlug($slug: String!) {
    markdownRemark(
      fields: { slug: { eq: $slug } }
    ) {
      html
      timeToRead
      excerpt
      frontmatter {
        title
        cover
        date
        category
        tags
        thumbnail {
          childImageSharp {
            responsiveSizes(maxWidth: 1920, quality: 50, cropFocus: CENTER, toFormat: JPG) {
              src
              srcSet
              sizes
              base64
            }
          }
        }
      }
      fields {
        slug
      }
    }
  }
`;

@tech4him1
Copy link
Contributor

It looks like you would either have to have relative path support in the CMS (#325 (comment)), or modify your build so that it doesn't try to modify the paths.

There is also a Gatsby starter template here: https://github.com/AustinGreen/gatsby-starter-netlify-cms. I don't know if you would be able to use the config from it to help you set up your site (I'm no Gatsby expert 😄).

@tech4him1
Copy link
Contributor

@erquhart Since you've been working on the media library, do you know if there is any better way to set this up?

@thomasheimstad
Copy link
Author

@tech4him1 Thanks so far, Caleb! I tried copying the starter, but again to no avail. Let's await erquhart's response, we might get lucky!

@erquhart
Copy link
Contributor

erquhart commented Nov 27, 2017

When your frontmatter has thumbnail: /static/testimage.jpg, Gatsby errors aside, is the path accurate? What happens if you navigate to yoursite.com/static/testimage.png in your browser?

@thomasheimstad
Copy link
Author

It doesn't even build when the query returns nothing for the

frontmatter {
  thumbnail {
    childImageSharp {
      responsiveSizes(quality: 50, cropFocus: CENTER, toFormat: JPG) {
        src

If I manually change to img/testimg.jpg, and check Google Developer, it shows the full static path when I import images with import Testimage from "../posts/img/testimg.jpg", similar to this: background-image: url("http://localhost:8000/static/testimg.7b158d53.jpg"

When I import images using the GraphQL-query, it shows only a relative path:background-image: url("/static/testimg.7b158d53.jpg"

So the frontmatter path must, apparently, be relative to the position of the markdown-file, and the image must reference the original image path?

http://localhost:8000/static/testimg.jpg doesn't exist. However, http://localhost:8000/static/testimg.7b158d53.jpg does.

Thumbnail at /static/testimg.jpg fails the build, both gatsby develop and gatsby build with TypeError: Cannot read property 'childImageSharp' of null

@erquhart
Copy link
Contributor

erquhart commented Nov 28, 2017

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!

@erquhart
Copy link
Contributor

erquhart commented Nov 29, 2017

Update: I submitted a PR to get the gatsby starter on point for media library usage (and it was merged), so you can reference that as a pattern.

Going to close this, but join us on Gitter if you need any more help getting off the ground!

@thomasheimstad
Copy link
Author

@erquhart Thanks a lot for your help! Personally I have no problems doing this manually (uploading, then adding the image manually as a string), but it's still pretty bad UI-design. Is there any way of changing the frontmatter field programatically, for instance with gatsby-transformer-remark? Two ideas, either checking if the field starts with "/" and then changing to "./", or to programatically create a new hidden frontmatterfield which copies the returned string of the image widget, and then prepends the necessary ".". It still feels hacky, though, and I'm starting to think there must be a way to access the way netlify-cms handles the image paths (such as not prepending the "/").

@erquhart
Copy link
Contributor

erquhart commented Jan 1, 2018

@thomasheimstad folks are working toward a proper solution to the Gatsby/Netlify CMS image issue in #325, have a look there.

@stephaniedavidson
Copy link

having the same issue in 2020

@erezrokah
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants