The file
Put dusk.config.ts (or .mts, .js, .mjs) at the project root and export the result of defineConfig:
Put dusk.config.ts (or .mts, .js, .mjs) at the project root and export the result of defineConfig:
dusk.config.tsts
import { defineConfig } from "@shadow-js/dusk/vite";
export default defineConfig({
security: { allowedHosts: ["app.example"], trustedOrigins: ["https://partner.example"] },
env: { DATABASE_URL: { type: "url", required: true, secret: true } },
redirects: [{ source: "/old/:slug", destination: "/posts/:slug", permanent: true }],
rewrites: { beforeFiles: [{ source: "/legacy/*rest", destination: "/archive/*rest" }] },
headers: [{ source: "/assets/**", headers: { "cache-control": "public, max-age=31536000, immutable" } }],
routeRules: {
"/about": { prerender: true },
"/blog/**": { revalidate: 300 },
"/admin/**": { headers: { "x-robots-tag": "noindex" } },
},
cacheLife: { catalog: { stale: 60, revalidate: 600, expire: 3600 } },
deploymentId: "2026.10.09-1",
});
The keys, all optional:
| Property | Type | Default | Purpose |
|---|---|---|---|
adapter |
Adapter |
Plugin choice | Select the output platform. A value passed to dusk({ adapter }) takes precedence. |
security |
DuskSecurityConfig |
Handler defaults | Configure hosts, headers, CSP, CSRF, limits, trusted proxies and CORS. |
env |
DuskEnvShape |
No schema | Validate server variables and declare the public environment contract. |
i18n |
DuskI18nConfig |
No locale configuration | Set locales and the default document language; enable automatic locale routing with routing. |
image |
DuskImageConfig |
Optimizer defaults | Allow remote sources and choose output widths, formats and qualities. |
prerender |
false or PrerenderOptions |
Plugin choice | Select routes, entries and link crawling for static output. |
redirects |
RedirectRule[] |
None | Redirect matching paths to another URL. |
rewrites |
Routing phase lists | None | Resolve a request to another internal path without changing its browser URL. |
headers |
Header rule list | None | Add response headers to matching paths. |
routeRules |
Path-to-rule record | None | Configure prerendering, revalidation and headers per path. |
cacheLife |
Named CacheLifeProfile record |
Built-in profiles | Add or replace named stale, revalidate and expire lifetimes, in seconds. |
draftMode |
DuskDraftModeConfig |
Draft-mode defaults | Set the secret variable, cookie name and enable/disable paths. |
instrumentation |
false |
File convention enabled | Disable src/instrumentation.ts. |
deploymentId |
string |
Build-generated ID | Detect server-function calls from a different deployment. |
skew.reload |
boolean |
true |
Reload a stale client after a deployment mismatch. |
build.secretScan |
boolean |
true |
Refuse client output that contains a server secret or credential pattern. |
build.budgets |
DuskBuildBudgets |
None | Set gzip byte limits for first-load JavaScript and individual routes; enforce: true makes an overage fail the build. |
The complete types are in DuskConfig.
Keys that belong to dusk({ ... }) (srcDir, outDir, shadow, router, importProtection, maxPreloadsPerRoute)
are refused in the file, with the place to set them.
Secrets never go in this file. The build writes the server part of it into the server bundle, so
security.cookieSecrets is refused and a function anywhere in the server part is a build error that names its path.
Read secrets from the environment and pass them to createHandler in src/entry-server.ts.