{"record":{"id":"936ca4af452b5bf9","repo":"withastro/astro","slug":"could-not-render-node-name-no-matching-impor","errorCode":null,"errorMessage":"Could not render `${node.name}`. No matching import has been found for `${node.name}`.","messagePattern":"Could not render `(.+?)`\\. No matching import has been found for `(.+?)`\\.","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/integrations/mdx/src/rehype-analyze-astro-metadata.ts","lineNumber":49,"sourceCode":"\t\tconst imports = parseImports(tree.children);\n\n\t\tvisit(tree, (node) => {\n\t\t\tif (node.type !== 'mdxJsxFlowElement' && node.type !== 'mdxJsxTextElement') return;\n\n\t\t\tconst tagName = node.name;\n\t\t\tif (\n\t\t\t\t!tagName ||\n\t\t\t\t!isComponent(tagName) ||\n\t\t\t\t!(hasClientDirective(node) || hasServerDeferDirective(node))\n\t\t\t)\n\t\t\t\treturn;\n\n\t\t\t// From this point onwards, `node` is confirmed to be an island component\n\n\t\t\t// Match this component with its import source\n\t\t\tconst matchedImport = findMatchingImport(tagName, imports);\n\t\t\tif (!matchedImport) {\n\t\t\t\tthrow new AstroError(\n\t\t\t\t\tAstroErrorData.NoMatchingImport.message(node.name!),\n\t\t\t\t\tAstroErrorData.NoMatchingImport.hint,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// If this is an Astro component, that means the `client:` directive is misused as it doesn't\n\t\t\t// work on Astro components as it's server-side only. Warn the user about this.\n\t\t\tif (matchedImport.path.endsWith('.astro')) {\n\t\t\t\tconst clientAttribute = node.attributes.find(\n\t\t\t\t\t(attr) => attr.type === 'mdxJsxAttribute' && attr.name.startsWith('client:'),\n\t\t\t\t) as MdxJsxAttribute | undefined;\n\t\t\t\tif (clientAttribute) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`You are attempting to render <${node.name!} ${\n\t\t\t\t\t\t\tclientAttribute.name\n\t\t\t\t\t\t} />, but ${node.name!} is an Astro component. Astro components do not render in the client and should not have a hydration directive. Please use a framework component for client rendering.`,\n\t\t\t\t\t);\n\t\t\t\t}","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/integrations/mdx/src/rehype-analyze-astro-metadata.ts#L31-L67","documentation":"In MDX, hydration directives like `client:load` require the compiler to pair the JSX element with a concrete import so the island's chunk can be built. The rehype-analyze-astro-metadata pass inspects every component element carrying `client:` (or `server:defer`) and looks up `findMatchingImport`; with no import matching the tag name, it throws the core NoMatchingImport AstroError.","triggerScenarios":"Writing `<Counter client:load />` in an .mdx file without a corresponding `import Counter from '../components/Counter'`, or with a mismatched imported name.","commonSituations":"Copy-pasting Astro examples into MDX where the import line was omitted; assuming globally registered components work in MDX; shadowing/renaming imports so the tag no longer matches the specifier.","solutions":["Add an explicit ES import for the component at the top of the .mdx file.","Make the imported name match the JSX tag exactly (default import name = tag name).","Remove the `client:` directive if the element is a plain HTML tag, not a component.","Remember Astro components themselves cannot hydrate — if the import resolves to a .astro file you'll get the separate misuse warning; use a framework component for islands."],"exampleFix":"import Counter from '../components/Counter';\n\n<Counter client:load />","handlingStrategy":"validation","validationCode":"// CI check: MDX files using client:* components must import them\nimport { globSync } from 'glob';\nimport fs from 'node:fs';\nconst importRe = /import\\s+([A-Za-z_$][\\w$]*)\\s+from\\s+['\"][^'\"]+['\"]/g;\nconst tagRe = /<([A-Z][\\w.]*)[^>]*\\sclient:[a-z]+/g;\nfor (const f of globSync('src/**/*.mdx')) {\n  const src = fs.readFileSync(f, 'utf8');\n  const imported = new Set([...src.matchAll(importRe)].map((m) => m[1]));\n  for (const m of src.matchAll(tagRe)) {\n    if (!imported.has(m[1])) throw new Error(`${f}: <${m[1]} client:*> used without a matching import`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Every component used with client: in MDX gets an explicit import in the same file.","Keep import names identical to JSX tag names to survive the matcher.","Add the import-lint to CI; eslint-plugin-mdx with react-refresh rules also catches unused/missing pairs."],"tags":["mdx","islands","client-directive","imports","hydration"],"backgroundTag":"mdx-missing-import","analyzedSha":"52e6c34790cc8ac4e69e6135ace06049867e5c4a","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}