withastro / astro

The web framework for content-driven websites. ⭐️ Star to support our work!
https://astro.build
Other
45.68k stars 2.4k forks source link

Inconsistent MDX rendering between pages and <Content> #5027

Closed christian-hackyourshack closed 1 year ago

christian-hackyourshack commented 1 year ago

What version of astro are you using?

1.4.6

Are you using an SSR adapter? If so, which one?

None

What package manager are you using?

pnpm

What operating system are you using?

linux

Describe the Bug

If you render an MDX page directly, you can export const components = { h1: Title } and get your h1-headings rendered with your custom component. The docs say, you can also pass components in via the components prop (https://docs.astro.build/en/guides/integrations-guide/mdx/#custom-components-with-imported-mdx), but actually it works only if you pass them in via the prop. Have a look at the following repro:

I think, this is not according to the docs, inconsistent and hence unintuitive.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-cvbuxz-ys5fyv?file=src/pages/mdx-through.astro

Participation

christian-hackyourshack commented 1 year ago

The issue seems to be in the application of components in MDX-JS: They are always only applied to the immediate generated component and not passed down. To pass them down to children, you must use an MDXProvider (https://mdxjs.com/docs/using-mdx/#mdx-provider). The MDXProvider seems to work according to my expectation, merging components on each level, where you introduce a new provider.

I am not sure how to integrate that into our code, my idea is:

if moduleExports includes 'components' then
  export MDXProvider with components as Content
else
  export MDXContent directly as Content
end-if

I would be glad, if one of the maintainers can give me a hand to create this PR.

bholmesdev commented 1 year ago

Discussed! We decided this behavior is consistent with the MDX docs, but our documentation is unclear. Making a docs PR for now with an MDXProvider investigation planned.

bholmesdev commented 1 year ago

Update: with the docs PR merged, this should be good to close! Still have the MDXProvider discussion noted though. Will follow up in the coming month or 2 as we gear up for Astro 2.0 👍

jcayzac commented 1 month ago

@bholmesdev I think the issue still exists: MDX rendered using <Content /> are covered, but it's still impossible to pass components to MDX pages that specify a layout: property in their frontmatter, except for manually copy-pasting the code below into each page:

import X from 'path/to/my/mdx/components'
export const components = { ...X }