vite-plugin-virtual-mpa

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

Vite plugin for building multi-page applications (MPA) with virtual file support and EJS templating. Current stable version 1.12.1, active development with regular minor/patch releases. Key differentiators: provides out-of-box MPA support without boilerplate, uses virtual HTML files (no physical templates needed), offers EJS template rendering, TypeScript types included, supports scan-based page auto-generation, and includes history fallback for dev/preview servers. Compatible with Vite >=2.0.0.

error Error: [vite-plugin-virtual-mpa] Failed to compile EJS template: Could not find matching close tag for "<% %>"
cause EJS syntax error in a template file (e.g., unclosed tag).
fix
Fix EJS syntax (e.g., close all <% %> tags). Check for missing closing '%>'. The plugin stops dev server on EJS error in recent versions.
error TypeError: createMpaPlugin is not a function
cause CommonJS require() used instead of ESM import.
fix
Replace const { createMpaPlugin } = require(...) with import { createMpaPlugin } from 'vite-plugin-virtual-mpa'.
error [plugin:vite-plugin-virtual-mpa] Cannot find module 'src/pages/.../main.ts'
cause Entry file specified in page config does not exist at the given path.
fix
Check the 'entry' path relative to project root. Ensure the file exists.
error Error: Page name must not contain '/'
cause Page 'name' contains a slash character.
fix
Remove slashes from page name; use only alphanumerics, hyphens, underscores.
breaking v1.0.0 removed support for CommonJS require; ESM import is required.
fix Use import instead of require().
gotcha page 'name' must not contain '/' characters; it is used for default redirect rules.
fix Use only alphanumeric characters, hyphens, or underscores for page names.
deprecated The 'pages' option was previously required to be passed directly; now can be built via createPages or scanOptions.
fix Use the modern API: createPages([]) or scanOptions.
gotcha When using scanOptions, scanned pages with same name as explicit pages will be ignored.
fix Ensure explicit page names are unique to avoid unexpected overrides.
breaking Vite 2 used a different transformIndexHtml API; plugin is designed for Vite >=2, but behavior may differ.
fix Use Vite >=3 for full compatibility; the plugin is tested with Vite 4 and 5.
npm install vite-plugin-virtual-mpa
yarn add vite-plugin-virtual-mpa
pnpm add vite-plugin-virtual-mpa

Minimal MPA setup with two pages (index, about) using EJS template and custom rewrite rule.

// vite.config.ts
import { defineConfig } from 'vite';
import { createMpaPlugin, createPages } from 'vite-plugin-virtual-mpa';

const pages = createPages([
  {
    name: 'index',
    filename: 'index.html',
    entry: 'src/pages/index/main.ts',
  },
  {
    name: 'about',
    filename: 'about.html',
    entry: 'src/pages/about/main.ts',
    template: 'src/pages/about/template.html', // custom EJS template
  },
]);

export default defineConfig({
  plugins: [
    createMpaPlugin({
      pages,
      verbose: true,
      rewrites: [
        { from: '/about', to: '/about.html' },
      ],
      transformHtml: (html, { page }) => {
        // inject page-specific meta tags
        return html.replace('</head>', `<meta name="page" content="${page.name}"></head>`);
      },
    }),
  ],
});