new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Vite · Guide · all subjects

ssr and backend integration

40 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Vite config for backend integration - entry and manifest

In the Vite config, set `input: '/path/to/main.js'` to overwrite the default .html entry, and set `build.manifest: true` to generate .vite/manifest.json in outDir. When configuring CORS for backend development, set `server.cors.origin` to the URL you will be accessing via browser (e.g., 'http://my-backend.example.com').

Module preload polyfill import for backend integration

If the module preload polyfill hasn't been disabled, import 'vite/modulepreload-polyfill' at the beginning of your app entry file when setting up backend integration.

Development HTML template injection for backend

For development, inject two script tags in the server's HTML template: <script type="module" src="http://localhost:5173/@vite/client"></script> and <script type="module" src="http://localhost:5173/main.js"></script>. Substitute http://localhost:5173 with the local URL Vite is running at. To properly serve assets, either configure the server to proxy static asset requests to the Vite server or set server.origin so that generated asset URLs resolve using the back-end server URL instead of a relative path.

React @vitejs/plugin-react HMR setup for backend

When using React with @vitejs/plugin-react in backend integration, inject this script before the other development scripts since the plugin cannot modify the HTML being served: <script type="module">\nimport RefreshRuntime from 'http://localhost:5173/@react-refresh'\nRefreshRuntime.injectIntoGlobalHook(window)\nwindow.$RefreshReg$ = () => {}\nwindow.$RefreshSig$ = () => (type) => type\nwindow.__vite_plugin_react_preamble_installed__ = true\n</script>. Substitute http://localhost:5173 with the local URL Vite is running at.

ManifestChunk interface structure

The ManifestChunk interface has the following properties: src (string, optional - input file name if known), file (string, required - output file name), css (string array, optional - CSS files imported by this chunk), assets (string array, optional - asset files imported by this chunk excluding CSS), isEntry (boolean, optional - whether this chunk or asset is an entry point), name (string, optional - name of this chunk/asset if known), isDynamicEntry (boolean, optional, JS chunks only - whether this chunk is a dynamic entry point), imports (string array, optional, JS chunks only - statically imported chunks with values as manifest keys), dynamicImports (string array, optional, JS chunks only - dynamically imported chunks with values as manifest keys).

Manifest entry types and key naming conventions

Entry chunks are generated from build.rolldownOptions.input with isEntry: true and key is relative src path from project root. Dynamic entry chunks have isDynamicEntry: true with key as relative src path. Non-entry chunks have key as base name of generated file prefixed with underscore. Asset chunks (images, fonts) have key as relative src path. CSS files: when build.cssCodeSplit is false, a single CSS file is generated with key 'style.css'; when build.cssCodeSplit is not false, key is generated like JS chunks (entry chunks without underscore prefix, non-entry chunks with underscore prefix).

Production HTML tag generation order for backend

For production, include tags in this order for optimal performance: (1) <link rel="stylesheet"> tag for each file in the entry point chunk's css list if it exists; (2) Recursively follow all chunks in the entry point's imports list and include <link rel="stylesheet"> for each CSS file of each imported chunk's css list if it exists; (3) A tag for the file key of the entry point chunk - <script type="module"> for JavaScript or <link rel="stylesheet"> for CSS; (4) Optionally, <link rel="modulepreload"> tag for the file of each imported JavaScript chunk, recursively following imports from the entry point.

Production HTML example for manifest entry views/foo.js

For entry point views/foo.js, the production HTML should include: <link rel="stylesheet" href="assets/foo-5UjPuW-k.css" />, <link rel="stylesheet" href="assets/shared-ChJ_j-JJ.css" />, <script type="module" src="assets/foo-BRBmoGS9.js"></script>, and optionally <link rel="modulepreload" href="assets/shared-B7PI925R.js" />.

Production HTML example for manifest entry views/bar.js

For entry point views/bar.js, the production HTML should include: <link rel="stylesheet" href="assets/shared-ChJ_j-JJ.css" />, <script type="module" src="assets/bar-gkvgaI9m.js"></script>, and optionally <link rel="modulepreload" href="assets/shared-B7PI925R.js" />.

