vite-multi-page-html-generator-plugin
v2.0.1
Published
Vite plugin for automatic multi-page HTML entry point generation with configurable options
Maintainers
Readme
📄 Vite Multi-Page HTML Generator Plugin
Production-ready Vite plugin for automatic multi-page static site generation with zero configuration
The Problem: Vite works with a single HTML file by default. For multi-page sites, you must manually configure every page in rollupOptions.input.
The Solution: This plugin automatically discovers all HTML files in your project and configures entry points for you. Add a new page → it's automatically included in the build. Zero manual configuration.
Features
- Zero config - Works out of the box
- Auto-discovery - Finds all HTML files automatically
- Security - Path traversal protection (v2.0+)
- Performance - Async operations, non-blocking
- TypeScript - Full type definitions included
- Safe merging - Preserves existing Rollup config
- Framework agnostic - Works with vanilla JS or any Vite project
- SVG integration - Works with vite-svg-sprite-generator-plugin
Installation
npm install -D vite-multi-page-html-generator-pluginQuick Start
1. Configure Vite
// vite.config.js
import { defineConfig } from 'vite';
import multiPagePlugin from 'vite-multi-page-html-generator-plugin';
export default defineConfig({
plugins: [multiPagePlugin()]
});2. Create Your Pages
project/
├── index.html ← Home page
├── about.html ← About page
├── contact.html ← Contact page
├── src/
│ └── main.js
└── vite.config.js3. Build
npm run buildOutput:
dist/
├── index.html
├── about.html
├── contact.html
└── assets/
├── main-[hash].js
└── styles-[hash].cssConfiguration
interface MultiPageOptions {
htmlRoot?: string; // Default: project root
exclude?: (string | RegExp)[]; // Default: []
entryNameFormatter?: (name, file) => string // Default: undefined
}Basic Example
multiPagePlugin({
htmlRoot: 'src/pages',
exclude: ['template.html', /test/i]
})Advanced Example
multiPagePlugin({
htmlRoot: 'src/pages',
exclude: [
'template.html', // Exclude template files
/^_/, // Exclude files starting with _
/\.draft\.html$/ // Exclude draft files
],
entryNameFormatter: (name, file) => {
// Custom entry point naming
return `page-${name}`;
}
})How It Works
The plugin automatically discovers HTML files and configures Vite's build:
Before (manual):
export default defineConfig({
build: {
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
about: resolve(__dirname, 'about.html'),
contact: resolve(__dirname, 'contact.html')
}
}
}
});After (automatic):
export default defineConfig({
plugins: [multiPagePlugin()]
// Entry points auto-configured! ✨
});Build Process
- Discovery - Scans
htmlRootfor.htmlfiles - Filtering - Applies
excludepatterns - Entry Points - Creates Rollup input config
- Merging - Safely merges with existing config
- Build - Vite builds all pages
Key Features
Auto-Discovery
// No configuration needed!
multiPagePlugin()
// Finds all HTML files automatically:
// ✅ index.html
// ✅ about.html
// ✅ contact.htmlFlexible Exclusion
multiPagePlugin({
exclude: [
'template.html', // String match
/test/i, // RegExp pattern
/^draft-/ // Files starting with "draft-"
]
})Security (v2.0+)
Automatic protection against path traversal attacks:
// ❌ Blocked - outside project
multiPagePlugin({
htmlRoot: '../../../etc'
})
// Error: Security: htmlRoot is outside project root
// ✅ Safe - inside project
multiPagePlugin({
htmlRoot: 'src/pages'
})Safe Configuration
Preserves your existing Rollup config:
export default defineConfig({
build: {
rollupOptions: {
input: {
custom: 'custom-entry.html'
},
output: {
manualChunks: {...}
}
}
},
plugins: [
multiPagePlugin() // Merges, doesn't overwrite
]
});
// Result: custom + auto-discovered entries ✅Integration
With SVG Sprite Plugin
Perfect combination for static multi-page sites:
// vite.config.js
import { defineConfig } from 'vite';
import multiPagePlugin from 'vite-multi-page-html-generator-plugin';
import svgSpritePlugin from 'vite-svg-sprite-generator-plugin';
export default defineConfig({
plugins: [
multiPagePlugin({
htmlRoot: 'src/pages'
}),
svgSpritePlugin({
iconsFolder: 'src/icons',
treeShaking: true // Each page gets only its icons
})
]
});Result: Full-featured static site with optimized SVG icons per page.
Use Cases
Static Multi-Page Website
project/
├── index.html # Home page
├── about.html # About
├── services.html # Services
├── contact.html # Contact
└── src/
├── main.js # Shared JavaScript
└── styles.css # Shared stylesDocumentation Site
docs/
├── index.html # Home
├── getting-started.html # Guide
├── api-reference.html # API docs
└── examples.html # ExamplesMarketing Site
site/
├── index.html # Home
├── features.html # Features
├── pricing.html # Pricing
├── about.html # About
└── contact.html # ContactAdvanced
Custom Entry Names
multiPagePlugin({
entryNameFormatter: (name, file) => {
// name: 'about', file: '/path/to/about.html'
// Add prefix
return `page-${name}`;
// Use full path as name
return file.replace(/\//g, '-');
// Custom logic
return name.startsWith('admin-')
? `admin/${name}`
: name;
}
})Conditional Pages
const isDev = process.env.NODE_ENV === 'development';
multiPagePlugin({
exclude: isDev
? [] // Show all in dev
: [/test/, /draft/] // Hide test pages in prod
})Multiple Page Directories
import { defineConfig } from 'vite';
import multiPagePlugin from 'vite-multi-page-html-generator-plugin';
export default defineConfig({
plugins: [
// Public pages
multiPagePlugin({
htmlRoot: 'src/public'
}),
// Admin pages (if needed, configure manually)
]
});Performance
Build Speed
- Async operations - Non-blocking file system access
- Efficient scanning - Single directory traversal
- Smart caching - Leverages Vite's built-in cache
Bundle Optimization
When pages share the same JavaScript:
3 pages, same JS import:
Without plugin:
- Manual config for each page
- Risk of misconfiguration
With plugin:
- Auto-configured
- Shared bundle: main-[hash].js
- No duplication ✅Compatibility
- Vite: 4.x, 5.x, 6.x, 7.x
- Node.js: 14.18.0+
- TypeScript: Full support
- OS: Windows, macOS, Linux
Migration Guide
From v1.x to v2.0
Breaking Changes:
- Path validation -
htmlRootmust be inside project - Async operations - Fully non-blocking
If using standard paths - no changes needed:
// ✅ Works the same
multiPagePlugin()
// ✅ Works the same
multiPagePlugin({
htmlRoot: 'src/pages'
})If using paths outside project - now blocked:
// ❌ v1.x - worked (vulnerability!)
multiPagePlugin({
htmlRoot: '../../../etc'
})
// ✅ v2.0 - throws error with explanation
// Error: Security: htmlRoot is outside project rootSee CHANGELOG.md for details.
Links
Related Plugins
- vite-svg-sprite-generator-plugin - SVG sprite generation with HMR
License
MIT © Karev G.S.
Made with ❤️ for the Vite ecosystem
