Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to convert dynamic data to MDX #55

Open
belkocik opened this issue Jun 12, 2021 · 14 comments
Open

How to convert dynamic data to MDX #55

belkocik opened this issue Jun 12, 2021 · 14 comments

Comments

@belkocik
Copy link

belkocik commented Jun 12, 2021

Hello, I got data on GraphCMS in markdown text and I'd like to convert it to MDX. Could you tell me how to do it? I've installed mdx-bundler.
content: portfolioItem.portfolios[0].content, // <--- it containts the markdown text from GraphCMS.
I tried with mdx-remote but there were errors with severity vulnerabilities

I got

import { bundleMDX } from "mdx-bundler";

export const getStaticProps = async ({ params }) => {
  const portfolioItem = await getPortfolioItem(params.slug);
  return {
    props: {
      portfolioItem: portfolioItem.portfolios[0],
      content: portfolioItem.portfolios[0].content,
    },
  };
};

export default function Home({ portfolioItem, content }) {
  console.log(portfolioItem);
  return (
        <div className="prose prose-xl max-w-none mt-4 text-justify  dark:text-gray-100 mb-10">
          {content}
        </div>
  );
}
@Arcath
Copy link
Collaborator

Arcath commented Jun 13, 2021

mdx-bundler can absolutely take a string from your CMS and bundle it!

In your getStaticProps you need to use bundleMDX to turn the string into a bundle, then pass it through props

const {code} = await bundleMDX(portfolioItem.portfolios[0].content)

return {
  props: {
    portfolioItem: portfolioItem.portfolios[0],
    code,
  },

Then add import {getMDXComponent} from 'mdx-bundler/client' to your page and output it like so:

export default function Home({ portfolioItem, content }) {
  const Component = React.useMemo(() => getMDXComponent(code), [code])
  return (
        <div className="prose prose-xl max-w-none mt-4 text-justify  dark:text-gray-100 mb-10">
          <Component />
        </div>
  );
}

There are a whole host of options that can improve the way MDX is handled depending on your needs which you can find here: https://github.com/kentcdodds/mdx-bundler#options

@belkocik
Copy link
Author

belkocik commented Jun 14, 2021

Thank you for your reply :). I got error when I click the post with markdown text:

Error: Build failed with 1 error:
__mdx_bundler_fake_dir__/_mdx_bundler_entry_point.mdx:23:55: error: [plugin: esbuild-xdm] Could not parse expression with acorn: Unexpected token

This error happened while generating the page. Any console logs will be displayed in the terminal window.

my 23 line is: const { code } = await bundleMDX(portfolioItem.portfolios[0].content);

my [slug].js file:
https://codepen.io/belkocik/pen/JjWemMV

@Arcath
Copy link
Collaborator

Arcath commented Jun 14, 2021

Sounds like an error in the MDX, what is line 23 excluding any frontmatter, of the MDX you are getting from your cms?

@belkocik
Copy link
Author

belkocik commented Jun 14, 2021

You mean what I got in content section in my graphCMS?

# Risus varius ad magna consequat sociosqu mol

Lorem ipsum dolor sit amet consectetur adipiscing elit hac per gravida ac, sed accumsan justo diam bibendum molestie feugiat nec nunc vehicula. Pulvinar tempus ante sociosqu litora ultrices sagittis lacus euismod purus tempor, risus rhoncus egestas nec penatibus aliquam ligula elementum. Posuere platea pretium commodo arcu viverra cubilia lectus, euismod eros mi maecenas quam sodales class porta, mattis a potenti risus consequat ligula. 

Ut sodales consequat augue nam integer curae cursus aliquet natoque vehicula euismod, orci eleifend ridiculus vitae quis laoreet ultricies placerat fames habitant libero, varius curabitur felis justo magnis imperdiet aptent lacus porttitor porta. Dignissim pharetra convallis augue bibendum enim commodo molestie ridiculus, condimentum potenti hendrerit primis libero orci imperdiet sapien, nostra vivamus et pellentesque parturient penatibus taciti. Senectus lacus scelerisque feugiat interdum vivamus proin massa parturient, justo pulvinar ornare sapien facilisis hendrerit in class, magna euismod vestibulum mollis natoque facilisi dictumst. 

