withastro / astro

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

Error when using client directives on component passed to MDX "components" prop #5853

Closed plmrry closed 1 year ago

plmrry commented 1 year ago

What version of astro are you using?

1.9.2

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

No

What package manager are you using?

npm

What operating system are you using?

StackBlitz

Describe the Bug

When using MDX, you can pass in custom components:

pages/index.astro:

---
import { Content } from '../data/index.mdx';
import Thing1 from '../components/Thing1.astro';
import Thing2 from '../components/Thing2.svelte';
import Thing3 from '../components/Thing3.astro';
---

<Content components={{ Thing1, Thing2, Thing3 }} />

This lets you use components in the MDX file without importing them:

data/index.mdx:

<main>
  Rendering Thing1:
  <Thing1 />
  Rendering Thing2:
  <Thing2 />
  Rendering Thing3:
  <Thing3 />
</main>

However, this breaks when you use a client directive:

data/index.mdx:

<main>
  <Thing2 client:load />
</main>

Here's the error:

NoMatchingImport: Could not render `Thing2`. No matching import has been found for `Thing2`.
    at PluginPass.JSXIdentifier (file://file:///home/projects/github-4i3mtk/node_modules/astro/dist/jsx/babel.js:305:17)
    at newFn (file:///home/projects/github-4i3mtk/node_modules/@babel/traverse/lib/visitors.js:143:21)
    at NodePath._call (file:///home/projects/github-4i3mtk/node_modules/@babel/traverse/lib/path/context.js:45:20)
    at NodePath.call (file:///home/projects/github-4i3mtk/node_modules/@babel/traverse/lib/path/context.js:35:17)
    at NodePath.visit (file:///home/projects/github-4i3mtk/node_modules/@babel/traverse/lib/path/context.js:80:31)
    at TraversalContext.visitQueue (file:///home/projects/github-4i3mtk/node_modules/@babel/traverse/lib/context.js:86:16)
    at TraversalContext.visitSingle (file:///home/projects/github-4i3mtk/node_modules/@babel/traverse/lib/context.js:65:19)
    at TraversalContext.visit (file:///home/projects/github-4i3mtk/node_modules/@babel/traverse/lib/context.js:109:19)
(the stack trace continues; it is quite long)

Note that if you use an Astro component in MDX, and within that component you use client:load, it works fine.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-4i3mtk?file=src/data/index.mdx

Participation

matthewp commented 1 year ago

This also doesn't work if you pass components to child Astro components. The client: directives only work with direct imports. This is because Astro needs to track which components are being used in the client so that it can build them all out properly.

If you import these components directly into your MDX, the client: directives should work.

plmrry commented 1 year ago

The client: directives only work with direct imports.

@matthewp is this documented anywhere? I'd be interested in making a docs PR if it isn't.