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.
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 https://github.com/netlify/netlify-cms/issues/325.
@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 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:
@thomasheimstad What does the directory structure look like when you build the site (I think the public folder)?
@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
}
@thomasheimstad Try setting the public_folder: "static".
@tech4him1 Tried before, tried again to no avail. It creates the post in the right folder with this frontmatter:
thumbnail: /static/testimage.jpg
Are you testing it with gatsby develop? or with the built site?
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.jpgthe build fails.
./img/testimageandimg/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
}
}
}
`;
It looks like you would either have to have relative path support in the CMS (https://github.com/netlify/netlify-cms/issues/325#issuecomment-290162337), 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 馃槃).
@erquhart Since you've been working on the media library, do you know if there is any better way to set this up?
@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!
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?
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
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.
src/pages/admin.jsx to static/admin/index.html.static/config.yml to static/admin/config.yml.At this point your static/admin folder should look something like this.
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:
Update your config:
media_folder: src/img
# public folder is omitted because it won't matter
- {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!
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!
@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 "/").
@thomasheimstad folks are working toward a proper solution to the Gatsby/Netlify CMS image issue in #325, have a look there.
having the same issue in 2020
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
Most helpful comment
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.
src/pages/admin.jsxtostatic/admin/index.html.static/config.ymltostatic/admin/config.yml.At this point your
static/adminfolder should look something like this.Next, treat image fields as simple strings, since they won't be converted to Sharp nodes by Gatsby any longer - so your
thumbnailfield, for example, should not include any selections, just the field name:If you really want the image processing, here's a third way that should work:
Update your config:
- {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!