## Dui aliquam eu imperdiet egestas ul

- Vehicula ad nulla neque torquent, interdum himenaeos tortor.

- Neque senectus feugiat varius eros, ut purus scelerisque.

- Vitae magnis varius nec in, accumsan dui auctor.

- Pellentesque laoreet sapien litora fusce hac, dictum nibh curae.



Feugiat fringilla consequat nascetur nisi in nulla aenean curae at aptent, ad leo placerat varius urna est vel rhoncus rutrum tincidunt, maecenas nostra nisl conubia fermentum blandit ligula orci semper. Conubia pretium pulvinar phasellus sollicitudin sociosqu lectus proin justo placerat auctor, sociis senectus libero pharetra cum parturient erat a faucibus vehicula etiam, laoreet velit nisl platea dictumst fusce fringilla semper tincidunt. 

First he wanted to stand up quietly and undisturbed, get dressed, above all have breakfast, and only then consider further action, for (he noticed this clearly) by thinking things over in bed he would not reach a reasonable conclusion. He remembered that he had already often felt a light pain or other in bed, perhaps the result of an awkward lying position, which later turned out to be purely imaginary when he stood up, and he was eager to see how his present fantasies would gradually dissipate. That the change in his voice was nothing other than the onset of a real chill, an occupational illness of commercial travelers, of that he had not the slightest doubt.

    function metamorphose(protagonist,author){
        if( protagonist.name.first === 'Gregor' && author.name.last === 'Kafka' ){
            protagonist.species = 'insect';
        }
    }

from my VSCode terminal:

> __mdx_bundler_fake_dir__/_mdx_bundler_entry_point.mdx:23:46: error: [plugin: esbuild-xdm] Could not parse expression with acorn: Unexpected token
    23 │     function metamorphose(protagonist,author){
Error: Build failed with 1 error:
__mdx_bundler_fake_dir__/_mdx_bundler_entry_point.mdx:23:55: error: [plugin: esbuild-xdm] Could not parse expression with acorn: Unexpected token
    at failureErrorWithLog (C:\Users\bubuq3\Desktop\Next.js-portfolio\portfolio-cms\node_modules\esbuild\lib\main.js:1449:15)
    at C:\Users\bubuq3\Desktop\Next.js-portfolio\portfolio-cms\node_modules\esbuild\lib\main.js:1131:28
    at runOnEndCallbacks (C:\Users\bubuq3\Desktop\Next.js-portfolio\portfolio-cms\node_modules\esbuild\lib\main.js:921:63)
    at buildResponseToResult (C:\Users\bubuq3\Desktop\Next.js-portfolio\portfolio-cms\node_modules\esbuild\lib\main.js:1129:7)
    at C:\Users\bubuq3\Desktop\Next.js-portfolio\portfolio-cms\node_modules\esbuild\lib\main.js:1236:14
    at C:\Users\bubuq3\Desktop\Next.js-portfolio\portfolio-cms\node_modules\esbuild\lib\main.js:609:9
    at handleIncomingPacket (C:\Users\bubuq3\Desktop\Next.js-portfolio\portfolio-cms\node_modules\esbuild\lib\main.js:706:9)
    at Socket.readFromStdout (C:\Users\bubuq3\Desktop\Next.js-portfolio\portfolio-cms\node_modules\esbuild\lib\main.js:576:7)
    at Socket.emit (events.js:315:20)
    at addChunk (internal/streams/readable.js:309:12)
    at readableAddChunk (internal/streams/readable.js:284:9)
    at Socket.Readable.push (internal/streams/readable.js:223:10)
    at Pipe.onStreamRead (internal/stream_base_commons.js:188:23) {
  errors: [
    {
      detail: [Error],
      location: [Object],
      notes: [],
      pluginName: 'esbuild-xdm',
      text: 'Could not parse expression with acorn: Unexpected token'
    }
  ],
  warnings: []
}

@Arcath
Copy link
Collaborator

Arcath commented Jun 14, 2021

MDX doesn't support indented code like that, wrapping it in js</code> and <code> fixes the problem for me.

@belkocik
Copy link
Author

I removed from my CMS

    function metamorphose(protagonist,author){
        if( protagonist.name.first === 'Gregor' && author.name.last === 'Kafka' ){
            protagonist.species = 'insect';
        }
    }

and this looks like this: It hasn't converted it to markdown
image

@Arcath
Copy link
Collaborator

Arcath commented Jun 14, 2021

What does the HTML look like? Has it put in <p> and <h2> tags? I know tailwind resets everything to a level playing field so it may just be a styling issue.

@belkocik
Copy link
Author

Yes when I click f12 and inspect that there are ul,li, p tags ;/
image

@Arcath
Copy link
Collaborator

Arcath commented Jun 14, 2021

Looks like mdx-bundler is doing its job :)

