diff options
author | 2022-12-05 21:56:43 +0100 | |
---|---|---|
committer | 2022-12-05 21:56:43 +0100 | |
commit | efc4363e0baf7f92900e20af339811bb3df42b0e (patch) | |
tree | 49a5d2e44c2de0578dc6c28a890f74c1b16e5ec6 /packages/integrations/mdx/src | |
parent | c1a944d55ae3b93282e13c9f39182774bbc3b679 (diff) | |
download | astro-efc4363e0baf7f92900e20af339811bb3df42b0e.tar.gz astro-efc4363e0baf7f92900e20af339811bb3df42b0e.tar.zst astro-efc4363e0baf7f92900e20af339811bb3df42b0e.zip |
Support rendering `<Fragment>` in MDX `<Content />` component (#5522)
Diffstat (limited to 'packages/integrations/mdx/src')
-rw-r--r-- | packages/integrations/mdx/src/index.ts | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/packages/integrations/mdx/src/index.ts b/packages/integrations/mdx/src/index.ts index e7a896d18..20a6bee82 100644 --- a/packages/integrations/mdx/src/index.ts +++ b/packages/integrations/mdx/src/index.ts @@ -132,11 +132,18 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration { transform(code, id) { if (!id.endsWith('.mdx')) return; - // Ensures styles and scripts are injected into a `<head>` - // When a layout is not applied - code += `\nMDXContent[Symbol.for('astro.needsHeadRendering')] = !Boolean(frontmatter.layout);`; - - const [, moduleExports] = parseESM(code); + const [moduleImports, moduleExports] = parseESM(code); + + // Fragment import should already be injected, but check just to be safe. + const importsFromJSXRuntime = moduleImports + .filter(({ n }) => n === 'astro/jsx-runtime') + .map(({ ss, se }) => code.substring(ss, se)); + const hasFragmentImport = importsFromJSXRuntime.some((statement) => + /[\s,{](Fragment,|Fragment\s*})/.test(statement) + ); + if (!hasFragmentImport) { + code = 'import { Fragment } from "astro/jsx-runtime"\n' + code; + } const { fileUrl, fileId } = getFileInfo(id, config); if (!moduleExports.includes('url')) { @@ -156,9 +163,19 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration { )}) };`; } if (!moduleExports.includes('Content')) { - code += `\nexport const Content = MDXContent;`; + // Make `Content` the default export so we can wrap `MDXContent` and pass in `Fragment` + code = code.replace('export default MDXContent;', ''); + code += `\nexport const Content = (props = {}) => MDXContent({ + ...props, + components: { Fragment, ...props.components }, + }); + export default Content;`; } + // Ensures styles and scripts are injected into a `<head>` + // When a layout is not applied + code += `\nContent[Symbol.for('astro.needsHeadRendering')] = !Boolean(frontmatter.layout);`; + if (command === 'dev') { // TODO: decline HMR updates until we have a stable approach code += `\nif (import.meta.hot) { |