withastro/astro · warning

More than one JSX renderer is enabled. This will lead to une

Error message

More than one JSX renderer is enabled. This will lead to unexpected behavior unless you set the `include` or `exclude` option. See https://docs.astro.build/en/guides/integrations-guide/solid-js/#combining-multiple-jsx-frameworks for more information.

What it means

When the Vue integration is configured with `jsx: true`, Vue itself becomes a JSX renderer competing with other JSX-based renderers. In its `astro:config:done` hook (packages/integrations/vue/src/index.ts:220) it checks `config.integrations` for more than one of @astrojs/react, @astrojs/preact, @astrojs/solid-js; if two or more are present and you passed neither `include` nor `exclude` to the Vue integration, it warns that JSX files may be compiled by the wrong framework. Without include/exclude globs, every `.jsx/.tsx` file goes through whichever renderer Vite resolves first, so a Solid page can silently render with React's `createElement` (or vice versa), producing broken hydration or runtime errors.

Source

Thrown at packages/integrations/vue/src/index.ts:220

		hooks: {
			'astro:config:setup': async ({ addRenderer, updateConfig, command }) => {
				addRenderer(getContainerRendererImpl());
				if (options?.jsx) {
					addRenderer(getJsxRenderer());
				}
				updateConfig({ vite: await getViteConfiguration(command, options) });
			},
			'astro:config:done': ({ logger, config }) => {
				if (!options?.jsx) return;

				const knownJsxRenderers = ['@astrojs/react', '@astrojs/preact', '@astrojs/solid-js'];
				const enabledKnownJsxRenderers = config.integrations.filter((renderer) =>
					knownJsxRenderers.includes(renderer.name),
				);

				// This error can only be thrown from here since Vue is an optional JSX renderer
				if (enabledKnownJsxRenderers.length > 1 && !options?.include && !options?.exclude) {
					logger.warn(
						'More than one JSX renderer is enabled. This will lead to unexpected behavior unless you set the `include` or `exclude` option. See https://docs.astro.build/en/guides/integrations-guide/solid-js/#combining-multiple-jsx-frameworks for more information.',
					);
				}
			},
		},
	};
}

View on GitHub (pinned to 52e6c34790)

Solutions

  1. Scope the Vue JSX rendering with include/exclude globs so each JSX variant only compiles its own files, e.g. `vue({ jsx: true, include: ['**/*.vue', '**/*.jsx'] })` combined with equivalent `include` on the other renderers.
  2. If you no longer need one of the JSX frameworks, remove its integration from `astro.config` and uninstall the package — the conflict disappears.
  3. Use file extensions or directory conventions to partition frameworks (e.g. `.tsx` for React under `src/react/`, `.jsx` for Vue under `src/vue/`) and reflect them in each renderer's include/exclude, per the linked solid-js guide.

Example fix

// before
import vue from '@astrojs/vue';
import react from '@astrojs/react';
import solid from '@astrojs/solid-js';

export default defineConfig({
  integrations: [vue({ jsx: true }), react(), solid()],
});

// after
export default defineConfig({
  integrations: [
    vue({ jsx: true, include: ['**/*.vue', '**/vue/**/*.jsx'] }),
    react({ include: ['**/*.tsx', '**/react/**'] }),
    solid({ include: ['**/solid/**'] }),
  ],
});
Defensive patterns

Strategy: validation

Validate before calling

// sanity-check the resolved Astro config before building
// (run via `astro config`-style inspection or by loading the config with the Astro CLI)
const jsxRenderers = config.integrations
  .map((i) => i.name)
  .filter((n) => ['@astrojs/react', '@astrojs/preact', '@astrojs/solid-js'].includes(n));
const vueOptionsIncludeExclude = /* your vue() include/exclude options */;
if (jsxRenderers.length > 1 && !vueOptionsIncludeExclude) {
  throw new Error('Set include/exclude on vue({ jsx: true }) — multiple JSX renderers enabled');
}

Prevention

When it happens

Trigger: `astro.config.mjs` has `vue({ jsx: true })` (or the JSX option enabled) AND at least two of @astrojs/react, @astrojs/preact, @astrojs/solid-js are in `integrations`, AND the Vue integration options contain neither `include` nor `exclude`. The check runs once during `astro dev`/`astro build` startup in `astro:config:done`. Note Vue is special-cased as the only place this can warn, because it is an optional JSX renderer; if only one other JSX renderer is enabled, no warning fires.

Common situations: A mixed-framework design-system or migration repo (e.g. incrementally moving React pages to Solid while both integrations stay installed) that also adds Vue with JSX support; monorepos where a shared config file lists many integrations; adding a new JSX framework dependency for one component without removing the old integration from the config.

Related errors


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