StartOptions
StartOptions configures the serving layer enabled by solidPlugin({ start }).
Import
import solidPlugin, { type StartOptions } from "@solidjs/vite-plugin";Type
interface StartOptions { app?: string; entries?: { server?: string; client?: string }; document?: string; middleware?: string; setup?: string; productionErrorBoundary?: boolean; externalServer?: boolean; node?: boolean;}All paths resolve relative to the Vite root and must exist.
The app, entry, document, middleware, and setup paths must remain inside that root.
The removed keys entryServer, entryClient, errorBoundary, external, env, and css fail at configuration time with a message naming the replacement.
Options
app
- Type:
string - Default: First match from
src/App.{tsx,jsx,ts,js}orsrc/app.{tsx,jsx,ts,js}
Specifies the default-exporting root component used by generated entries.
The plugin requires app when it cannot use an authored client entry in client mode or an authored entry pair in SSR mode.
entries.server
- Type:
string - Default: First existing
src/entry-server.{tsx,jsx,ts,js,mjs}, otherwise generated
Specifies an authored server entry for SSR start mode. The authored server entry must export:
function render( request?: Request, context?: { clientEntry: string; [key: string]: unknown }): RenderToStreamResult | string | Response | Promise<string | Response>;The plugin ignores entries.server and the conventional server entry in client start mode.
entries.client
- Type:
string - Default: First existing
src/entry-client.{tsx,jsx,ts,js,mjs}, otherwise generated
Specifies the browser entry. In SSR mode, authored server and client entries must both exist. In client mode, an authored client entry can stand alone.
Generated client entries call hydrate() in SSR mode and render() into document.body in client mode.
document
- Type:
string - Default: First existing
src/Document.{tsx,jsx}, otherwise a built-in document
Specifies the default-exporting full-document component used by generated server entries.
The document receives the application as props.children.
In SSR mode, an authored document must emit the <html> document and <HydrationScript />.
The handler injects the client entry into <head>.
In client mode, the document renders without the application. The handler removes an authored hydration script from that static shell.
middleware
- Type:
string - Default:
undefined
Specifies a server-only module whose default export is one middleware function or an array.
type Middleware = ( request: Request, next: (request?: Request) => Response | Promise<Response>) => Response | Promise<Response>;Middleware runs in array order inside the request-event scope. The middleware fronts every request dispatched by the generated handler, including pages and the server-function endpoint.
serverSetup
- Type:
string - Default:
undefined
Specifies a server-only module the plugin runs to completion once, before anything else in the server graph loads: the app, the middleware, @solidjs/web, and every dependency.
It is the place for a monitoring SDK's init(), which has to run before the modules it patches load.
The module needs no exports and may use top-level await.
It is the server counterpart of clientSetup.
serverRenderSetup
- Type:
string - Default:
undefined
Specifies a server-only module whose default export runs before every generated server render.
type ServerRenderSetup = ( event: RequestEvent, App: Component) => Component | void | Promise<Component | void>;Return a component to replace App for that request.
Return nothing to keep App.
The plugin ignores serverRenderSetup in client mode and rejects it when SSR uses authored entries.
The function does not run for server-function endpoint dispatch.
productionErrorBoundary
- Type:
boolean - Default:
true
In a production build, generated entries wrap the application in a default error boundary.
A render error streams a generic 500 | Internal Server Error fallback with no stack or error details, the error itself goes to console.error, and an error caught before the shell flushes commits a real 500 status.
Development is unaffected, and so are authored entries.
Set false when application middleware owns error handling: an error middleware only sees the throw when no boundary catches it first.
externalServer
- Type:
boolean - Default:
false
Hands SSR start-mode build wiring and HTTP serving to a host integration.
The plugin keeps generated entries, the client manifest, and virtual:solid-ssr-handler, but does not configure dist/server or its development middlewares.
The plugin ignores externalServer in client mode.
A host-owned, non-runnable ssr development environment is detected without this option.
Use serverFunctions.devMiddleware: false to hand over only development endpoint dispatch.
node
- Type:
boolean - Default:
false
Emits dist/server/node.js, a complete Node server, next to dist/server/server.js during vite build.
server.js, handleRequest, and the default { fetch } export do not change.
The emitted module:
- Serves the client build as static files before the handler, under a root-relative
base. Files underbuild.assetsDircarryCache-Control: public, max-age=31536000, immutable; other files carrypublic, max-age=0, must-revalidateandLast-Modified. Dot-segment paths and..traversal are refused. - Passes remaining requests to
handleRequest(request, { event: { nativeEvent: req } })through the bridge used byvite devandvite preview. A thrown error logs toconsole.errorand answers500. - In client mode with server functions, serves
dist/client/index.htmlfor HTMLGETrequests that match no file and dispatches the server-function endpoint. - Listens on
PORT(default3000) andHOSTwhen run directly withnode dist/server/node.js.
import type { IncomingMessage, Server, ServerResponse } from "node:http";
type Listener = (req: IncomingMessage, res: ServerResponse) => Promise<void>;
interface ListenerOptions { static?: boolean; event?: (req: IncomingMessage) => Record<string, unknown>;}
export declare const listener: Listener; // createListener()export declare function createListener(options?: ListenerOptions): Listener;export declare function serve( options?: { port?: number; host?: string } & ListenerOptions): Server;static: false skips the file lookup and the client-mode index.html fallback.
event returns fields merged over { nativeEvent: req }.
The build emits node.js only in the ssr environment and only when that build contains server.js.
The plugin warns and emits nothing with externalServer, and in client mode without serverFunctions.
Valid mode combinations
Transform only
solidPlugin();solidPlugin({ ssr: true });Without start, the plugin configures transforms only.
ssr: true enables the client and server transforms, while the application supplies entries and serving.
Client start mode
solidPlugin({ start: true });- Development serves the document shell for HTML
GETrequests and mounts the application withrender(). vite buildwrites the prerendered shell and client assets todist/client.- The build removes
dist/serverunless server functions require its handler. vite previewuses static SPA fallback and dispatches the server-function endpoint when enabled.
SSR start mode
solidPlugin({ start: true, ssr: true });- Development streams HTML through the runnable
ssrenvironment. vite buildbuilds the client first, writes client assets and a Vite manifest todist/client, and writesdist/server/server.js.- With
node: true, the build also writesdist/server/node.js. - The server bundle exports
handleRequest(request, options?). vite previewserves client assets and sends other requests through the built handler.
Server functions
serverFunctions composes with either start mode.
In client mode, pages remain static while dist/server/server.js remains available for endpoint requests.
With node: true, dist/server/node.js serves the static pages and the endpoint from one process.
In SSR mode, the same handler dispatches the endpoint before rendering a page.