From 0128f3fa1f08891f40b0e4d15e0956b664c72674 Mon Sep 17 00:00:00 2001 From: arlo Date: Wed, 25 Mar 2026 23:30:08 +0800 Subject: [PATCH] feat(core): introduce `@vitejs/devtools/preamble` for explicit devtools client injection --- docs/guide/index.md | 12 ++++++++++++ packages/core/src/node/plugins/injection.ts | 1 + 2 files changed, 13 insertions(+) diff --git a/docs/guide/index.md b/docs/guide/index.md index c7ec8ee6..4818a693 100644 --- a/docs/guide/index.md +++ b/docs/guide/index.md @@ -110,6 +110,18 @@ pnpm dev Then open your app in the browser and open the DevTools panel. +#### Projects without an HTML entry + +The embedded DevTools client is usually injected through Vite's `transformIndexHtml` hook. If your app does not start from an HTML entry, keep the `DevTools()` plugin enabled and import the client injector manually in your client entry instead: + +```ts twoslash +import '@vitejs/devtools/client/inject' +``` + +This loads the same DevTools client that would normally be added to `index.html`. Put it in a browser entry such as `main.ts` or `entry.client.ts`, not in server-only files or shared SSR entry files. + +If your project does have an HTML entry, avoid importing `@vitejs/devtools/client/inject` in addition to the HTML injection, as that would inject the client twice and create duplicate dock elements. + #### Building with the App You can also generate a static DevTools build alongside your app's build output by enabling the `build.withApp` option: diff --git a/packages/core/src/node/plugins/injection.ts b/packages/core/src/node/plugins/injection.ts index 878090cf..335187ad 100644 --- a/packages/core/src/node/plugins/injection.ts +++ b/packages/core/src/node/plugins/injection.ts @@ -7,6 +7,7 @@ export function DevToolsInjection(): Plugin { return { name: 'vite:devtools:injection', enforce: 'post', + apply: 'serve', transformIndexHtml() { const fileUrl = process.env.VITE_DEVTOOLS_LOCAL_DEV ? normalize(join(dirDist, '..', 'src/client/inject/index.ts'))