I have been building out a site with gatsby, netlify-cms and would really love to be able to leverage gatsby-image. It seems that since the image URLs need to be known when writing the query and the nature of my CMS data is that its dynamic at compile, I won't be able to set this up. I was wondering if there is any way to query for the childImageSharp resoutions shown in the gatsby-image example in a page level query referencing a fields URL value and then getting the image resolutions from that.
As a followup, is there any way to manually say what I would like my resolutions will be and just pass those to the Img component?
Sorry about this, ended up finding what I was looking for in a past issue.
@peterlazzarino were you able to implement this?
@SaintEmbers I wasn't. I am reopening because there doesn't seem to be a consensus way to access netlify uploaded images using gatsby graphQL queries. I'm not sure if this should be opened on the netlify CMS repo or not. I did a lot of running around today trying out examples that didn't work out.
@peterlazzarino are you able to add links to the past issues that talk about handling this?
@m-allanson sure, here's what I could find on the issue.
https://github.com/netlify/netlify-cms/issues/843
https://github.com/gatsbyjs/gatsby/issues/4753
https://github.com/netlify/netlify-cms/issues/325
https://github.com/AustinGreen/gatsby-starter-netlify-cms/issues/7
https://github.com/netlify/netlify-cms/issues/325#issuecomment-354514547
@peterlazzarino This has worked for me for the last couple of builds https://github.com/danielmahon/gatsby-remark-relative-images
You need to make sure you read the whole readme very carefully because every placement is important.
@hennessyevan I am not trying to use images uploaded in markdown, sorry I should have clarified. I am trying to use images I have uploaded using the image widget in the netlify CMS which are uploaded to the media folder of the project.
@peterlazzarino this should still work for that AFAIK, you just need to source that folder and pass the name to relative-images. The relative-images plugin just fixes some incongruences with gatsby-image and netlifyCMS after that you should be able to run gatsby-image graphql fragments on any image in your media-folder.
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/static/mediafolder/`, //path to your media-folder
name: "media"
}
},
{
resolve: "gatsby-transformer-remark",
options: {
plugins: [
{
resolve: `gatsby-remark-relative-images`,
options: {
name: "media" // Must match the source name ^
}
},
{
resolve: `gatsby-remark-images`,
options: { }
}
]
}
}
After setting this up you can run a query on allImageSharp
filtering for some parameter
query getResolutionsByID {
allImageSharp(filter: {id: {eq: "imageID"}}) {
edges {
node {
id
resolutions {
base64
srcSet
}
}
}
}
}
I may be wrong about this but @danielmahon would be able to let you know if this is indeed in the scope of this plugin. Β―_(γ)_/Β―
@hennessyevan based on that approach and what I'm trying to accomplish I don't think it's doable with that solution.
I have a page with frontmatter like {
logo
etc...
}
where logo could be any file. I can't hardcode that since the imageID depends on the upload and from what I understand my image component can't receive the image id as a prop to pass to the query.
What I would like to and what I saw as an example in other issues would be a graphQL Query that includes this
logo {
childImageSharp {
responsiveSizes(quality: 50, cropFocus: CENTER, toFormat: JPG) {
src
srcSet
sizes
base64
}
}
}
With the example you sent over I get the error. Field "logo" must not have a selection since type "String" has no subfields. This what I've been wrestling with the last few days after trying to configure this correctly.
Logo would be added from the netlifyCMS image-widget right? So it would be pointing to some image file, (although not in the absolute
format remark-images wants). This still seems like the right use-case.
If graphql is giving you that message that could mean that we'll need to make sure everything is configured right.
Can you send your gatsby-config.js and gatsby-node.js?
Sure! Here are my -config and -node files and a screenshot of my directory structure. Really appreciate the help.
gatsby-config.js
module.exports = {
siteMetadata: {
title: "Student Mentorship & College Admissions Consulting | CollegeVine",
description: "CollegeVine is a mentorship, test prep, and admissions advisory firm comprised of consultants from top US universities powered by data-driven technology."
},
plugins: [
"gatsby-plugin-react-helmet",
"gatsby-plugin-sass",
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/src/pages`,
name: "pages"
}
},
{
resolve: "gatsby-plugin-google-fonts",
options: {
fonts: [
"montserrat:400,700",
"open sans:400,600,700" // you can also specify font weights and styles
]
}
},
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/src/img`,
name: "images"
}
},
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/src/content`,
name: "layout"
}
},
"gatsby-plugin-sharp",
"gatsby-transformer-sharp",
{
resolve: "gatsby-transformer-remark",
options: {
plugins: [
{
resolve: `gatsby-remark-relative-images`,
options: {
name: "images"
}
},
{
resolve: `gatsby-remark-images`,
options: { }
}
]
}
},
{
resolve: "gatsby-plugin-netlify-cms",
options: {
modulePath: `${__dirname}/src/cms/cms.js`
}
},
"gatsby-plugin-styled-components",
"gatsby-plugin-netlify" // make sure to keep it last in the array
]
};
gatsby-node.js
const path = require("path");
const { createFilePath } = require("gatsby-source-filesystem");
exports.createPages = ({ boundActionCreators, graphql }) => {
const { createPage } = boundActionCreators;
return graphql(`
{
allMarkdownRemark(limit: 1000) {
edges {
node {
id
fields {
slug
}
frontmatter {
templateKey
path
}
}
}
}
}
`).then((result) => {
if (result.errors) {
result.errors.forEach(e => console.error( e.toString()));
return Promise.reject(result.errors);
}
const posts = result.data.allMarkdownRemark.edges;
posts.forEach(({ node }) => {
const { id } = node;
const pagePath = node.frontmatter.path || node.fields.slug;
createPage({
path: pagePath,
component: path.resolve(`src/templates/${String(node.frontmatter.templateKey)}.js`),
// additional data can be passed via context
context: {
id
}
});
});
});
};
exports.onCreateNode = ({ node, boundActionCreators, getNode }) => {
const { createNodeField } = boundActionCreators;
if (node.internal.type === "MarkdownRemark") {
const value = createFilePath({ node, getNode });
createNodeField({
name: "slug",
node,
value
});
}
};
Also if it helps I can fork my private repo strip out most of the content so it can be cloned / tested.
I've been really struggling with a solution for this same issue for a few days now, if anyone has one.
@peterlazzarino @ambethia this should work using gatsby-remark-relative-images
. Did you try setting it up for converting frontmatter? https://github.com/danielmahon/gatsby-remark-relative-images#to-convert-frontmatter-images
@danielmahon Oh great!, I ended up converting the path manually and adding it as a field in gatsby-node.js
, but I think yours might be a better option, thanks! I will try it out.
@danielmahon Unfortunately it didn't work for me. I could be wrong, but it looks like this function is only backing out once so it will only work if your markdown files are in a directory 1 step in front of the absolute path. That's just my guess though.
There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub issues, we have to clean some of the old issues as many of them have already been resolved with the latest updates.
Please make sure to update to the latest Gatsby version and check if that solves the issue. Let us know if that works for you by adding a comment π
Updating did not solve the issue for me. I am still using a hack to make this work with Netlify CMS but it works nonetheless.
I wound up writing a plugin to help with this but it might not be suitable for all use cases.
https://www.npmjs.com/package/gatsby-plugin-netlify-cms-paths
@peterlazzarino can you try plugins provided by @danielmahon or @kennedyrose?
Updating did not solve the issue for me. I am still using a hack to make this work with Netlify CMS but it works nonetheless.
What is your solution and what brakes it?
I was having a hard time setting up Netlify CMS with gatsby-remark-images
. I described the process on my blog. @pieh suggested that I could describe the solution in gatsby-plugin-netlify-cms/README.md. What do you think @erquhart?
Hi @stlk - tried your blog post but still getting "Field \"thumbnail\" must not have a selection since type \"String\" has no subfields."
Hi @jonathanphz, do you have a public repo I could check?
@stlk a PR with a quick blurb in the main cms plugin readme would be welcomed, glad you found a working solution!
@stlk, your post was very helpful but I was missing one piece: telling gatsby-source-filesystem about my NetlifyCMS image folder (as @hennessyevan mentioned at the top of this thread):
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/static/mediafolder/`, //path to your media-folder
name: "media"
}
},
@jonathanphz, could this be the reason why it's not working for you?
Took me around 2 days to finally find a solution of what was going on (and I still don't know) but I got it working in my application.
My app is a fresh install of gatsby and I'm manually adding the plugins, including NetlifyCMS. Any of the solutions will always return me this error:
{
"errors": [
{
"message": "Field \"image\" must not have a selection since type \"String\" has no subfields.",
"locations": [
{
"line": 9,
"column": 17
}
]
}
]
}
What I did was to include my media folder as recommended by @raulrpearson but with a twist: Media folder should be included before the other content.
My application is very simple, it has a content
folder with markdown that comes from Netlify. Here's my gatsby-config.js
:
module.exports = {
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/static/assets`,
name: 'assets',
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/src/content`,
name: 'content',
},
},
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
{
resolve: `gatsby-remark-relative-images`,
options: {
name: 'assets'
}
},
{
resolve: `gatsby-remark-images`,
options: {},
},
],
},
},
`gatsby-plugin-netlify-cms`,
],
}
And my gatsby-node.js
includes this per recommendation from the gatsby-remark-relative-images
package:
exports.onCreateNode = ({ node, actions, getNode }) => {
fmImagesToRelative(node)
}
This configuration above allowed me to query this:
{
allMarkdownRemark {
edges {
node {
frontmatter {
image {
childImageSharp {
fluid(maxWidth: 200) {
src
}
}
}
}
}
}
}
}
And it returns
{
"data": {
"allMarkdownRemark": {
"edges": [
{
"node": {
"frontmatter": {
"image": {
"childImageSharp": {
"fluid": {
"src": "/static/dqoq1idu4aag5k1-3d94dd633c52b449121ca8c7e1e754f2-25b9c.jpg"
}
}
},
}
}
}
]
}
}
}
Posting this so anyone can benefit from the solution since it's not intuitive nor well documented at all.
@kinduff seems like that would be a good readme PR for gatsby-remark-relative-images
Sorry I haven't been able to try out the solutions yet.
I was able to get this working following @kinduff comment. No need for gatsby-plugin-netlify-cms-paths
to make it work.
Thanks!
@peterlazzarino I submitted a PR. If the documented solution works for all, this issue should be closed now.
@kinduff I had a different solution to this in place and attempted to switch to yours without any luck. I might be doing something wrong here but here's my setup.
gatsby-config
module.exports = {
siteMetadata: {
title: "Student Mentorship & College Admissions Consulting | CollegeVine",
siteUrl: "https://www.collegevine.com",
description: "CollegeVine is a mentorship, test prep, and admissions advisory firm comprised of consultants from top US universities powered by data-driven technology."
},
plugins: [
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/static/img`,
name: "media"
}
},
"gatsby-plugin-react-helmet",
"gatsby-plugin-sass",
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/src/pages`,
name: "pages"
}
},
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/src/content`,
name: "layout"
}
},
"gatsby-plugin-styled-components",
"gatsby-transformer-sharp",
"gatsby-plugin-sharp",
{
resolve: "gatsby-transformer-remark",
options: {
plugins: [
{
resolve: "gatsby-remark-images",
options: {
maxWidth: 2000
}
},
{
resolve: `gatsby-remark-relative-images`,
options: {
name: "media"
}
},
{
resolve: "gatsby-remark-external-links",
options: {
target: "_blank",
rel: "noopener noreferrer"
}
}
]
}
},
{
resolve: "gatsby-plugin-netlify-cms",
options: {
modulePath: `${__dirname}/src/cms/cms.js`
}
},
"gatsby-plugin-netlify" // make sure to keep it last in the array
]
};
Snippet from a now failing query
<StaticQuery
query={graphql`
query LayoutQuery {
markdownRemark(fields: { slug: { eq: "/layout/" } }) {
id
frontmatter {
logo {
childImageSharp {
fixed(width: 173) {
...GatsbyImageSharpFixed
}
}
}
I get an error at the query above
GraphQL Error Field "logo" must not have a selection since type "String" has no subfields.
file: /.../layout.js
Screen shot showing my folder structure
The admittedly not pretty gatsby-node code that works when I remove the examples above
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions;
if (node.internal.type === "MarkdownRemark") {
deepMap(node.frontmatter, (value) => {
let newPath = value;
if (typeof value === "string" && path.isAbsolute(value) && value.indexOf("/img/") !== -1) {
const mdPath = node.fileAbsolutePath;
const depth = mdPath.split("src/")[1].split("/");
newPath = path.join(`${depth.map(() => "../").join("")}`, "static", value);
}
return newPath;
}, {
inPlace: true
});
}
};
@peterlazzarino you might be missing this part: https://github.com/danielmahon/gatsby-remark-relative-images#to-convert-frontmatter-images
// gatsby-node.js
const { fmImagesToRelative } = require('gatsby-remark-relative-images');
exports.onCreateNode = ({ node }) => {
fmImagesToRelative(node);
};
ah yep that was it! Thanks, closing
Hi @kinduff - is there documentation forname
in:
{
resolve: `gatsby-remark-relative-images`,
options: {
name: 'assets'
}
}
I'm trying to figure something out and can't find it anywhere.
I'm using Netlify CMS and I set up the images folder to be uploads
using public_folder: uploads
(in config.yml for the CMS) but now that I have this working correctly I see that I have an uploads
folder and a static
folder. This is duplicating all the images.
@peterlazzarino do you have the same issue?
@jonathanphz the name should match a corresponding entry for gatsby-source-filesystem AFAIK
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/static/img`,
name: "media"
}
}
In my site the "media" named folder is referenced above, for gatsby-remark-relative-images as "media" and then in my config.yml I have the following
media_folder: static/img
public_folder: img
@peterlazzarino yeah that's what I think but could not find documentation on using 'name' in options: {}
So on your public directory do you have an img
directory and a static
directory which both have the same images?
Right now the generated images are being placed in both for me - creating lots of duplicate image files.
When I inspect the images using the browser dev tools I see they're being served from static
and not img
. Which makes sense but still there's the issue of duplicate files.
@jonathanphz @peterlazzarino The options.name
config was removed in the latest version (which supports Gatsby v2), so you shouldnt need to worry about it anymore. The plugin will resolve all relative links from gatsby-source-filesystem
. Just need:
{
resolve: `gatsby-remark-relative-images`,
}
If you have issues or feature request please feel free to open an issue on https://github.com/danielmahon/gatsby-remark-relative-images
@jonathanphz my images only end up in the static/img folder. Not sure how they'd end up in both, is the CMS inserting them in both places on publish?
@peterlazzarino I figured it out. I had duplicate gatsby-transformer-remark
and gatsby-plugin-sharp
in the gatsby-config.js
file
Sorry everyone
Netlify CMS only commits images to one destination, whatever path you've set as media_folder
in your CMS config.yml. You can check the commits created by Netlify CMS in your repo to confirm this.
@kinduff Unfortunately, I can't replicate your success. I tried following your steps exactly. I created the src/content
and static/assets
folders and added a markdown file with frontmatter that links to an image in the assets folder, but when I try to run this same sample query in GraphiQL:
{
allMarkdownRemark {
edges {
node {
frontmatter {
image {
childImageSharp {
fluid(maxWidth: 200) {
src
}
}
}
}
}
}
}
}
, I still get the same Field "image" must not have a selection since type "String" has no subfields.
error. If I query for just image
directly I get the string that was set in the frontmatter.
I've created a repo with my attempt here. Does anybody know why it doesn't work?
@cmmartti did you tried this: https://github.com/gatsbyjs/gatsby/issues/5990#issuecomment-438315682 ??
@jonathanphz Yes I have, that's why I'm so confused. Maybe I'm using different library version(s) that are not compatible? I don't what else it could be.
@cmmartti I just cloned and ran your repo and I'm able to query
Try cleaning up your app (.cache, public and node_modules) and run npm install
again. I didn't update, I just cloned, installed and ran gatsby develop
. Here's the generated package-lock.json
https://gist.github.com/kinduff/4def00df2ea189c578caaacaedef791f
@kinduff @cmmartti
I have also tried your example - cloned, installed and ran gatsby develop
but met the same issue as you...
Would it be possible to compare environments?
OS: Windows 10
Node: v11.1.0 (also tried v11.2.0)
NPM: v6.4.1
Update:
Tested on a colleague's mac which is working! Could be a Windows issue if @cmmartti is on Windows...
OS: macOS mojave
Node: v11.2.0
NPM: v6.4.1
@Coder2012 can you link to your package.json like @kinduff did?
@Coder2012 can you link to your package.json like @kinduff did?
@peterlazzarino I believe @kinduff posted his package-lock.json
rather than his package.json
.
As requested - package-lock.json
sorry @Coder2012 that's what I meant :) Seems they are identical, I can test this on my windows machine later to try to verify this as well
Deleting the cache
, public
, and node_modules
folders changed nothing.
@Coder2012 I am also on Windows 10. Node 10.11, npm 6.0.1. Also, my package-lock.json is nearly identical to @kinduff's. So it seems that this is a Windows issue.
Posting sys information of the working example above. Hope this is not an OS issue.
OS: Linux 4.14.80-1-MANJARO x86_64 GNU/Linux
NPM: 6.4.1
Node: 8.9.0
I will try your example on my windows machine later this afternoon. I will also try the solution i have used in the past which doesn't depend on the gatsby-remark-relative-images plugin to try and narrow down the root cause.
@peterlazzarino @kinduff
I have just tested the example by @cmmartti using Windows Subsystem Linux - Ubuntu on Windows 10 Enterprise and it works for me.
Given this is a Linux environment I do believe it's pointing more toward a Windows OS issue.
It fails for me on Windows 10, Node 8.11.4 and NPM 5.6.0
I'm going to poke around a bit here to see if I can narrow this down.
@Coder2012 @cmmartti @kinduff
Now that we know its reproducible on windows only I decided to try a solution based on one I use in a project after I was not able to get gatsby-remark-relative-images working (maybe it's because I was building it on windows π.
My fork that works on windows is here
my only change was removing the gatsby-remark-relative transform from gatsby-node and implementing my own, admittedly crude solution. This (IMO) isolates the break to gatsby-remark-relative-images and I will be adding an issue there.
Also fails for me on Win10 / Node 10.6.0 / npm 6.1.0 and I'm new to GatsbyJS/Netlify CMS but am willing to test if someone can give me specific directions.
I will try to take a look at this today or this weekend. My gut says itβs a windows path issue and probably a quick fix once I find the offending line.
Latest 0.2.1 of the gatsby-remark-relative-images plugin is working fine for me now on Windows 10 guys. Thank you.
Woo thanks everyone π
As stated the latest version 0.2.1 of gatsby-remark-relative-images should fix windows support. Thanks @haroldhues, @peterlazzarino, and everyone for the fix and testing π
Relative image path support is now in beta as of Netlify CMS 2.9.8-beta.2 - try it out:
npm update netlify-cms-app@beta
Then add media_folder_relative: true
to your Netlify CMS config.
https://github.com/gatsbyjs/gatsby/issues/5990#issuecomment-433664162
This worked for me (on Mac) with one change: my content folder could not have any sub folders. all .md
files need to be in a flat folder.
I followed all the above suggestions plus this blog was the final nail in the coffin regarding this issue
https://theleakycauldronblog.com/blog/problems-with-gatsby-image-and-their-workarounds/
Most helpful comment
As stated the latest version 0.2.1 of gatsby-remark-relative-images should fix windows support. Thanks @haroldhues, @peterlazzarino, and everyone for the fix and testing π