Is tailwind-typography installed and configured?

@belkocik
Copy link
Author

belkocik commented Jun 14, 2021

Thank you, everything works right now 👍 appreciate your help 😄
btw. is it possible to highlight the syntax in js? there is just gray color of the text :(

    function metamorphose(protagonist,author){
        if( protagonist.name.first === 'Gregor' && author.name.last === 'Kafka' ){
            protagonist.species = 'insect';
        }
    }

image

image

@Arcath
Copy link
Collaborator

Arcath commented Jun 14, 2021

Syntax highlight is possible with a remark plugin, I use remarkHighlight to do it on my site

@belkocik
Copy link
Author

belkocik commented Jun 18, 2021

Got an error:

Error: Additional keys were returned from `getStaticProps`. Properties intended for your component must be nested under the `props` key, e.g.:

	return { props: { title: 'My Title', content: '...' } }
export const getStaticProps = async ({ params }) => {
  const portfolioItem = await getPortfolioItem(params.slug);
  const { code } = await bundleMDX(portfolioItem.portfolios[0].content, {
    xdmOptions(options) {
 
      options.remarkPlugins = [
        ...(options.remarkPlugins ?? []),
        remarkHighlight,
      ];

      return options;
    },
  });

  return code;
};

@Arcath
Copy link
Collaborator

Arcath commented Jun 22, 2021

The return from getStaticProps needs to be an object with a props object that gets passed to your component

for example:

export const getStaticProps = async ({ params }) => {
  const portfolioItem = await getPortfolioItem(params.slug);
  const { code } = await bundleMDX(portfolioItem.portfolios[0].content, {
    xdmOptions(options) {
 
      options.remarkPlugins = [
        ...(options.remarkPlugins ?? []),
        remarkHighlight,
      ];

      return options;
    },
  });

  return {props: {code}};
};
``

@belkocik
Copy link
Author

belkocik commented Jul 1, 2021

Got it like:
image

im my GraphCMS: content section i got:

js~~~

    function metamorphose(protagonist,author){
        if( protagonist.name.first === 'Gregor' && author.name.last === 'Kafka' ){
            protagonist.species = 'insect';
        }
    }
~~~

And it still doesn't highlight the code as it is javascript syntax.

export const getStaticProps = async ({ params }) => {
  const portfolioItem = await getPortfolioItem(params.slug);
  const { code } = await bundleMDX(portfolioItem.portfolios[0].content, {
    xdmOptions(options) {
      options.remarkPlugins = [
        ...(options.remarkPlugins ?? []),
        remarkHighlight,
      ];

      return options;
    },
  });

  return { props: { code, portfolioItem: portfolioItem.portfolios[0] } };
};

I've imported: import remarkHighlight from "remark-highlight.js";
and that is how I pass it:

export default function Home({ portfolioItem, content, code }) {

  const Component = React.useMemo(() => getMDXComponent(code), [code]);

 return (
     <div className="prose prose-xl max-w-none mt-4 text-justify dark:text-gray-100 mb-10 cms-content">
            <Component />
          </div>
)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants