contentlayerdev / contentlayer

Contentlayer turns your content into data - making it super easy to import MD(X) and CMS content in your app
https://www.contentlayer.dev
MIT License
3.33k stars 201 forks source link

Contentlayer throws an error with remark-heading-id or rehype-custom-heading-id #257

Closed kouliavtsev closed 2 years ago

kouliavtsev commented 2 years ago

For some reason, I am not able to get working with remark-heading-id or rehype-custom-heading-id

I simply want to convert this syntax:

### My Great Heading {#custom-id}

to

<h3 id="custom-id">My Great Heading</h3>

Here is an example of my setup in contenlayer.config.js.

import remarkHeadingId from "remark-heading-id";
...

export default makeSource({
  contentDirPath: "content",
  documentTypes: [Post],
  mdx: {
    remarkPlugins: [remarkHeadingId],
    // 👇 used with rehype-autolink-headings
    [
      rehypeAutolinkHeadings,
      {
        behavior: "prepend",
        properties: {
          className: ["anchor"],
        },
        test: ["h1", "h2", "h3"],
      },
    ],
  },
});

After rebuilding the pages, I get this error.

✘ [ERROR] [plugin @mdx-js/esbuild] Could not parse expression with acorn: Unexpected character '#'

Can anyone share an example on how to add custom ids?

stefanprobst commented 2 years ago

Markdown and MDX are not the same, they are parsed differently. See MDX Syntax.

in your case i think what is happening is that the curly brace is treated by the MDX parser as the start of a javascript expression, hence the error message.

you could try adapting the remark-heading-id plugin here to use other special characters to denote a custom id (or you could use rehype-slug slug if you're ok with autogenerated ids).

kouliavtsev commented 2 years ago

@stefanprobst

Thanks for the help, it has pointed me on the right path. 👍

In this issue, I have found out that there is a plugin that fixes it.

Thanks for all the pointers! ended up making a separate package: remark-custom-heading-id. The micromark code is substantially different than the unist-util-visit-based approach, and the old extension is still good-enough for non-MDX cases.