vite-preload

raw JSON →
1.0.5 verified Mon Apr 27 auth: no javascript

Vite plugin (v1.0.6) that preloads server-rendered lazy React components and their CSS to eliminate FOUC and reduce load times. Unlike vite-plugin-preload, it evaluates used modules at render time (not build time). Supports Vite 5-8 and React 18-19. Ships TypeScript types, offers lazy() wrapper and preloadAll() for server-side resolution. Compatible with 103 Early Hints via getLinkHeaders(). Active development with frequent releases.

error Error: The 'vite-preload' plugin is not found or not configured correctly.
cause Importing preloadPlugin from wrong path (e.g., import { preloadPlugin } from 'vite-preload').
fix
Use default import from 'vite-preload/plugin': import preloadPlugin from 'vite-preload/plugin'.
error TypeError: Cannot read properties of undefined (reading 'getLinkHeaders')
cause createChunkCollector returned undefined because manifest path is incorrect or file not found.
fix
Ensure manifest path points to valid file (e.g., './dist/client/.vite/manifest.json') and file exists.
error [vite-preload] Chunk not found in manifest: ...
cause A lazy-loaded module's chunk is missing from the manifest; possibly due to Rollup chunk merging.
fix
Remove build.rollupOptions.output.experimentalMinChunkSize or set to 0.
error Error: React.lazy is not supported without the 'lazy' wrapper from vite-preload
cause Using React.lazy directly instead of the wrapper from 'vite-preload' which collects chunks.
fix
Replace React.lazy with import { lazy } from 'vite-preload'.
gotcha Preloading does not work in development mode (vite dev). CSS is injected via inline style tags causing FOUC.
fix Only rely on preloading for production builds; test CSS appearance separately in dev.
gotcha If modules are not preloaded, check that build.rollupOptions.output.experimentalMinChunkSize is not set, as Rollup may merge chunks and break manifest mapping.
fix Remove experimentalMinChunkSize or set it to 0.
breaking CJS require() may fail in some environments. Package is ESM-only.
fix Use import syntax or enable ESM in Node.js ("type": "module" in package.json).
deprecated React 17 is not supported as a peer dependency; only React 18 and 19 are allowed.
fix Upgrade React to version 18 or later.
gotcha The 'asyncScript' option generates async entry module; React hydration must wait for DOMContentLoaded.
fix Ensure you do not hydrate or render React before DOMContentLoaded if using asyncScript.
breaking The plugin import path changed: import from 'vite-preload/plugin', not 'vite-preload'.
fix Use import preloadPlugin from 'vite-preload/plugin'.
npm install vite-preload
yarn add vite-preload
pnpm add vite-preload

Shows Vite plugin setup, server-side chunk collector initialization, Early Hints, and link tag injection.

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import preloadPlugin from 'vite-preload/plugin';

export default defineConfig({
  plugins: [
    preloadPlugin(),
    react()
  ]
});

// server/entry.server.tsx (simplified)
import { ChunkCollectorContext, createChunkCollector, preloadAll } from 'vite-preload';
import React from 'react';
import { renderToPipeableNodeStream } from 'react-dom/server';

// On server startup:
await preloadAll();

// In request handler:
const collector = createChunkCollector({
  manifest: './dist/client/.vite/manifest.json',
  entry: 'index.html'
});

// Early Hints
res.writeEarlyHints({ link: collector.getLinkHeaders() });

const { pipe } = renderToPipeableNodeStream(
  <ChunkCollectorContext.Provider value={collector}>
    <App />
  </ChunkCollectorContext.Provider>
);

// After rendering, inject <link> tags into HTML head
const linkTags = collector.getLinkTags();
const html = template.replace('</head>', `${linkTags}</head>`);
res.write(html);