Experimental build.chunkImportMap import map injection

If using the experimental build.chunkImportMap option, the import map is output to importmap.json in the output directory. Inject the <script type="importmap"> tag before any <script type="module"> tags or <link rel="modulepreload"> tags.

Manifest file structure for backend asset resolution

The .vite/manifest.json file has a Record<name, chunk> structure where each key maps to a ManifestChunk. The manifest maps source files to their build outputs and dependencies. Each entry represents entry chunks (from build.rolldownOptions.input), dynamic entry chunks (from dynamic imports), non-entry chunks, asset chunks, or CSS files. This manifest enables backends to render correct links and preload directives with hashed filenames.

SSR build CLI option

The `--ssr [entry]` option in `vite build` enables building a specified entry for server-side rendering.

WebAssembly SSR limitation

For SSR build, Node.js compatible runtimes are only supported. Due to the lack of a universal way to load a file, the internal implementation for both direct `.wasm` imports and `.wasm?init` relies on the `node:fs` module. This means that these features will only work in Node.js compatible runtimes for SSR builds.

Vite includes SSR primitives support

Vite includes support for SSR primitives, which are usually present in higher-level tools but are fundamental to building modern web frameworks.

Vite works with backend frameworks

Vite is a great fit when paired with backend frameworks like Ruby and Laravel.

server.middlewareMode create Vite server as middleware

server.middlewareMode is of type 'boolean' with default value 'false'. Create Vite server in middleware mode. Related to 'appType' and 'SSR - Setting Up the Dev Server'.

server.middlewareMode example implementation

Example of server.middlewareMode: ```js import express from 'express' import { createServer as createViteServer } from 'vite' async function createServer() { const app = express() // Create Vite server in middleware mode const vite = await createViteServer({ server: { middlewareMode: true }, // don't include Vite's default HTML handling middlewares appType: 'custom', }) // Use vite's connect instance as middleware app.use(vite.middlewares) app.use('*', async (req, res) => { // Since `appType` is `'custom'`, should serve response here. // Note: if `appType` is `'spa'` or `'mpa'`, Vite includes middlewares // to handle HTML requests and 404s so user middlewares should be added // before Vite's middlewares to take effect instead }) } createServer() ```

vite.ssrFixStacktrace for error handling

The vite.ssrFixStacktrace(error) method maps error stack traces back to actual source code in SSR contexts, allowing proper error reporting and debugging.

SSR definition and scope

Server-Side Rendering (SSR) specifically refers to front-end frameworks such as React, Preact, Vue, and Svelte that support running the same application in Node.js, pre-rendering it to HTML, and finally hydrating it on the client. For integration with traditional server-side frameworks, the Backend Integration guide should be consulted instead.

Typical SSR application source structure

