Gatsby: [gatsby-transformer-remark] Improve opaque need for slug field

Created on 14 Feb 2018  ·  14Comments  ·  Source: gatsbyjs/gatsby

Description

The gatsby-transformer-remark has an opaque dependency on having a slug field. It's needed if the tableOfContents property is requested as part of a GraphQL query. You have to use the createNodeField action on markdown nodes to add a field called 'slug', or else the query fails and it's not clear why.

Environment

Gatsby version: 1.9.197

Actual result

Given this query

query AllPostsQuery {
  allMarkdownRemark {
    edges {
      node {
        tableOfContents
        frontmatter {
          title
        }
      }
    }
  }
}

It will have an error for the tableOfContents field

{
  "errors": [
    {
      "message": "Cannot read property 'slug' of undefined",
      "locations": [
        {
          "line": 13,
          "column": 6
        }
      ],
      "path": [
        "markdownRemark",
        "tableOfContents"
      ]
    }
  ],
  "data" : ...
}

Expected behavior

The error should at least describe the need for a slug field and a link to where the person can read more about how to add it.

Most helpful comment

Not sure why this is a "feature". Atleast on Gatsby V2, slug is nowhere to be seen in any examples. The error is in no way indicative that a node field by that name needs to be added, and populated for this to work.

As a user, I just installed gatsby-transformer-remark and looked through graphiql fields, where the error immediately hit my face and I spent quite some time reading the sources to see what I had configured wrong.

All 14 comments

:-( didn't realize this was happening. Yeah, this is very wrong.

Perhaps I don't really understand what the tableOfContents is doing — why does it need to construct the full URL? Shouldn't it just do a relative link since it's all on the same page?

That's what I thought. I found this PR (https://github.com/gatsbyjs/gatsby/pull/2856) about a special case that added the full URLs by default. I'm planning on adding an option to the plugin to specify whether or not you want to use full URLs vs relative hashes.

@lourd yeah... ok — yeah slug shouldn't have been hard coded. Make it a full URL should be optional and if you select that, you should have to include a function which pulls the path off the MarkdownRemark node.

@Swizec how's that sound?

@lourd @KyleAMathews I like the idea of adding an option to enable full URLs. Didn't realize my PR would break things like that.

The original reason I added that was so you can print the tableOfContents on pages other than the page itself. Like on an index for your entire site. Useful for books/workshops/docs where it's convenient to have a full index on the frontpage.

I think at some point I forgot that a slug is something you have to add manually through node creation and not something the markdown plugin does by default. Maybe it should?

FYI, I believe the field slug is also an opaque requirement of the gatsby-plugin-feed according to my reading of this.

I'm not sure if this is the right issue for what I'm going for but generating table of contents in index page might have been broken as well.

I have an index page generated from a Markdown file (index.md) and my template uses Remark's tableOfContents, and for some reason it generates a broken anchor link.

It would generate this:

<a href="//#example-anchor">

instead of this:

<a href="#example-anchor">

Not sure why this is a "feature". Atleast on Gatsby V2, slug is nowhere to be seen in any examples. The error is in no way indicative that a node field by that name needs to be added, and populated for this to work.

As a user, I just installed gatsby-transformer-remark and looked through graphiql fields, where the error immediately hit my face and I spent quite some time reading the sources to see what I had configured wrong.

How and where do I configure this even? 😬

Actually, I was really hoping that the headings selection set in GQL included the header slug because I'm building a sub-menu in the left nav...

The table of contents field should take an argument for which field to use and if an argument isn't provided, default to "slug". If a slug field doesn't exist, then it should return null.

I'd like to give this a go if no one is touching this

👏 Please do!

hmm, I'm a little confused regarding this. My code creates a slug field using setFieldsOnGraphQLNodeType, but I still get the error Skipping TableOfContents. Field 'slug' missing from markdown node. I can only assume that my slug hasn't quite yet been created when the remark plugin runs. I know that the slug is eventually created because I can query it from GraphiQL. Any thoughts?

@nadrane Not sure what your exact issue is, but I don't think setFieldsOnGraphQLNodeType is what you need. I believe you need to have a hook that calls createNodeField for each markdown node.

That worked. thank you :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rossPatton picture rossPatton  ·  3Comments

3CordGuy picture 3CordGuy  ·  3Comments

magicly picture magicly  ·  3Comments

dustinhorton picture dustinhorton  ·  3Comments

andykais picture andykais  ·  3Comments