nitro icon indicating copy to clipboard operation
nitro copied to clipboard

[vite] globalThis.__VITE_MANIFEST__ is undefined

Open b3nten opened this issue 2 months ago • 5 comments

This value is not getting set in production on the server. The workaround is to use a plugin like:

const manifestPlugin = (): Plugin => {
	let manifest = "{}";
	const id = "#vite-manifest";
	const resolvedId = `\0${id}`;
	return {
		name: "manifest",
		applyToEnvironment(e) {
			return e.name === "nitro"
		},
config() { return { manifest: true } },
		resolveId(possibleId) {
			if (possibleId === id) {
				return resolvedId
			}
		},
		load(id) {
			if (id === resolvedId) {
				return `export default ${manifest}`
			}
		},
		async buildStart(c) {
			manifest = await fs.readFile("./.output/public/.vite/manifest.json", "utf-8");
		},
	}
}

and importing the manifest from "#vite-manifest"

b3nten avatar Oct 14 '25 09:10 b3nten

Can you please open a PR to add it?

pi0 avatar Oct 14 '25 09:10 pi0

Hey 👋, I’d like to work on this issue and open a PR to add the fix. The plugin approach shared above makes sense — I’ll integrate it properly and test it in production mode to ensure VITE_MANIFEST is correctly defined. Please assign this issue to me if possible.

deepakstwt avatar Oct 15 '25 22:10 deepakstwt

We are revising manifest injection approach (see https://github.com/hi-ogawa/vite-plugins/tree/main/packages/fullstack proposal)

pi0 avatar Oct 15 '25 22:10 pi0

I like that approach. I would say, having the ability to import the entire manifest would be nice as well, but most of the time it's just to resolve the main entry point.

There is another use case which would be less common, but it's when you want to build the server first, but still have access to the manifest at runtime. So far the only approach I can think of is to use advancedChunks in Rolldown to force the virtual manifest import into it's own file, stub it during server build, and then during client build replace it's contents with the actual manifest.

b3nten avatar Oct 16 '25 01:10 b3nten

There is another use case which would be less common, but it's when you want to build the server first, but still have access to the manifest at runtime. So far the only approach I can think of is to use advancedChunks in Rolldown to force the virtual manifest import into it's own file, stub it during server build, and then during client build replace it's contents with the actual manifest.

It doesn't necessary require manual chunking configuration for this. The technique I used in @hiogawa/vite-plugin-fullstack (and also in @vitejs/plugin-rsc) is to resolve #some-manifest as external ./__some_manifest.js during the build and then write out the content after both client and ssr build has finished.

hi-ogawa avatar Oct 16 '25 08:10 hi-ogawa