withastro/astro · warning

[@astrojs/preact] Importing `getContainerRenderer` from `@as

Error message

[@astrojs/preact] Importing `getContainerRenderer` from `@astrojs/preact` is deprecated. Import it from `@astrojs/preact/container-renderer` instead.

What it means

@astrojs/preact kept a getContainerRenderer() re-export on its package root for backward compatibility, but container rendering APIs now live in the subpath export. Calling the root-level shim prints this console.warn and forwards to the real implementation from ./container-renderer.js, so output is correct but the import is scheduled for removal.

Source

Thrown at packages/integrations/preact/src/index.ts:18

import { fileURLToPath } from 'node:url';
import { preact, type PreactPluginOptions as VitePreactPluginOptions } from '@preact/preset-vite';
import type { AstroIntegration, AstroRenderer, ViteUserConfig } from 'astro';
import * as devalue from 'devalue';
import type { EnvironmentOptions, Plugin } from 'vite';
import {
	getContainerRenderer as getContainerRendererImpl,
	getRenderer,
} from './container-renderer.js';
import type { VirtualModuleOptions } from './types.js';

const babelCwd = new URL('../', import.meta.url);

/**
 * @deprecated Import `getContainerRenderer` from `@astrojs/preact/container-renderer` instead.
 */
export function getContainerRenderer(): AstroRenderer {
	console.warn(
		'[@astrojs/preact] Importing `getContainerRenderer` from `@astrojs/preact` is deprecated. Import it from `@astrojs/preact/container-renderer` instead.',
	);
	return getContainerRendererImpl();
}

function optionsPlugin(include: Options['include'], exclude: Options['exclude']): Plugin {
	const virtualModule = 'astro:preact:opts';
	const virtualModuleId = '\0' + virtualModule;
	return {
		name: '@astrojs/preact:opts',
		resolveId: {
			filter: {
				id: new RegExp(`^${virtualModule}$`),
			},
			handler() {
				return virtualModuleId;
			},
		},

View on GitHub (pinned to 52e6c34790)

Solutions

  1. Change the import specifier: import { getContainerRenderer } from '@astrojs/preact/container-renderer';
  2. Update TypeScript moduleResolution settings if the subpath types are not found (bundler/node16 resolution recommended).
  3. Re-run the container render; the warning should disappear while output stays identical.

Example fix

// before
import { getContainerRenderer } from '@astrojs/preact';
const Container = await experimental_AstroContainer.create();
Container.addRenderer({ name: 'preact', serverEntrypoint: await getContainerRenderer() });

// after
import { getContainerRenderer } from '@astrojs/preact/container-renderer';
const Container = await experimental_AstroContainer.create();
Container.addRenderer({ name: 'preact', serverEntrypoint: await getContainerRenderer() });
Defensive patterns

Strategy: validation

Validate before calling

// CI guard: reject root-level getContainerRenderer imports
const files = await glob('server/**/*.ts');
for (const f of files) {
  const src = await readFile(f, 'utf8');
  if (/from ['"]@astrojs\/preact['"].*getContainerRenderer|getContainerRenderer.*from ['"]@astrojs\/preact['"]/s.test(src)) {
    throw new Error(`${f}: import getContainerRenderer from '@astrojs/preact/container-renderer'`);
  }
}

Prevention

When it happens

Trigger: Code calls getContainerRenderer imported from '@astrojs/preact' (root), typically in a custom Express/Hono/Nest SSR entry: import { getContainerRenderer } from '@astrojs/preact'; followed by renderToStreamingMarkup / experimental_AstroContainer usage.

Common situations: Upgrading @astrojs/preact to a version that moved container APIs to @astrojs/preact/container-renderer while keeping old manual-SSR code; copying older container-rendering examples from the Astro docs or blog posts.

Related errors


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