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

feat: Attach export to MDXContent? #14

Closed
domdomegg opened this issue Jan 14, 2024 · 7 comments
Closed

feat: Attach export to MDXContent? #14

domdomegg opened this issue Jan 14, 2024 · 7 comments

Comments

@domdomegg
Copy link

Not sure whether this is in scope for this plugin - feel free to close if so.

I'm hoping to use this plugin with Next.js so that I can insert a header component using the frontmatter content. I think I currently can't access it from _app.tsx, where this is currently rendered. I could access it by adding something to every .mdx file, but this adds overhead to writing pages that I want to avoid.

To fix this, I was hoping this plugin could add it to the component itself, e.g. so rather than:

export const frontmatter = {
  hello: 'frontmatter'
}

export default function MDXContent() {
  return <p>Rest of document</p>
}

It outputs:

export default function MDXContent() {
  return <p>Rest of document</p>
}

MDXContent.frontmatter = {
  hello: 'frontmatter'
}

This is somewhat similar to what's described in https://www.josephrex.me/frontmatter-with-nextjs-and-mdx/ - although the actual component would be in _app.tsx.


This is roughly what I had in mind for my _app.tsx:

import '../styles/globals.css';
import type { AppProps } from 'next/app';

const App: React.FC<AppProps> = ({ Component, pageProps }: AppProps) => {
  if (Component.displayName === 'MDXContent') {
    return (
      <>
        <Header frontmatter={Component.frontmattter} />
        <div className="max-w-sm md:max-w-2xl mx-auto px-8 py-12 md:my-24 prose animate-fade-up">
          <Component {...pageProps} />
        </div>
      </>
    );
  }

  return <Component {...pageProps} />;
};

export default App;
@remcohaszing
Copy link
Owner

I suggest you take a look at recma-nextjs-static-props.

@domdomegg
Copy link
Author

Thanks! I couldn't quite figure out how to get that one working, so I've done it a hacky way in recma-mdx-frontmatter. Closing this given there seem multiple ways to achieve what I wanted without this feature request.

@remcohaszing
Copy link
Owner

I’m glad you found a solution to your problem. Still, could you elaborate what wasn’t working for you with recma-nextjs-static-props?

@domdomegg
Copy link
Author

I think I didn't quite see how to but the bits together, at least on my inital look at it. I haven't given it another shot, but now I think it would roughly be:

  • use remark-mdx-frontmatter to export the frontmatter object
  • use recma-nextjs-static-props to add the frontmatter object to get static props
  • use pageProps in Next.js to access these static props in _app.tsx (although caveat I'm not sure this works - there seems to be a warning "App does not support Next.js Data Fetching methods like getStaticProps or getServerSideProps.")

Is that right?

I think the thing that would have made me more likely to take this route would be a more complete documentation example with an _app.tsx (not saying you need to do this - appreciate it's just one use case, and don't mean to shift the burden on you when it's something I could maybe have figured out).

(also as for timings - I played around with this yesterday, and only saw your comment suggesting recma-nextjs-static-props after I had created my separate recma plugin)

domdomegg added a commit to domdomegg/domdomegg.github.io that referenced this issue Jan 16, 2024
@domdomegg
Copy link
Author

Out of interest, I ended up giving implementing this a go. In short, yes the above works:

domdomegg/domdomegg.github.io@497ec45

I think using getStaticProps seems to change the developer experience a little. Live reload doesn't work quite as nicely: instead of instantly updating the right part, whenever any change is made the whole page reloads. I think this difference is minor though and someone smarter than me can probably figure out how to make it work with the above method.

@remcohaszing
Copy link
Owner

The distinction between getStaticProps vs a property on MDXContent you’re describing is interesting. Thanks for sharing.


I see some bugs in recma-mdx-frontmatter:

@domdomegg
Copy link
Author

Both good suggestions, I will look into them. I really appreciate the time you've put into reviewing the code and the kind way you've delivered the feedback!

I'm initially hesitant to reimplement parts of gray-matter, given it seems widely used and recommended in this space. I suspect trying to do so myself would likely introduce more bugs rather than less! But I see in jonschlinkert/gray-matter#147 it may be a bit stuck.

I agree pojoToEstree feels a little rough around the edges. I'll take a look at estree-util-value-to-estree. I was initially spooked by it being ESM, but I'll give it a revisit (and I know I might seem slightly crazy for still trying to maintain CJS - but it makes sense for where I want to use some of my packages: and for standardisation reasons it's nice to have all my packages use similar build processes etc.).

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