API
This is the API documentation for this plugin. Here you will find all the options and their descriptions.
Example
Basic Example
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import csp from "vite-plugin-csp-guard";
import { definePolicy, self, unsafeInline } from "csp-toolkit";
export default defineConfig({
plugins: [
react(),
csp({
algorithm: "sha256", // Hash algorithm
dev: {
run: true, // Run in development mode
},
policy: definePolicy({
scriptSrc: [self, "https://www.google-analytics.com"],
styleSrcElem: [
self,
"https://fonts.googleapis.com",
unsafeInline,
],
fontSrc: [self, "https://fonts.gstatic.com"],
}),
}),
],
});Example with Environment-Specific Override
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import csp from "vite-plugin-csp-guard";
import { definePolicy, self } from "csp-toolkit";
export default defineConfig({
plugins: [
react(),
csp({
algorithm: "sha256",
dev: {
run: true,
override: false, // RECOMMENDED: Merge with defaults so dev mode works properly
},
build: {
sri: true,
override: true, // Use only custom policy in production for strict control
},
policy: definePolicy({
scriptSrc: [self, "https://www.google-analytics.com"],
styleSrcElem: [self, "https://fonts.googleapis.com"],
fontSrc: [self, "https://fonts.gstatic.com"],
}),
}),
],
});Options
algorithm
- Type:
string - Default:
sha256 - Description: The algorithm to use for hashing the content.
- Options:
sha256sha384sha512
dev
- Type:
object - Default:
{run: false, outlierSupport: [], override: undefined} - Description: The options for the dev server.
dev properties
policy
- Type:
CSPPolicy|DefinedPolicy(from csp-toolkit (opens in a new tab)) - Default:
{} - Description: The CSP to apply. Recommended: build it with
definePolicy()fromcsp-toolkit(camelCase directive keys, keyword helpers likeselfandunsafeInline). You can also pass a plain object with kebab-case directive keys and string sources, as before.
policy properties
With definePolicy, use camelCase keys (scriptSrc, styleSrcElem, etc.) and an array of sources per directive. With a plain object, the key is the directive name in kebab-case and the value is an array of string sources.
All official CSP directives (opens in a new tab) should be supported. If you find one that is not, please open an issue on the repo.
See Creating your policy and Upgrade to V4 — definePolicy.
Using definePolicy (recommended):
import { definePolicy, self, unsafeInline } from "csp-toolkit"
definePolicy({
scriptSrc: [self, "https://www.google-analytics.com"],
styleSrcElem: [
self,
"https://fonts.googleapis.com",
unsafeInline,
],
fontSrc: [self, "https://fonts.gstatic.com"],
})Plain object (still supported):
{
"script-src": ["'self'", "https://www.google-analytics.com"],
"style-src-elem": [
"'self'",
"https://fonts.googleapis.com",
"'unsafe-inline'",
],
"font-src": ["'self'", "https://fonts.gstatic.com"],
}build
- Type:
object - Default:
{sri: false, outlierSupport: [], override: undefined} - Description: Options that apply only when running
vite build.
override
- Type:
boolean - Default:
false - Description: This is a flag to override the default policy. When set to
false, the plugin will merge the default policy (provided by the plugin) with your policy. When set totrue, the plugin will only use your policy.
This option serves as the default override behavior for both development and production. You can override this on a per-environment basis using dev.override or build.override for more granular control.
Environment-Specific Control: The dev.override and build.override options take precedence over this top-level setting. This allows you to have different override behaviors in development vs production (e.g., merge in dev for easier debugging, but use only your policy in production for strict security).
transformPolicy
Added in v4. Not available in v3 or earlier.
- Type:
(cspString: string, meta: TransformPolicyMeta) => string | null | undefined | void - Default:
undefined(hook not used; the plugin injects a<meta http-equiv="Content-Security-Policy">as usual)
After the final CSP string is computed—including all generated hashes—this function runs. Use it to sync the policy to host-specific files (for example vercel.json, customHttp.yml on AWS Amplify, or Cloudflare _headers) while vite build still has the complete string.
The second argument, meta, has:
| Field | Type | Description |
|---|---|---|
command | "build" | "serve" | "build" during vite build, "serve" during vite dev (when the plugin runs with dev.run: true) |
algorithm | "sha256" | "sha384" | "sha512" | The hashing algorithm in use |
Return value and <meta> injection:
- Return
undefined(or omit a return) to keep the default: inject a meta tag using the generated policy string unchanged. - Return a
stringto use that value as the meta tagcontent(replace the generated string for the tag only; useful if you need to adjust quoting or a subset for local testing). - Return
nullto skip injecting the<meta>tag entirely. Use this when the real policy is sent as an HTTPContent-Security-Policyresponse header, which supports directives that meta tags cannot (for exampleframe-ancestors,report-uri,report-to).
The hook still runs in dev when dev.run is true, so any file writes run on each policy refresh. Guard side effects (e.g. only write when meta.command === "build") if you need to avoid touching deploy config on every HMR.
Example: write deploy config and skip the meta tag
import * as fs from "node:fs";
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import csp from "vite-plugin-csp-guard";
export default defineConfig({
plugins: [
react(),
csp({
policy: {
"default-src": ["'self'"],
"script-src-elem": ["'self'"],
"style-src-elem": ["'self'"],
},
transformPolicy: (cspString, meta) => {
if (meta.command === "build") {
// Example: emit a file your host reads at deploy time
fs.writeFileSync(
"csp-built.txt",
cspString,
"utf8",
);
}
// Headers-only delivery in production: do not duplicate policy in HTML
return null;
},
}),
],
});