Gatsby: Add a node field

Created on 11 Jul 2017  路  11Comments  路  Source: gatsbyjs/gatsby

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?

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

All 11 comments

Have you tried running the query in graphiql?

Yes, I get the same error

screen shot 2017-07-12 at 00 02 05

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rossPatton picture rossPatton  路  3Comments

dustinhorton picture dustinhorton  路  3Comments

Oppenheimer1 picture Oppenheimer1  路  3Comments

KyleAMathews picture KyleAMathews  路  3Comments

ferMartz picture ferMartz  路  3Comments