hashicorp / next-mdx-remote

Load MDX content from anywhere
Mozilla Public License 2.0
2.59k stars 139 forks source link

Breaks with latest version of remark-gfm; unhelpful error message #403

Open HerbCaudill opened 11 months ago

HerbCaudill commented 11 months ago

I'm not really sure where to file this, but:

I just started using next-mdx-remote, and everything was working fine until I added the remark-gfm plugin. This is the entire error I was getting, with no further information:

Error: [next-mdx-remote] error compiling MDX: Cannot read properties of undefined (reading 'inTable')

After some trial and error, I narrowed the issue down to inline code blocks -- I only get the error when they're present.

After a bit more flailing I figured out that remark-gfm released version 4.0 a few days ago, which uses remark-parser v11, while @mdx-js/mdx uses remark-parser v10. Rolling remark-gfm back to version 3.x fixed the issue.

I've made a minimal repro here: https://codesandbox.io/p/github/HerbCaudill/next-mdx-remote-vs-remark-gfm

I'd assume whatever needs to be fixed is not in this library but somewhere upstream; noting the solution here in case it helps anyone.

However I would suggest revisiting the error formatter in format-mdx-error.ts. For some reason it removes the stack trace before throwing MDX formatting errors, which made this very difficult to debug. I can't imagine what the reason for doing that would be.

https://github.com/hashicorp/next-mdx-remote/blob/4b2c128f16dba9d440fe7f4931e04bb8c5d74474/src/format-mdx-error.ts#L58-L66

wdavidw commented 11 months ago

I confirm having the same issue, a simple MDX with an inline code triggers the error message.

ethernal commented 11 months ago

I have the same plugin but i use bright as a wrapper around pre tags, you can see in repo here: https://github.com/ethernal/personal-site/blob/main/src/constants/componentMap.ts

and the CodeSnippet is here: https://github.com/ethernal/personal-site/blob/main/src/components/CodeSnippet/CodeSnippet.tsx

and I have no issues with having remark-gfm even after upgrading to NextJS 13.5 (there are other issues with it though). See: https://github.com/ethernal/personal-site/blob/main/src/constants/constants.ts and exported MDXOptions.

jordanlambrecht commented 11 months ago

Confirming, same issue.

TheWilley commented 11 months ago

After a bit more flailing I figured out that remark-gfm released version 4.0 a few days ago, which uses remark-parser v11, while @mdx-js/mdx uses remark-parser v10. Rolling remark-gfm back to version 3.x fixed the issue.

I can confirm this solution works, good catch! The error appeared for me no matter what GFM component I used, although I first noticed after trying to add tables.

TheWilley commented 11 months ago

In addition to the error which appears in the browser window, an error is also printed in the console, although it doesn't yield any additional useful info:

- error {
  name: 'Error',
  source: 'server',
  message: '[next-mdx-remote] error compiling MDX:\n' +
    "Cannot set properties of undefined (setting 'inTable')\n" +
    '\n' +
    'More information: https://mdxjs.com/docs/troubleshooting-mdx',
  stack: '',
  digest: '199367153'
}
vickkhera commented 11 months ago

I also get this error if there is a table in the markdown.

The solution to use v3 works for me for tables and back-ticks.

ovflowd commented 11 months ago

Is this somewhat going to be addressed by the maintainers here? As the last release was in March.

jmarroyave-compsci commented 11 months ago

Some feedback, reverting 3.0.1 resolves the issue

I noticed that this happen when trying to parse Tables, but specifically, tables with headers.

| a | b  |  c |  d  |
| - | - | - | - |
| a | b  |  c |  d  |

if the hyphens row is included this throw error of this.data is null

| a | b  |  c |  d  |
| a | b  |  c |  d  |

if the hyphens row is NOT included doesn't throw the error but doesn't parsed it either

Vacilando commented 11 months ago

Same here, reverting remark-gfm to v3.0.1 resolves the issue.

jmarroyave-compsci commented 11 months ago

The problem is in https://github.com/syntax-tree/mdast-util-gfm-table/

lib/index

line 79 //this.setdata.inTable = true this.setData('inTable', true)

and line 89 //this.data.inTable = undefined this.setData('inTable')

the problem is because this.data is undefined while trying to update the prop inTable

this is just a fix, but it breaks the build, apparently 'CompileContext' is supposed to initialize this.data, but it isn't.

Error: lib/index.js(79,8): error TS2339: Property 'setData' does not exist on type 'CompileContext'. error while trying to do a pull request

Can someone give me feedback about 'CompileContext'?

ovflowd commented 11 months ago

The problem is in syntax-tree/mdast-util-gfm-table

