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

Rendering <Content /> fails for MDX file containing <Fragment> #5519

Closed
1 task
delucis opened this issue Dec 2, 2022 · 2 comments · Fixed by #5522
Closed
1 task

Rendering <Content /> fails for MDX file containing <Fragment> #5519

delucis opened this issue Dec 2, 2022 · 2 comments · Fixed by #5522

Comments

@delucis
Copy link
Member

delucis commented Dec 2, 2022

What version of astro are you using?

1.6.12

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

n/a

What package manager are you using?

npm

What operating system are you using?

macOS / Stackblitz

Describe the Bug

(Ran into this bug as part of migrating docs to MDX and it’s a bit of blocker given how much we use <Fragment> to pass content to slots.)

  1. MDX supports using <Fragment>, which can be useful for example to pass stuff to a named slot:

    <Component>
      <Fragment slot="box">Box content</Fragment>
    </Component>

    This renders fine for an MDX page, e.g. src/pages/index.mdx.

  2. If you import (or glob) the same page and use it’s <Content /> component however:

    ---
    import { Content } from './index.mdx';
    ---
    <Content />

    Astro will throw an error:

    Expected component `Fragment` to be defined: you likely forgot to import, pass, or provide it.
    

I guess somewhere <Fragment> support is being wired up when a page is rendered but that same wiring is missing for the <Content /> render.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-zq6zwz?file=src/pages/index.mdx

Participation

  • I am willing to submit a pull request for this issue.
@delucis
Copy link
Member Author

delucis commented Dec 3, 2022

Wrote some tests for this issue at https://github.com/withastro/astro/tree/issue/5519 (failing currently, but should pass once this issue is fixed).

@delucis
Copy link
Member Author

delucis commented Dec 3, 2022

Ah and here is where we fixed this previously, but I suspect only for pages not for the <Content /> component:

// HACK: expose `Fragment` for all MDX components
if (typeof mod.default === 'function' && mod.default.name.startsWith('MDX')) {
Object.assign(pageProps, {
components: Object.assign((pageProps?.components as any) ?? {}, { Fragment }),
});
}

Compiled MDX output looks like:

function _createMdxContent(props) {
  const _components = Object.assign(
      {
        h1: 'h1',
        // map of standard HTML elements used by this MDX file
      },
      props.components
    ),
    { Fragment } = _components; // <-- Look for Fragment definition in `props.components`
  if (!Fragment) _missingMdxReference('Fragment', true);

  // ... MDX contents as JSX ...
}

So Fragment needs passing in.

I tried modifying the MDX integration so that Content does this:

export const Content = (props) => MDXContent({
  ...props,
  components: {
    Fragment,
    ...props.components,
  },
});

This bypasses the _missingMdxReference error, but fragment contents still doesn’t seem to be rendered — it is rendered! I just hadn’t updated a query selector in my test. Fix in #5522 🎉

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

Successfully merging a pull request may close this issue.

1 participant