ChristopherBiscardi / gatsby-mdx

Gatsby+MDX • Transformers, CMS UI Extensions, and Ecosystem Components for ambitious projects

Home Page:https://gatsby-mdx.netlify.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

id attributes on headers (for HTML bookmarks) missing

adueck opened this issue · comments

In the HTML being rendered by the <MDXRenderer> component, the headers are missing the id attribute with a slug that allows for the creation of HTML Bookmarks / internal links to the various headings.

The heading information is available from queries:

{    
    allMdx 
    (sort: { fields: [frontmatter___date], order: ASC }) {
      edges {
        node {
          tableOfContents   <--- HEADING url SLUGS AVAILABLE HERE
          id
        }
      }
    }		
}

Which gives us information something like this:

"tableOfContents": {
    "items": [
        {
            "url": "#first-heading",
            "title": "First Heading"
        },
        {
            "url": "#second-heading",
            "title": "Second Heading"
        },
    ]
}    

Each of the heading elements that get created should be rendered with an id attribute that provides the corresponding url value, shouldn't it? That way we could create internal links to different sections on the page, but currently we can't do this.

So given an mdx file with:

# First Heading

## Second Heading

It should render the elements as:

<h1 id="first-heading">First Heading</h1>
<h2 id="second-heading">Second Heading</h2>

But we get elements without the handy id attributes

<h1>First Heading</h1>
<h2>Second Heading</h2>

If this is not expected behavior, I would say that this is a really crucial feature.

Thanks for all your work!

We generally follow remark in this regard, which I don't think does this by default (or at least didn't?). This can be implemented by using a Heading component in MDXProvider though with the appropriate slugging algorithm. If remark does this by default then we should too, otherwise we should provide a component to handle it if remark still relies on sub-plugins to do it.

There's a PR in #389 that I need to get around to reviewing which provides such a component as an installable package.

Thanks for all your work!

❤️

Hmm, you're right remark doesn't do that by defailt but looks like there is a ready-made plugin for remark that remark has to add these id slugs. 😄

Plugin: remark-slug 👍

Hi,

both approaches are fine to me but if self-generation is the recommended approach I suggest to add a reliable specification of the algorithm. You don't want to end up with just 98% of the ToC working because the slugs on GraphQL think a certain special character is to be replaced with fooBar and the other thinks that it should be omitted.

Making remark-slug the reference explicit could be a good option, they use github-slugger
( https://github.com/Flet/github-slugger ), so directly using that package could also be a reference.

P.S: github-slugger is stateful (detects duplicates and adds -1 -2 etc). So that's a bit of a hurdle to get its state to per-page but not for the whole site in a React friendly way?

@adueck Did you find any workaround for the issue already? I was hoping to just switch my .md blog to .mdx blog with better styling, but there are roadblocks all along the way, TOC being one of them

Ok, so here's what worked for me. Turned out to be quite simple.
I just added some remark plugins

{
      resolve: `gatsby-plugin-mdx`,
      options: {
        gatsbyRemarkPlugins: [
          {
            resolve: 'gatsby-remark-images',
            options: {
              maxWidth: 970
            }
          },
          `gatsby-remark-autolink-headers`
        ]
      }
    },
```###