A typical SSR application has the following structure: index.html (entry point), server.js (main application server), and src/ directory containing main.js (exports env-agnostic universal app code), entry-client.js (mounts the app to a DOM element), and entry-server.js (renders the app using the framework's SSR API).

index.html SSR outlet placeholder

The index.html file must reference entry-client.js and include a placeholder where server-rendered markup should be injected. The placeholder can be any string that can be precisely replaced, such as <!--ssr-outlet-->.

Conditional logic based on SSR vs client

To perform conditional logic based on SSR vs client, use the import.meta.env.SSR property. This is statically replaced during build and allows tree-shaking of unused branches.

Vite middleware mode for SSR dev server

When building an SSR app, use Vite in middleware mode by setting server.middlewareMode to true and appType to 'custom' in createViteServer. The vite.middlewares property is a Connect instance that can be used as middleware in any connect-compatible Node.js framework. When the server restarts, vite.middlewares remains the same reference with a new internal stack of middlewares.

vite.transformIndexHtml for HTML transforms

The vite.transformIndexHtml(url, template) method applies Vite HTML transforms to the index.html template. This injects the Vite HMR client and applies HTML transforms from Vite plugins, such as global preambles from @vitejs/plugin-react.

vite.ssrLoadModule for loading server entry

The vite.ssrLoadModule method automatically transforms ESM source code to be usable in Node.js without bundling. It provides efficient invalidation similar to HMR. Use this to load the server entry file and access exported functions like render.

SSR production build scripts

For production SSR projects, create separate build scripts: 'build:client' runs 'vite build --outDir dist/client' for the client build, and 'build:server' runs 'vite build --outDir dist/server --ssr src/entry-server.js' for the SSR build. The --ssr flag indicates this is an SSR build and should specify the SSR entry.

Production SSR server changes

In production SSR, use dist/client/index.html as the template instead of the root index.html because it contains correct asset links. Instead of vite.ssrLoadModule, use import() to load the built SSR entry file at dist/server/entry-server.js. Move vite dev server creation behind dev-only conditional branches and add static file serving middlewares for the dist/client directory.

SSR manifest generation with --ssrManifest flag

The 'vite build' command supports the --ssrManifest flag which generates .vite/ssr-manifest.json in the build output directory. The manifest is generated from the client build and contains mappings of module IDs to their associated chunks and asset files. Use this to map module IDs of components used during server render to enable preload directive generation.

Module ID collection in SSR context

Frameworks like @vitejs/plugin-vue automatically register used component module IDs on the associated Vue SSR context. The module IDs are collected in ctx.modules as a Set during server render and can be used to generate preload directives for files used by async routes.

Pre-rendering or Static-Site Generation (SSG)

If routes and data needed for certain routes are known ahead of time, they can be pre-rendered into static HTML using the same logic as production SSR. This is also considered Static-Site Generation (SSG).

SSR externals default behavior

Dependencies are externalized from Vite's SSR transform module system by default when running SSR. This speeds up both dev and build. If a dependency needs to be transformed by Vite's pipeline, it can be added to ssr.noExternal. Linked dependencies are not externalized by default to take advantage of Vite's HMR.

ssr.external for linked dependencies

To test linked dependencies as if they are not linked, add them to the ssr.external configuration option.

Aliases working with SSR externalized dependencies

If aliases are configured that redirect one package to another, alias the actual node_modules packages instead to make it work for SSR externalized dependencies. Both Yarn and pnpm support aliasing via the npm: prefix.

SSR-specific plugin hook option

Vite passes an additional ssr property in the options object of plugin hooks: resolveId, load, and transform. This allows frameworks to compile components into different formats based on client vs SSR. The options object in load and transform is optional, with the ssr flag indicating whether SSR-specific transforms should be applied.

SSR target configuration

The default target for SSR build is a node environment, but it can also run in a Web Worker. Configure the target using ssr.target set to 'webworker'. Package entry resolution differs for each platform.

SSR bundle with ssr.noExternal

For runtimes like webworker where you want to bundle SSR build into a single JavaScript file, set ssr.noExternal to true. This treats all dependencies as noExternal and throws an error if any Node.js built-ins are imported.

SSR resolve conditions configuration

Package entry resolution for SSR build uses conditions set in resolve.conditions by default. Use ssr.resolve.conditions and ssr.resolve.externalConditions to customize this behavior.

Vite CLI for SSR applications

The CLI commands 'vite dev' and 'vite preview' can be used for SSR apps. Add SSR middlewares to the development server using configureServer hook and to the preview server using configurePreviewServer hook. Use post hooks so that SSR middleware runs after Vite's middlewares.

How Vite distinguishes between server and client code in SSR

Vite distinguishes between server and client code in SSR through the import.meta.env.SSR property and by passing an ssr flag in the options object of plugin hooks (resolveId, load, transform). These allow conditional logic and transformations based on whether code runs on the server or client.

Qwik CSR mode configuration

To enable Client-Side Rendering (CSR) mode in a Qwik + Vite project, use the qwikVite plugin with the csr option set to true in the defineConfig. CSR mode means the application is fully bootstrapped in the browser, but most of Qwik's innovations take advantage of SSR (Server-Side Rendering) mode instead.

Give your agent this brain