Skip to content

Instantly share code, notes, and snippets.

@stoppert
Last active February 1, 2025 10:09
Show Gist options
  • Select an option

  • Save stoppert/017f43c8463319c5390ea3a75e8ad4f5 to your computer and use it in GitHub Desktop.

Select an option

Save stoppert/017f43c8463319c5390ea3a75e8ad4f5 to your computer and use it in GitHub Desktop.
Vite Plugin to generate index.html in dev mode
import fs from "fs/promises";
import {IndexHtmlTransformContext, Plugin, ServerOptions, UserConfig} from "vite";
let htmlCache: string | undefined = undefined;
const getUrlFromServer = (server: ServerOptions): string => {
const protocol = server.https ? 'https' : 'http';
const host = server.origin ?? 'localhost';
const port = server.port;
return `${protocol}://${host}:${port}`;
}
const vitePluginWriteIndexToDisk: () => Plugin = () => ({
name: 'vite-plugin-write-index-to-disk',
apply: 'serve',
order: 'pre',
config(config: UserConfig) {
// warmup triggers transformIndexHtml on start
if(config?.server?.warmup?.clientFiles && !config.server.warmup.clientFiles.includes('index.html')) {
config.server.warmup.clientFiles.push('index.html')
} else {
if(!config.server) {
config.server = {};
}
config.server.warmup = {
clientFiles: [
'index.html'
]
};
}
},
async handleHotUpdate({ server, modules }) {
if(modules.length === 0) {
const url = getUrlFromServer(server.config.server);
// fetch triggers transformIndexHtml after the initial warmup
await fetch(url);
}
},
transformIndexHtml(html: string, ctx: IndexHtmlTransformContext) {
if(!ctx.server) {
return;
}
const {build, server} = ctx.server.config;
const outDir = build.outDir;
const url = getUrlFromServer(server);
if(html !== htmlCache) {
htmlCache = html;
fs.writeFile(
`./${outDir}/index.html`,
html
.replaceAll('src="', `src="${url}`)
.replaceAll('href="', `href="${url}`)
);
}
},
});
export default vitePluginWriteIndexToDisk;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment