diff --git a/docs/guide/ssr.md b/docs/guide/ssr.md index 7651c729e4b165..5d7648b0ebf667 100644 --- a/docs/guide/ssr.md +++ b/docs/guide/ssr.md @@ -102,6 +102,52 @@ createServer() Here `vite` is an instance of [ViteDevServer](./api-javascript#vitedevserver). `vite.middlewares` is a [Connect](https://github.com/senchalabs/connect) instance which can be used as a middleware in any connect-compatible Node.js framework. +::: tip SSR-only module updates +By default, updating a module that is only imported by the SSR environment does not reload the page in the browser. Framework integrations usually handle this for you. For a low-level custom SSR setup, you can add a plugin that reloads the browser when an SSR-only module changes: + +```ts twoslash +import type { EnvironmentModuleNode, Plugin } from 'vite' + +export function ssrReload(): Plugin { + return { + name: 'ssr-reload', + enforce: 'post', + hotUpdate: { + order: 'post', + handler({ modules, server, timestamp }) { + if (this.environment.name !== 'ssr') return + + const invalidatedModules = new Set() + let hasSsrOnlyModules = false + + for (const mod of modules) { + if (mod.id == null) continue + const clientModule = + server.environments.client.moduleGraph.getModuleById(mod.id) + if (clientModule != null) continue + + this.environment.moduleGraph.invalidateModule( + mod, + invalidatedModules, + timestamp, + true, + ) + hasSsrOnlyModules = true + } + + if (hasSsrOnlyModules) { + server.environments.client.hot.send({ type: 'full-reload' }) + return [] + } + }, + }, + } +} +``` + +Add `ssrReload()` to the `plugins` array passed to `createViteServer` in the example above. See the [`hotUpdate` hook](./api-environment-plugins#the-hotupdate-hook) for details. +::: + The next step is implementing the `*` handler to serve server-rendered HTML: ```js twoslash [server.js]