lib/index

line 79 //this.setdata.inTable = true this.setData('inTable', true)

and line 89 //this.data.inTable = undefined this.setData('inTable')

the problem is because this.data is undefined while trying to update the prop inTable

this is just a fix, but it breaks the build, apparently 'CompileContext' is supposed to initialize this.data, but it isn't.

Error: lib/index.js(79,8): error TS2339: Property 'setData' does not exist on type 'CompileContext'. error while trying to do a pull request

Can someone give me feedback about 'CompileContext'?

FYI this issue is already solved on all upstream libraries. Problem is, next-mdx-remote needs to update their version of said libraries, otherwise some will be using older ones whilst other newer ones and that will well.. break.

andri2621 commented 11 months ago

I have the same plugin but i use bright as a wrapper around pre tags, you can see in repo here: https://github.com/ethernal/personal-site/blob/main/src/constants/componentMap.ts

and the CodeSnippet is here: https://github.com/ethernal/personal-site/blob/main/src/components/CodeSnippet/CodeSnippet.tsx

and I have no issues with having remark-gfm even after upgrading to NextJS 13.5 (there are other issues with it though). See: https://github.com/ethernal/personal-site/blob/main/src/constants/constants.ts and exported MDXOptions.

i do like from your repo, but it still have same issue. Screenshot from 2023-10-23 19-26-51

piscopancer commented 9 months ago

I downgraded remark-gfm from version 4.0.1 to version 3.0.1 and the error was gone

limeojin363 commented 8 months ago

I downgraded remark-gfm from version 4.0.1 to version 3.0.1 and the error was gone

I'm using next@14.0.4 and this works for me. Thanks!

ghost commented 8 months ago

Not sure if this is related, but we faced a similar problem when using react-markdown alongside remark-gfm; and we are able to use remark-gfm: 4.0.1 when react-markdown is installed with a version of ^9.0.1.

SiegeSailor commented 8 months ago

Same issue. This is what I had:

"dependencies": {
    "@reduxjs/toolkit": "1.9.5",
    "@sentry/browser": "7.57.0",
    "framer-motion": "10.13.0",
    "next": "13.4.5",
    "next-mdx-remote": "4.4.1",
    "prismjs": "1.29.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-icons": "4.9.0",
    "react-redux": "8.1.1",
    "rehype-slug": "6.0.0",
    "remark": "15.0.1",
    "remark-gfm": "4.0.0", // Downgrading this to 3.0.1 solves the Error: [next-mdx-remote] error compiling MDX: Cannot read properties of undefined (reading 'inTable') issue.
    "remark-sectionize": "2.0.0",
    "remark-unwrap-images": "4.0.0",
    "unist-util-visit": "5.0.0"
  },
justinmahar commented 7 months ago

Downgrading remark-gfm to version 3 solves the problem on my end.

npm i remark-gfm@3

(For reference, I'm using Storybook with gfm in my MDX files and am following their official guide for adding gfm support)

DiegoBistro commented 7 months ago

Same issue here, reverting remark-gfm to v3.0.1 resolves the issue.

But I don't like having outdated libraries. Is it possible that the problem hasn't been fixed yet?

daasrattale commented 7 months ago

I also confirm rolling back to v3.0.1 works, still we need a fix for the v4 as well ://

swaffelen commented 6 months ago

Bumping it as we still need a proper fix

TheWilley commented 6 months ago

For anyone landing on this page, the issue has been acknowledged in a discussion thread and a fix is on its way. See https://github.com/hashicorp/next-mdx-remote/discussions/437.

karlhorky commented 6 months ago

Another update from @dstaley: Canary releases of v5 are now available (check out the first comment by the bot to get the latest published canary version):

jbukuts commented 5 months ago

As an additional note for anyone trying to use @next/mdx or any other tool alongside next-mdx-remote. Most of the issues relate to conflicts in dependency versions.

For instance, when I tried using @next/mdx alongside it I hade to bump my @mdx-js/loader and @mdx-js/react versions down to match the next-mdx-remote package.json.

TL;DR Play package.json musical chairs with dependencies. Hopefully v5 fixes the chaos.

dstaley commented 5 months ago

@jbukuts Definitely give the canary release of v5 a shot! Should be much smoother sailing.

paigen11 commented 5 months ago

As an additional note for anyone trying to use @next/mdx or any other tool alongside next-mdx-remote. Most of the issues relate to conflicts in dependency versions.

For instance, when I tried using @next/mdx alongside it I hade to bump my @mdx-js/loader and @mdx-js/react versions down to match the next-mdx-remote package.json.

TL;DR Play package.json musical chairs with dependencies. Hopefully v5 fixes the chaos.

I believe I'm having a similar issue, but was hoping you might help me sanity check my thinking here.

For my Next.js app, I'm using next-mdx-remote v4.4.1 and remark-gfm v3.0.1 together fine, however, when I plug remark-gfm into the next.config.mjs file (with next and @next/mdx at v14.1.4 and @mdx-js/loader and @mdx-js/react at v3.0.1), the mdx pages being wrapped with the <MDXProvider> component from mdx-js/react throw an error and won't render at all.

Obscure error message in the browser as it gets caught in an infinite error loop for all MDX files: TypeError: _main.mdx:TypeError: this.getData is not a function at new Promise (<anonymous>)

When I remove the remark-gfm plugin, they render without table styling (which I expect since remark-gfm is absent). And I have no issues with anything when mdx-js/react and mdx-js/loader are both v2.3.0.

Does this sound at all plausible, or am I completely off base here?

Here's my next.config.mjs file for reference:

import gfm from "remark-gfm";
import createMDX from "@next/mdx";

const withMDX = createMDX({
  options: {
    remarkPlugins: [gfm], // commenting this line out allows my MDX pages to render w/out table styling, leaving it in and the won't render
  },
});

const nextConfig = {
  pageExtensions: ["js", "jsx", "md", "mdx", "ts", "tsx"],
};

export default withMDX(nextConfig);
paigen11 commented 5 months ago

@dstaley any docs on how to use a canary release? I haven't (knowingly) used one, but I'm hoping it might fix the issue I've just described above

karlhorky commented 5 months ago

@paigen11 open the "Published 1 packages" on this comment:

Inside you'll find the version that you can add to your package.json file for next-mdx-remote (and then run npm install - or whatever your package manager install command is)

paigen11 commented 5 months ago

@karlhorky thanks very much - the canary release seems to have fixed my issue! I now have two follow up questions for you:

  1. When might we expect v5 to come out officially?
  2. As Next.js migrates to the mdx-components.tsx file at the root of the project, is it still necessary to pass a list of MDXComponents to the <MDXRemote > component? I'm just seeing if I can consolidate down some of these MDX component lists I have floating around in my project

For reference, I am still using the Next.js pages/ directory, not the new RSC app/ directory.

dstaley commented 5 months ago

@paigen11 I'm aiming to release v5 sometime this month, and hearing that it fixes your issue is a great thing to hear! As for mdx-components.tsx, it's not something we have specific support for. You could certainly define your components there and import them from there to pass to MDXRemote though!

vxsahu commented 5 months ago

Screenshot 2024-04-09 at 9 51 48 PM fix this bro -- how to use "Remarkplugins" in MdxRemote

paigen11 commented 5 months ago

@snypiie if you're using next-mdx-remote inside of a getStaticProps call, you'll need to do something like this to use the remark plugin with it.

import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from "next";
import { serialize } from "next-mdx-remote/serialize";
import { MDXRemote, MDXRemoteSerializeResult } from "next-mdx-remote";
import gfm from "remark-gfm";
// other imports here to fetch blog content (irrelevant to this example)

const BlogPostPage = ({ post, mdxSource }: BlogPostPageProps) => (
  <>
      <BlogPostContent post={post}>
        <MDXRemote {...mdxSource} components={MDXComponentMap} />
      </BlogPostContent>
  </>
);

export const getStaticPaths: GetStaticPaths = async () => {
  // code to figure out blog slug URLs
};

export const getStaticProps: GetStaticProps = async ({
  params,
}: GetStaticPropsContext) => {
  const { slug } = params as Params;
  const post = await getBlogArticleFromSlug(slug);

  const mdxSource = await serialize(post.content, {
    mdxOptions: { remarkPlugins: [gfm] },
  });

  return {
    props: {
      post,
      mdxSource,
    },
  };
};

export default BlogPostPage;

The part to focus on is the mdxSource function where { remarkPlugins: [gfm] } is included. That's what you need to add to make tables format correctly with next-mdx-remote

  const mdxSource = await serialize(post.content, {
    mdxOptions: { remarkPlugins: [gfm] },
  });
adityaptikao commented 3 months ago

Is this issue fixed yet or not because i would like to update my package to latest version but i could not because of this issue.

karlhorky commented 3 months ago

@adityaptikao I believe this issue should be fixed with v5

@dstaley if I'm correct about this being resolved with v5, should this issue be closed now?

vickkhera commented 3 months ago

Since v4 remark-gfm has worked for me after upgrading NextJS from 14.0 to 14.2.

@adityaptikao you can just try it and if it doesn't work for you just delete that git branch.