withastro/astro · warning

You are attempting to render <${node.name!} ${clientAttribut

Error message

You are attempting to render <${node.name!} ${clientAttribute.name} />, 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.

What it means

While compiling .mdx files, the rehype-analyze-astro-metadata pass resolves each JSX element to its import. When the import path ends in .astro and the element carries any mdxJsxAttribute whose name starts with client:, the compiler warns that Astro components are server-side only — a hydration directive on them cannot work and should be removed or moved to a framework component.

Source

Thrown at packages/integrations/mdx/src/rehype-analyze-astro-metadata.ts:62

			// From this point onwards, `node` is confirmed to be an island component

			// Match this component with its import source
			const matchedImport = findMatchingImport(tagName, imports);
			if (!matchedImport) {
				throw new AstroError(
					AstroErrorData.NoMatchingImport.message(node.name!),
					AstroErrorData.NoMatchingImport.hint,
				);
			}

			// If this is an Astro component, that means the `client:` directive is misused as it doesn't
			// work on Astro components as it's server-side only. Warn the user about this.
			if (matchedImport.path.endsWith('.astro')) {
				const clientAttribute = node.attributes.find(
					(attr) => attr.type === 'mdxJsxAttribute' && attr.name.startsWith('client:'),
				) as MdxJsxAttribute | undefined;
				if (clientAttribute) {
					console.warn(
						`You are attempting to render <${node.name!} ${
							clientAttribute.name
						} />, 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.`,
					);
				}
			}

			const resolvedPath = resolvePath(matchedImport.path, file.path);

			if (hasClientOnlyDirective(node)) {
				// Add this component to the metadata
				metadata.clientOnlyComponents.push({
					exportName: matchedImport.name,
					localName: '',
					specifier: tagName,
					resolvedPath,
				});
				// Mutate node with additional island attributes

View on GitHub (pinned to 52e6c34790)

Solutions

  1. Remove the client:* attribute from the .astro component usage
  2. Extract the interactive part into a framework component (React/Svelte/Vue/Solid) and place the client:* directive on that instead
  3. Reconsider whether the component needs client JS at all — most .astro components render static HTML

Example fix

# before  src/content/docs/guide.mdx
import Card from '../../components/Card.astro';
import Like from '../../components/Like.svelte';
<Card client:load title="Hello" />

# after
<Card title="Hello">
  <Like client:load />
</Card>
Defensive patterns

Strategy: type-guard

Validate before calling

# CI review aid: list every client: directive in MDX content for manual check
# against imports — flag ones whose component comes from a .astro file
grep -rn --include='*.mdx' 'client:' src/content

Type guard

const isAstroComponentFactory = (c: unknown): c is () => any =>
  typeof c === 'function' &&
  (c as { isAstroComponentFactory?: boolean }).isAstroComponentFactory === true;

// in dynamic JSX: only attach client:* when the component is NOT an Astro factory
const props = isAstroComponentFactory(Comp) ? rest : { ...rest, 'client:load': true };

Prevention

When it happens

Trigger: In an .mdx file: `import Card from './Card.astro'` followed by `<Card client:load />` (any client:* attribute). Emitted at compile time, once per offending element, via console.warn during the rehype pass.

Common situations: Docs/content sites authoring in MDX with .astro components; copy-pasting hydration directives from framework component usage; prototyping interactivity by slapping client: on whatever component is at hand.

Related errors


AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18). Data as JSON: /api/errors/5ed53972fd297adf. Report an issue: GitHub.