smolter
API

deploymentPlugin

Generate production build identity and a virtual browser manifest reference.

Compatibility

ReactServer/build API, not a browser import.
React SSRAvailable to this renderer's SSR integration; browser event handlers run after hydration.
PreactServer/build API, not a browser import.
Preact SSRAvailable to this renderer's SSR integration; browser event handlers run after hydration.

Import from @kasperrt/smolter/react/vite @kasperrt/smolter/preact/vite

Signature

function deploymentPlugin(
  options: DeploymentPluginOptions = {},
): Plugin;

Configuration

Add alongside fileRouter or applicationPlugins in the browser Vite configuration. Import from /react/vite or /preact/vite. It does not introduce a runtime dependency on Vite.

import { deploymentPlugin, applicationPlugins } from "@kasperrt/smolter/preact/vite";

export default {
  plugins: [...applicationPlugins(), deploymentPlugin()],
};

Build outputs

Emits a deterministic browser build identity, shared dependency fingerprint and lazy file-route fingerprints. Identical inputs keep their identity; styles/assets in the graph participate. virtual:smolter/deployment embeds the same metadata and manifest URL. Development and SSR export null. Manual/eager routes without route metadata retain conservative whole-build recovery.

import deployment from "virtual:smolter/deployment";

Hosting and base paths

The default public URL is Vite base plus smolter-manifest.json. Set manifestURL explicitly for a relative base or reverse proxy. Your host must serve the emitted file at that URL with Cache-Control: no-store, before fallback routes. Cross-origin reads require CORS.

deploymentPlugin({ manifestURL: "/admin/smolter-manifest.json" });

Connect the client

The plugin only produces metadata. Connect watchDeployment to the browser router to check updates during navigation. Static offline packages can omit both helpers.

import { watchDeployment } from "@kasperrt/smolter/react/client";

watchDeployment(router, deployment);

Server contracts and asset retention

Browser graph fingerprints cannot infer changes in independently deployed server code. Change compatibility when server-only contracts become incompatible. Retain old hashed assets during deployment; a missing chunk forces recovery even when semantic route fingerprints match. Runtime configuration, environment changes and external assets are not automatically fingerprinted. No new route code is loaded into an old runtime based only on matching hashes.

deploymentPlugin({ compatibility: "server-contract-v2" });

When to change the compatibility key

Usually no key is needed: changes visible to the browser build already change its fingerprints. Use a stable contract identifier only for incompatible changes outside that graph, then rebuild and deploy the frontend and its manifest with the new key. For example, an independently deployed API changing { name } to { displayName } is invisible to an unchanged browser build. A new key makes old tabs eligible for recovery; the newly deployed frontend must already understand the new response. It does not repair incompatible code, detect backend deployments automatically, or replace coordinated rollout and backward compatibility. Do not change the key for ordinary data updates.

deploymentPlugin({ compatibility: "profile-contract-v2" });
View implementation ↗