@ulu/vite-plugin-eleventy
v0.0.1
Published
Integrates Eleventy into Vite, providing HMR for development and automatic asset hashing for production builds.
Maintainers
Readme
@ulu/vite-plugin-eleventy
Integrates Eleventy with Vite for development and production workflows.
Overview
This plugin manages the Eleventy lifecycle within Vite:
- Development: Runs Eleventy in watch mode and serves the output via Vite middleware.
- Production: Orchestrates the Eleventy build after Vite assets are bundled.
- Assets: Provides helpers to link to Vite-managed assets, handling hashing (production) and source paths (development).
Features
- Zero Config Injection: Injects necessary configuration into Eleventy via the Programmatic API.
- Dev Server: Serves Eleventy output from a hidden cache directory.
- Reloads: Triggers Vite full-page reloads on HTML changes.
- Asset Helpers: Shortcodes/Filters for
scriptandlinktags that respect the Vite manifest.
Installation
npm install @ulu/vite-plugin-eleventy --save-devUsage
1. Configure Vite
Add the plugin to your vite.config.js:
// vite.config.js
import { defineConfig } from "vite";
import eleventyPlugin from "@ulu/vite-plugin-eleventy";
export default defineConfig({
plugins: [
eleventyPlugin({
// Path to your Eleventy config file
configPath: "./eleventy.config.js",
// Optional: Override the base URL for generated asset links.
// Defaults to Vite's 'base' config.
// Example: Set to "/" to force root-relative paths if Vite base is "./"
// publicPath: "/"
})
],
build: {
outDir: "dist", // Vite builds assets here (standard)
manifest: true, // Required for production asset hashing
rollupOptions: {
input: "src/main.js" // Your entry point
}
}
});2. Configure Eleventy
You do not need to manually add a plugin in your eleventy.config.js. The Vite plugin injects itself automatically.
⚠️ IMPORTANT WARNING
Ensure your
eleventy.config.jsdoes NOT hardcode adir.outputdirectory. The plugin must control the output directory:
- Development: It needs to write to a hidden cache directory.
- Production: It needs to write to the Vite build directory.
If you hardcode
output: "dist", the dev server will not find your files!
// eleventy.config.js
module.exports = function(eleventyConfig) {
// ... your config
return {
dir: {
input: "src",
// DO NOT set output here!
// output: "dist"
}
};
};3. Use in Templates
Use the provided Shortcodes and Filters to reference your assets. They automatically switch between local paths (Dev) and hashed paths (Prod).
Scripts:
<!-- Output <script type="module" src="..."> -->
{{ viteEntry("site/src/main.js") | safe }}Styles (CSS):
<!-- In <head>: Output <link rel="stylesheet"> for any CSS associated with the entry -->
<!-- Note: In Dev, Vite injects CSS via JS, so this outputs nothing. -->
{{ viteEntryStyles("site/src/main.js") | safe }}Raw URL (Advanced):
<!-- Get just the URL string -->
<link rel="preload" href="{{ 'src/main.js' | viteEntryUrl }}" as="script">Configuration Options
The plugin accepts the following options:
| Option | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| configPath | String | "eleventy.config.js" | Path to your Eleventy configuration file (relative to project root). |
| outDir | String | viteConfig.build.outDir | The directory where Eleventy should write its output in Production. Usually defaults to Vite's output directory. |
| cacheDir | String | node_modules/.@ulu-cache-vite-plugin-eleventy | The directory where Eleventy writes output in Development. Hidden by default. |
| publicPath | String | viteConfig.base | The URL prefix for assets (e.g. / or /assets/). Used to construct absolute URLs for {% viteEntry %}. Defaults to Vite's base config. |
| debug | Boolean | false | Enable verbose logging. |
How it Works
Development (
vite dev):- Starts Eleventy in
watchmode. - Writes HTML to a hidden cache directory.
- Vite Middleware intercepts requests and serves HTML from the cache.
{% viteEntry %}outputs paths to source files (e.g.,/src/main.js), allowing Vite to handle HMR.
- Starts Eleventy in
Production (
vite build):- Vite builds your assets (JS/CSS) first.
- Plugin waits for
closeBundlehook. - Plugin runs Eleventy build.
{% viteEntry %}readsmanifest.jsongenerated by Vite and outputs hashed paths (e.g.,/assets/main.a8b3f.js).
