withastro/astro · warning

[@astrojs/vue] appEntrypoint `${appEntrypoint}` does not exp

Error message

[@astrojs/vue] appEntrypoint `${appEntrypoint}` does not export a default function. Check out https://docs.astro.build/en/guides/integrations-guide/vue/#appentrypoint.

What it means

When you configure the Vue integration with `appEntrypoint` (e.g. `vue({ appEntrypoint: '/src/app.ts' })`), the integration generates a virtual module whose `setup(app)` dynamically imports your entry and calls its default export (packages/integrations/vue/src/index.ts:69-85). If the module has no `default` export, the generated code logs this console.warn — but only when `!isBuild`, i.e. in `astro dev`/`astro preview`; production builds compile the branch out entirely. Consequence: your Vue app instance never receives the setup call (plugins, global components, directives from that file are never installed), and in production it fails silently — so treat the dev warning as a real bug, not noise.

Source

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

				return RESOLVED_VIRTUAL_MODULE_ID;
			},
		},
		load: {
			filter: {
				id: new RegExp(`^${RESOLVED_VIRTUAL_MODULE_ID}$`),
			},
			handler() {
				if (appEntrypoint) {
					return `\
export const setup = async (app) => {
	const mod = await import(${JSON.stringify(appEntrypoint)});

	if ('default' in mod) {
		await mod.default(app);
	} else {
		${
			!isBuild
				? `console.warn("[@astrojs/vue] appEntrypoint \`" + ${JSON.stringify(
						appEntrypoint,
					)} + "\` does not export a default function. Check out https://docs.astro.build/en/guides/integrations-guide/vue/#appentrypoint.");`
				: ''
		}
	}
}`;
				}
				return `export const setup = () => {};`;
			},
		},
		// Ensure that Vue components reference appEntrypoint directly
		// This allows Astro to associate global styles imported in this file
		// with the pages they should be injected to
		transform: {
			filter: {
				id: /\.vue$/,
			},
			handler(code) {

View on GitHub (pinned to 52e6c34790)

Solutions

  1. Add a default export that accepts the Vue app and performs the setup: `export default function (app) { app.use(router); app.component(...); }`.
  2. Verify you're pointing `appEntrypoint` at the intended file (absolute path from project root, e.g. '/src/app.ts') — a typo can resolve to a helper module with no default export.
  3. If the entry legitimately has no setup to run, remove the `appEntrypoint` option entirely so the integration uses the no-op `setup = () => {}` path instead of warning.
  4. Confirm global plugins/components render in both dev and a production build, since production silently skips the missing default.

Example fix

// before: src/app.ts
import { myPlugin } from './plugin';
export function setupApp(app) {
  app.use(myPlugin);
}

// after: src/app.ts
import { myPlugin } from './plugin';
export default function setupApp(app) {
  app.use(myPlugin);
}
Defensive patterns

Strategy: validation

Validate before calling

// verify the appEntrypoint module exposes a default export function before wiring it
const spec = '/src/app.ts'; // must match the vue({ appEntrypoint }) option
const mod = await import(spec);
if (typeof mod.default !== 'function') {
  throw new Error(`${spec} must export a default function (app) => void`);
}

Type guard

// narrows a dynamic import result to a usable Vue app entry
type VueAppEntry = { default: (app: unknown) => void | Promise<void> };
const isVueAppEntry = (m: unknown): m is VueAppEntry =>
  typeof m === 'object' && m !== null && typeof (m as { default?: unknown }).default === 'function';

Prevention

When it happens

Trigger: Configuring `appEntrypoint` in the Vue integration options while the target module exports only named exports (e.g. `export function setupApp()` or `export const plugins = [...]`) instead of `export default`. Opening any page in `astro dev` that instantiates the Vue app triggers the warn from the generated virtual module.

Common situations: Following the appEntrypoint guide but writing `export function ...` out of habit or per an older example; refactoring the entry file and dropping the `default` keyword; TypeScript files where `export default defineApp(...)` was changed to a named export during a lint autofix or codemod; splitting the entry into multiple files so the imported module no longer has a default.

Related errors


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