I'm trying to add a slug node field, had a look at https://github.com/gatsbyjs/gatsby/blob/master/www/gatsby-node.js & https://github.com/gatsbyjs/gatsby/blob/master/www/src/templates/template-blog-post.js
And here is my onCreateNode function
// Create slugs for files.
exports.onCreateNode = ({ node, boundActionCreators }) => {
const { createNodeField } = boundActionCreators
if (node.internal.type === 'File') {
createNodeField({
node,
name: 'slug',
value: path.basename(node.relativePath, '.md'),
})
}
}
and the query
export const postQuery = graphql`
query BlogPostBySlug($slug: String!) {
site {
siteMetadata {
title
author
}
}
markdownRemark(fields: { slug: { eq: $slug } }) {
id
html
fields {
slug
}
frontmatter {
title
date
}
}
}
`
But when I try to run this I get GraphQLError: Cannot query field "fields" on type "MarkdownRemark" any idea what am I doing wrong here?
Have you tried running the query in graphiql?
Yes, I get the same error

Can you verify your onCreateNode function is being called? By adding a console.log there?
It's getting called & returning an object with type ADD_FIELD_TO_NODE & the payload object inside it contains field object with a slug property inside of it.
Oh there is is. Your code has an if statement filtering nodes to only those of type "File". If you try querying File you'll see your field. You need to add the slug to nodes of type MarkdownRemark. Check out my blog for this pattern github.com/kyleamathews/blog
Thanks @KyleAMathews
I had the same problem doing the tutorial the programmatically create page. @KyleAMathews can you explain what was your solution. I don't understand the pattern github.com/kyleamathews/blog.
Thanks!
@morattoo You need something like this for example in Kyle's blog he is adding this field on MarkdownRemark in my case I'm adding it Mdx field so you need to know which field you want to modify.
exports.onCreateNode = ({node, actions}) => {
const {createNodeField} = actions
switch (node.internal.type) {
case '<FIELD TYPE YOU WANT TO CHANGE>': { // <-- Change this to match your usage.
const {
fileAbsolutePath,
} = node
createNodeField({
node,
name: 'slug',
value: `/blog/${path.basename(fileAbsolutePath, '.md')}`,
})
}
}
}
Also having no luck getting a custom field to stick to a node.
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions;
if (!isLeverNode(node)) return;
createNodeField({
node,
name: 'slug',
value: `${node.lever_id}_dvb`,
});
console.log('onCreateNode', node);
};
That console.log shows the node.fields.slug being added... but then when I try to access it from graphql, or from graphiQL its not there.
What ended up happening with this? Shouldn't the solution ultimately be to fix the code samples here: https://www.gatsbyjs.com/tutorial/part-seven/ ? Is there really that few people walking through the tutorial?
Root cause for me was I had put gatsby-node.js in the src folder instead of the root of the site as the tutorial directs -- my bad. Hopefully this helps someone else.
Most helpful comment
Oh there is is. Your code has an if statement filtering nodes to only those of type "File". If you try querying File you'll see your field. You need to add the slug to nodes of type MarkdownRemark. Check out my blog for this pattern github.com/kyleamathews/blog