UNPKG

astro

Version:

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

1,125 lines 132 kB
import type { OutgoingHttpHeaders } from 'node:http'; import type { RemotePattern } from '@astrojs/internal-helpers/remote'; import type { RehypePlugins, RemarkPlugins, RemarkRehype, ShikiConfig, Smartypants, SyntaxHighlightConfigType } from '@astrojs/internal-helpers/markdown'; import type { MarkdownProcessor } from '../../markdown/index.js'; import type { UserConfig as OriginalViteUserConfig, SSROptions as ViteSSROptions } from 'vite'; import type { FontFamily, FontProvider } from '../../assets/fonts/types.js'; import type { ImageFit, ImageLayout } from '../../assets/types.js'; import type { AssetsPrefix } from '../../core/app/types.js'; import type { CacheProviderConfig, RouteRules } from '../../core/cache/types.js'; import type { AstroConfigType } from '../../core/config/schemas/index.js'; import type { REDIRECT_STATUS_CODES } from '../../core/constants.js'; import type { CspAlgorithm, CspDirective, CspHash, CspHashEntry, CspKind, CspResourceEntry } from '../../core/csp/config.js'; import type { AstroLoggerLevel } from '../../core/logger/core.js'; import type { SessionConfig, SessionDriverConfig, SessionDriverName } from '../../core/session/types.js'; import type { EnvSchema } from '../../env/schema.js'; import type { AstroIntegration } from './integrations.js'; import type { SvgOptimizer } from '../../assets/svg/types.js'; import type { LoggerHandlerConfig } from '../../core/logger/config.js'; export type Locales = (string | { codes: [string, ...string[]]; path: string; })[]; export type { FontProvider }; export type { CspAlgorithm, CspHash, CspKind, CspResourceEntry, CspHashEntry }; export type { RemotePattern }; export type { SvgOptimizer }; export type CspStyleDirective = { hashes?: CspHashEntry[]; resources?: CspResourceEntry[]; }; export type CspScriptDirective = { hashes?: CspHashEntry[]; resources?: CspResourceEntry[]; strictDynamic?: boolean; }; type NormalizeLocales<T extends Locales> = { [K in keyof T]: T[K] extends string ? T[K] : T[K] extends { codes: Array<string>; } ? T[K]['codes'][number] : never; }[number]; export interface ImageServiceConfig<T extends Record<string, any> = Record<string, any>> { entrypoint: 'astro/assets/services/sharp' | (string & {}); config?: T; } export type RuntimeMode = 'development' | 'production'; export type ValidRedirectStatus = (typeof REDIRECT_STATUS_CODES)[number]; export type RedirectConfig = string | { status: ValidRedirectStatus; destination: string; }; export type ServerConfig = { /** * @name server.host * @type {string | boolean} * @default `false` * @version 0.24.0 * @description * Set which network IP addresses the dev server should listen on (i.e. non-localhost IPs). * - `false` - do not expose on a network IP address * - `true` - listen on all addresses, including LAN and public addresses * - `[custom-address]` - expose on a network IP address at `[custom-address]` */ host?: string | boolean; /** * @name server.port * @type {number} * @default `4321` * @description * Set which port the dev server should listen on. * * If the given port is already in use, Astro will automatically try the next available port. */ port?: number; /** * @name server.allowedHosts * @type {string[] | true} * @default `[]` * @version 5.4.0 * @description * * A list of hostnames that Astro is allowed to respond to. When the value is set to `true`, any * hostname is allowed. * * ```js * { * server: { * allowedHosts: ['staging.example.com', 'qa.example.com'] * } * } * ``` */ allowedHosts?: string[] | true; /** * @name server.headers * @typeraw {OutgoingHttpHeaders} * @default `{}` * @version 1.7.0 * @description * Set custom HTTP response headers to be sent in `astro dev` and `astro preview`. */ headers?: OutgoingHttpHeaders; /** * @name server.open * @type {string | boolean} * @default `false` * @version 4.1.0 * @description * Controls whether the dev server should open in your browser window on startup. * * Pass a full URL string (e.g. "http://example.com") or a pathname (e.g. "/about") to specify the URL to open. * * ```js * { * server: { open: "/about" } * } * ``` */ open?: string | boolean; }; export interface ViteUserConfig extends OriginalViteUserConfig { ssr?: ViteSSROptions; } /** * Astro User Config * Docs: https://docs.astro.build/reference/configuration-reference/ * * Generics do not follow semver and may change at any time. */ export interface AstroUserConfig<TLocales extends Locales = never, TDriver extends SessionDriverName | SessionDriverConfig | undefined = never, TFontProviders extends Array<FontProvider> = never> { /** * @docs * @kind heading * @name Top-Level Options */ /** * @docs * @name site * @type {string} * @description * Your final, deployed URL. Astro uses this full URL to generate your sitemap and canonical URLs in your final build. It is strongly recommended that you set this configuration to get the most out of Astro. * * ```js * { * site: 'https://www.my-site.dev' * } * ``` */ site?: string; /** * @docs * @name base * @type {string} * @description * The base path to deploy to. Astro will use this path as the root for your pages and assets both in development and in production build. * * In the example below, `astro dev` will start your server at `/docs`. * * ```js * { * base: '/docs' * } * ``` * * When using this option, all of your static asset imports and URLs should add the base as a prefix. You can access this value via `import.meta.env.BASE_URL`. * * The value of `import.meta.env.BASE_URL` will be determined by your `trailingSlash` config, no matter what value you have set for `base`. * * A trailing slash is always included if `trailingSlash: "always"` is set. If `trailingSlash: "never"` is set, `BASE_URL` will not include a trailing slash, even if `base` includes one. * * Additionally, Astro will internally manipulate the configured value of `config.base` before making it available to integrations. The value of `config.base` as read by integrations will also be determined by your `trailingSlash` configuration in the same way. * * In the example below, the values of `import.meta.env.BASE_URL` and `config.base` when processed will both be `/docs`: * ```js * { * base: '/docs/', * trailingSlash: "never" * } * ``` * * In the example below, the values of `import.meta.env.BASE_URL` and `config.base` when processed will both be `/docs/`: * * ```js * { * base: '/docs', * trailingSlash: "always" * } * ``` */ base?: string; /** * @docs * @name trailingSlash * @type {('always' | 'never' | 'ignore')} * @default `'ignore'` * @see build.format * @description * * Set the route matching behavior for trailing slashes in the dev server and on-demand rendered pages. Choose from the following options: * - `'ignore'` - Match URLs regardless of whether a trailing "/" exists. Requests for "/about" and "/about/" will both match the same route. * - `'always'` - Only match URLs that include a trailing slash (e.g: "/about/"). In production, requests for on-demand rendered URLs without a trailing slash will be redirected to the correct URL for your convenience. However, in development, they will display a warning page reminding you that you have `always` configured. * - `'never'` - Only match URLs that do not include a trailing slash (e.g: "/about"). In production, requests for on-demand rendered URLs with a trailing slash will be redirected to the correct URL for your convenience. However, in development, they will display a warning page reminding you that you have `never` configured. * * When redirects occur in production for GET requests, the redirect will be a 301 (permanent) redirect. For all other request methods, it will be a 308 (permanent, and preserve the request method) redirect. * * Trailing slashes on prerendered pages are handled by the hosting platform, and may not respect your chosen configuration. * See your hosting platform's documentation for more information. You cannot use Astro [redirects](https://docs.astro.build/en/reference/configuration-reference/#redirects) for this use case at this point. * * ```js * { * // Example: Require a trailing slash during development * trailingSlash: 'always' * } * ``` */ trailingSlash?: 'always' | 'never' | 'ignore'; /** * @docs * @name redirects * @type {Record<string, RedirectConfig>} * @default `{}` * @version 2.9.0 * @description Specify a mapping of redirects where the key is the route to match * and the value is the path to redirect to. * * You can redirect both static and dynamic routes, but only to the same kind of route. * For example, you cannot have a `'/article': '/blog/[...slug]'` redirect. * * * ```js * export default defineConfig({ * redirects: { * '/old': '/new', * '/blog/[...slug]': '/articles/[...slug]', * '/about': 'https://example.com/about', * '/news': { * status: 302, * destination: 'https://example.com/news' * }, * // '/product1/', '/product1' // Note, this is not supported * } * }) * ``` * * * For statically-generated sites with no adapter installed, this will produce a client redirect using a [`<meta http-equiv="refresh">` tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta#http-equiv) and does not support status codes. * * When using SSR or with a static adapter in `output: static` * mode, status codes are supported. * Astro will serve redirected GET requests with a status of `301` * and use a status of `308` for any other request method. * * You can customize the [redirection status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages) using an object in the redirect config: * * ```js * export default defineConfig({ * redirects: { * '/other': { * status: 302, * destination: '/place', * }, * } * }) * * * ``` */ redirects?: Record<string, RedirectConfig>; /** * @docs * @name output * @type {('static' | 'server')} * @default `'static'` * @see adapter * @description * * Specifies the output target for builds. * * - `'static'` - Prerender all your pages by default, outputting a completely static site if none of your pages opt out of prerendering. * - `'server'` - Use server-side rendering (SSR) for all pages by default, always outputting a server-rendered site. * * ```js * import { defineConfig } from 'astro/config'; * * export default defineConfig({ * output: 'static' * }) * ``` */ output?: 'static' | 'server'; /** * @docs * @name adapter * @typeraw {AstroIntegration} * @see output * @description * * Deploy to your favorite server, serverless, or edge host with build adapters. Import one of our first-party adapters ([Cloudflare](https://docs.astro.build/en/guides/integrations-guide/cloudflare/), [Netlify](https://docs.astro.build/en/guides/integrations-guide/netlify/), [Node.js](https://docs.astro.build/en/guides/integrations-guide/node/), [Vercel](https://docs.astro.build/en/guides/integrations-guide/vercel/)) or explore [community adapters](https://astro.build/integrations/2/?search=&categories%5B%5D=adapters) to enable on-demand rendering in your Astro project. * * See our [on-demand rendering guide](https://docs.astro.build/en/guides/on-demand-rendering/) for more on Astro's server rendering options. * * ```js * import netlify from '@astrojs/netlify'; * { * // Example: Build for Netlify serverless deployment * adapter: netlify(), * } * ``` */ adapter?: AstroIntegration; /** * @docs * @name integrations * @typeraw {AstroIntegration[]} * @description * * Extend Astro with custom integrations. Integrations are your one-stop-shop for adding framework support (like Solid.js), new features (like sitemaps), and new libraries (like Partytown). * * Read our [Integrations Guide](https://docs.astro.build/en/guides/integrations/) for help getting started with Astro Integrations. * * ```js * import react from '@astrojs/react'; * import mdx from '@astrojs/mdx'; * { * // Example: Add React + MDX support to Astro * integrations: [react(), mdx()] * } * ``` */ integrations?: Array<AstroIntegration | (AstroIntegration | false | undefined | null)[] | false | undefined | null>; /** * @docs * @name root * @cli --root * @type {string} * @default `"."` (current working directory) * @summary Set the project root. The project root is the directory where your Astro project (and all `src`, `public` and `package.json` files) live. * @description You should only provide this option if you run the `astro` CLI commands in a directory other than the project root directory. Usually, this option is provided via the CLI instead of the Astro config file, since Astro needs to know your project root before it can locate your config file. * * If you provide a relative path (ex: `--root: './my-project'`) Astro will resolve it against your current working directory. * * #### Examples * * ```js * { * root: './my-project-directory' * } * ``` * ```bash * $ astro build --root ./my-project-directory * ``` */ root?: string; /** * @docs * @name srcDir * @type {string} * @default `"./src"` * @description Set the directory that Astro will read your site from. * * The value can be either an absolute file system path or a path relative to the project root. * * ```js * { * srcDir: './www' * } * ``` */ srcDir?: string; /** * @docs * @name publicDir * @type {string} * @default `"./public"` * @description * Set the directory for your static assets. Files in this directory are served at `/` during dev and copied to your build directory during build. These files are always served or copied as-is, without transform or bundling. * * The value can be either an absolute file system path or a path relative to the project root. * * ```js * { * publicDir: './my-custom-publicDir-directory' * } * ``` */ publicDir?: string; /** * @docs * @name outDir * @type {string} * @default `"./dist"` * @see build.server * @description Set the directory that `astro build` writes your final build to. * * The value can be either an absolute file system path or a path relative to the project root. * * ```js * { * outDir: './my-custom-build-directory' * } * ``` */ outDir?: string; /** * @docs * @name cacheDir * @type {string} * @default `"./node_modules/.astro"` * @description Set the directory for caching build artifacts. Files in this directory will be used in subsequent builds to speed up the build time. * * The value can be either an absolute file system path or a path relative to the project root. * * ```js * { * cacheDir: './my-custom-cache-directory' * } * ``` */ cacheDir?: string; /** * @docs * @name compressHTML * @type {boolean | "jsx"} * @default `'jsx'` * @description * * Controls how Astro handles whitespace in your HTML. This affects both development mode and the final build output. * * Since v7.0, Astro applies by default the JSX whitespace rules used by frameworks like React. This removes whitespace and line breaks around elements, collapses multi-line text onto a single line, and preserves whitespace within a single line (e.g. a space between two inline elements). To keep a space that would otherwise be removed, include it explicitly in the source through constructs such as `{" "}`. * * Setting this option to `true` instead removes whitespace, including line breaks, in a lossless manner from `.astro` components. Some whitespace may be preserved as needed to maintain the visual rendering of your HTML. * * Setting this option to `false` disables HTML compression and preserves all whitespace. * * ```js * { * compressHTML: true * // or: * // compressHTML: false * } * ``` */ compressHTML?: boolean | 'jsx'; /** * @docs * @name scopedStyleStrategy * @type {('where' | 'class' | 'attribute')} * @default `'attribute'` * @version 2.4 * @description * * Specify the strategy used for scoping styles within Astro components. Choose from: * - `'where'` - Use `:where` selectors, causing no specificity increase. * - `'class'` - Use class-based selectors, causing a +1 specificity increase. * - `'attribute'` - Use `data-` attributes, causing a +1 specificity increase. * * Using `'class'` is helpful when you want to ensure that element selectors within an Astro component override global style defaults (e.g. from a global stylesheet). * Using `'where'` gives you more control over specificity, but requires that you use higher-specificity selectors, layers, and other tools to control which selectors are applied. * Using `'attribute'` is useful when you are manipulating the `class` attribute of elements and need to avoid conflicts between your own styling logic and Astro's application of styles. */ scopedStyleStrategy?: 'where' | 'class' | 'attribute'; /** * @docs * @name prerenderConflictBehavior * @type {'error' | 'warn' | 'ignore'} * @default `'warn'` * @version 6.0 * @description * Determines the default behavior when two routes generate the same prerendered URL: * - `error`: fail the build and display an error, forcing you to resolve the conflict * - `warn` (default): log a warning when conflicts occur, but build using the highest-priority route * - `ignore`: silently build using the highest-priority route when conflicts occur * * ```js * { * prerenderConflictBehavior: 'error' * } * ``` */ prerenderConflictBehavior?: 'error' | 'warn' | 'ignore'; /** * @docs * @name vite * @typeraw {ViteUserConfig} * @description * * Pass additional configuration options to Vite. Useful when Astro doesn't support some advanced configuration that you may need. * * View the full `vite` configuration object documentation on [vite.dev](https://vite.dev/config/). * * #### Examples * * ```js * { * vite: { * ssr: { * // Example: Force a broken package to skip SSR processing, if needed * external: ['broken-npm-package'], * } * } * } * ``` * * ```js * { * vite: { * // Example: Add custom vite plugins directly to your Astro project * plugins: [myPlugin()], * } * } * ``` */ vite?: ViteUserConfig; /** * @docs * @name security * @type {Record<"checkOrigin", boolean> | undefined} * @default `{checkOrigin: true}` * @version 4.9.0 * @description * * Enables security measures for an Astro website. * * These features only exist for pages rendered on demand (SSR) using `server` mode or pages that opt out of prerendering in `static` mode. * * By default, Astro will automatically check that the “origin” header * matches the URL sent by each request in on-demand rendered pages. You can * disable this behavior by setting `checkOrigin` to `false`: * * ```js * // astro.config.mjs * export default defineConfig({ * output: "server", * security: { * checkOrigin: false * } * }) * ``` */ security?: { /** * @docs * @name security.checkOrigin * @kind h4 * @type {boolean} * @default `true` * @version 4.9.0 * @description * * Performs a check that the "origin" header, automatically passed by all modern browsers, matches the URL sent by each `Request`. This is used to provide Cross-Site Request Forgery (CSRF) protection. * * The "origin" check is executed only for pages rendered on demand, and only for the requests `POST`, `PATCH`, `DELETE` and `PUT` with * one of the following `content-type` headers: `'application/x-www-form-urlencoded'`, `'multipart/form-data'`, `'text/plain'`. * * If the "origin" header doesn't match the `pathname` of the request, Astro will return a 403 status code and will not render the page. */ checkOrigin?: boolean; /** * @docs * @name security.allowedDomains * @kind h4 * @type {RemotePattern[]} * @default `[]` * @version 5.14.2 * @description * * Defines a list of permitted host patterns for incoming requests when using SSR. When configured, Astro will validate the `X-Forwarded-Host` header * against these patterns for security. If the header doesn't match any allowed pattern, the header is ignored and the request's original host is used instead. * * This prevents host header injection attacks where malicious actors can manipulate the `Astro.url` value by sending crafted `X-Forwarded-Host` headers. * * Each pattern can specify `protocol`, `hostname`, and `port`. All three are validated if provided. * The patterns support wildcards for flexible hostname matching: * * - `*.example.com` - matches exactly one subdomain level (e.g., `sub.example.com` but not `deep.sub.example.com`) * - `**.example.com` - matches any subdomain depth (e.g., both `sub.example.com` and `deep.sub.example.com`) * * ```js * { * security: { * // Example: Allow any subdomain of example.com on https * allowedDomains: [ * { * hostname: '**.example.com', * protocol: 'https' * }, * { * hostname: 'staging.myapp.com', * protocol: 'https', * port: '443' * } * ] * } * } * ``` * * In some specific contexts (e.g., applications behind trusted reverse proxies with dynamic domains), you may need to allow all domains. To do this, use an empty object: * * ```js * { * security: { * // Allow any domain - use this only when necessary * allowedDomains: [{}] * } * } * ``` * * When not configured, `X-Forwarded-Host` headers are not trusted and will be ignored. */ allowedDomains?: Partial<RemotePattern>[]; /** * @docs * @name security.actionBodySizeLimit * @kind h4 * @type {number} * @default `1048576` (1 MB) * @version 5.18.0 * @description * * Sets the maximum size in bytes allowed for action request bodies. * * By default, action request bodies are limited to 1 MB (1048576 bytes) to prevent abuse. * You can increase this limit if your actions need to accept larger payloads, for example when handling file uploads. * * ```js * // astro.config.mjs * export default defineConfig({ * security: { * actionBodySizeLimit: 10 * 1024 * 1024 // 10 MB * } * }) * ``` */ actionBodySizeLimit?: number; /** * @docs * @name security.serverIslandBodySizeLimit * @kind h4 * @type {number} * @default `1048576` (1 MB) * @version 6.0.0 * @description * * Sets the maximum size in bytes allowed for server island request bodies, which contain the encrypted props and slot HTML passed to the island component. * * By default, server island request bodies are limited to 1 MB (1048576 bytes) to prevent abuse. * You can increase this limit if your server islands need to accept larger payloads. * * ```js * // astro.config.mjs * export default defineConfig({ * security: { * serverIslandBodySizeLimit: 10 * 1024 * 1024 // 10 MB * } * }) * ``` */ serverIslandBodySizeLimit?: number; /** * @docs * @name security.csp * @kind h4 * @type {boolean | object} * @default `false` * @version 6.0.0 * @description * * Enables support for [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) to help minimize certain types of security threats by controlling which resources a document is allowed to load. This provides additional protection against [cross-site scripting (XSS)](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) attacks. * * Enabling this feature adds additional security to Astro's handling of processed and bundled scripts and styles by default, and allows you to further configure these, and additional, content types. * * This feature comes with some limitations: * - External scripts and external styles are not supported out of the box, but you can [provide your own hashes](https://docs.astro.build/en/reference/configuration-reference/#securitycspscriptdirectivehashes). * - [Astro's view transitions](https://docs.astro.build/en/guides/view-transitions/) using the `<ClientRouter />` are not supported, but you can [consider migrating to the browser native View Transition API](https://events-3bg.pages.dev/jotter/astro-view-transitions/) instead if you are not using Astro's enhancements to the native View Transitions and Navigation APIs. * - Shiki isn't currently supported. By design, Shiki functions use inline styles that cannot work with Astro CSP implementation. Consider [using `<Prism />`](https://docs.astro.build/en/guides/syntax-highlighting/#prism-) when your project requires both CSP and syntax highlighting. * - `unsafe-inline` directives are incompatible with Astro's CSP implementation. By default, Astro will emit hashes for all its bundled scripts (e.g. client islands) and all modern browsers will automatically reject `unsafe-inline` when it occurs in a directive with a hash or nonce. * * :::note * Due to the nature of the Vite dev server, this feature isn't supported while working in `dev` mode. Instead, you can test this in your Astro project using `build` and `preview`. * ::: * * When enabled, Astro will add a `<meta>` element inside the `<head>` element of each page. * This element will have the `http-equiv="content-security-policy"` attribute, and the `content` attribute will provide values for the `script-src` and `style-src` [directives](https://docs.astro.build/en/reference/configuration-reference/#securitycspdirectives) based on the script and styles used in the page. * * ```html * * <head> * <meta * http-equiv="content-security-policy" * content=" * script-src 'self' 'sha256-somehash'; * style-src 'self' 'sha256-somehash'; * " * > * </head> * ``` * * You can further customize the `<meta>` element by enabling this feature with a configuration object that includes additional options. */ csp?: boolean | { /** * @docs * @name security.csp.algorithm * @kind h5 * @type {"SHA-256" | "SHA-384" | "SHA-512"} * @default `'SHA-256'` * @version 6.0.0 * @description * * The [hash function](https://developer.mozilla.org/en-US/docs/Glossary/Hash_function) to use when generating the hashes of the styles and scripts emitted by Astro. * * ```js title="astro.config.mjs" * import { defineConfig } from 'astro/config'; * * export default defineConfig({ * security: { * csp: { * algorithm: 'SHA-512' * } * } * }); * ``` */ algorithm?: CspAlgorithm; /** * @docs * @name security.csp.directives * @kind h5 * @type {string[]} * @default `[]` * @version 6.0.0 * @description * * A list of [CSP directives](https://content-security-policy.com/#directive) (beyond `script-src` and `style-src` which are included by default) that defines valid sources for specific content types. These directives are added to all pages. * * ```js title="astro.config.mjs" * import { defineConfig } from 'astro/config'; * * export default defineConfig({ * security: { * csp: { * directives: [ * "default-src 'self'", * "img-src 'self' https://images.cdn.example.com" * ] * } * } * }); * ``` * After the build, the `<meta>` element will add your directives into the `content` value alongside Astro's default directives: * * ```html * <meta * http-equiv="content-security-policy" * content=" * default-src 'self'; * img-src 'self' 'https://images.cdn.example.com'; * script-src 'self' 'sha256-somehash'; * style-src 'self' 'sha256-somehash'; * " * > * ``` */ directives?: CspDirective[]; /** * @docs * @name security.csp.styleDirective * @kind h5 * @type {CspStyleDirective} * @default `undefined` * @version 6.0.0 * @description * * A configuration object that allows you to override the default sources for the `style-src` directive with the [`resources`](https://docs.astro.build/en/reference/configuration-reference/#securitycspstyledirectiveresources) property, or to provide additional [hashes](https://docs.astro.build/en/reference/configuration-reference/#securitycspstyledirectivehashes) to be rendered. */ styleDirective?: { /** * @docs * @name security.csp.styleDirective.hashes * @kind h6 * @type {CspHashEntry[]} * @default `[]` * @version 6.0.0 * @description * * A list of additional hashes to be rendered. * * You must provide hashes that start with `sha384-`, `sha512-` or `sha256-`. Other values will cause a validation error. These hashes are added to all pages. * * Since Astro v7.1, each entry can be a string or an object. The object allows changing the scope of the hash via the `kind` field. The `kind` field accepts: * - `"element"`: it will store the hash in the `style-src-elem` directive * - `"attribute"`: it will store the hash in the `style-src-attr` directive * - `"default"`: it will store the hash in the `style-src` directive * * A `"default"` hash goes on `style-src`, or on `style-src-elem` instead once you use `kind: "element"`. It is never added to `style-src-attr`. Astro's generated hashes follow the same rule. * * ```js title="astro.config.mjs" * import { defineConfig } from 'astro/config'; * * export default defineConfig({ * security: { * csp: { * styleDirective: { * hashes: [ * "sha384-styleHash", * "sha512-styleHash", * "sha256-styleHash" * ] * } * } * } * }); * ``` * * After the build, the `<meta>` element will include your additional hashes in the `style-src` directives: * * ```html * <meta * http-equiv="content-security-policy" * content=" * style-src 'self' 'sha384-styleHash' 'sha512-styleHash' 'sha256-styleHash' 'sha256-generatedByAstro'; * " * > * ``` * * Scoping a hash to `"element"` stores it in `style-src-elem` instead. Astro's generated hashes move there too: * * ```js title="astro.config.mjs" * import { defineConfig } from 'astro/config'; * * export default defineConfig({ * security: { * csp: { * styleDirective: { * hashes: [{ hash: "sha256-styleHash", kind: "element" }] * } * } * } * }); * ``` * * After the build, the `<meta>` element will include the hash in the `style-src-elem` directive instead of `style-src`: * * ```html * <meta * http-equiv="content-security-policy" * content=" * style-src 'self'; * style-src-elem 'self' 'sha256-styleHash' 'sha256-generatedByAstro'; * " * > * ``` */ hashes?: CspHashEntry[]; /** * @docs * @name security.csp.styleDirective.resources * @kind h6 * @type {CspResourceEntry[]} * @default `[]` * @version 6.0.0 * @description * * A list of valid sources for `style-src` directives to override Astro's default sources. This will not include `'self'` by default, and must be included in this list if you wish to keep it. These resources are added to all pages. * * Since Astro v7.1, each entry can be a string or an object. The object allows changing the scope of the source via the `kind` field. The `kind` field accepts: * - `"element"`: it will store the source in the `style-src-elem` directive * - `"attribute"`: it will store the source in the `style-src-attr` directive * - `"default"`: it will store the source in the `style-src` directive * * `"attribute"` sources must be one of `'none'`, `'unsafe-hashes'`, `'unsafe-inline'`, or `'report-sample'`, and `'unsafe-hashes'` cannot be used with `"element"`. A common use is allowing inline `style` attributes (for example, from `define:vars` or Shiki) with `{ resource: "'unsafe-inline'", kind: "attribute" }`. * * Unlike a hash, a `"default"` source is never moved: it stays on `style-src` only. Where there is a mix of "default" and specific resources (e.g. `"element"` or `"attribute"`), Astro emits a warning. * * ```js title="astro.config.mjs" * import { defineConfig } from 'astro/config'; * * export default defineConfig({ * security: { * csp: { * styleDirective: { * resources: [ * "'self'", * "https://styles.cdn.example.com" * ] * } * } * } * }); * ``` * * After the build, the `<meta>` element will instead apply your sources to the `style-src` directives: * * ```html * <head> * <meta * http-equiv="content-security-policy" * content=" * style-src 'self' https://styles.cdn.example.com 'sha256-somehash'; * " * > * </head> * ``` * * A `"default"` source is not copied into the more specific directives. Here, a `"default"` source and an `"element"` source render in different directives: * * ```js title="astro.config.mjs" * import { defineConfig } from 'astro/config'; * * export default defineConfig({ * security: { * csp: { * styleDirective: { * resources: [ * "https://styles.cdn.example.com", * { resource: "https://elements.cdn.example.com", kind: "element" } * ] * } * } * } * }); * ``` * * After the build, the `<meta>` element keeps `https://styles.cdn.example.com` on `style-src` only. This means that this value is not added to `style-src-elem` and does not apply to `<style>` and `<link>` elements (the generated hash, by contrast, does move there): * * ```html * <meta * http-equiv="content-security-policy" * content=" * style-src https://styles.cdn.example.com; * style-src-elem https://elements.cdn.example.com 'sha256-generatedByAstro'; * " * > * ``` * * When resources are inserted multiple times or from multiple sources (e.g. defined in your `csp` config and added using [the CSP runtime API](/en/reference/api-reference/#csp)), Astro will merge and deduplicate all resources to create your `<meta>` element. */ resources?: CspResourceEntry[]; }; /** * @docs * @name security.csp.scriptDirective * @kind h5 * @type {CspScriptDirective} * @default `undefined` * @version 6.0.0 * @description * * A configuration object that allows you to override the default sources for the `script-src` directive with the [`resources`](https://docs.astro.build/en/reference/configuration-reference/#securitycspscriptdirectiveresources) property, or to provide additional [hashes](https://docs.astro.build/en/reference/configuration-reference/#securitycspscriptdirectivehashes) to be rendered. */ scriptDirective?: { /** * @docs * @name security.csp.scriptDirective.hashes * @kind h6 * @type {CspHashEntry[]} * @default `[]` * @version 6.0.0 * @description * * A list of additional hashes to be rendered. * * You must provide hashes that start with `sha384-`, `sha512-` or `sha256-`. Other values will cause a validation error. These hashes are added to all pages. * * Since Astro v7.1, each entry can be a string or an object. The object allows changing the scope of the hash via the `kind` field. The `kind` field accepts: * - `"element"`: it will store the hash in the `script-src-elem` directive * - `"attribute"`: it will store the hash in the `script-src-attr` directive * - `"default"`: it will store the hash in the `script-src` directive * * A `"default"` hash goes on `script-src`, or on `script-src-elem` instead once you use `kind: "element"`. It is never added to `script-src-attr`. Astro's generated hashes follow the same rule. * * ```js title="astro.config.mjs" * import { defineConfig } from 'astro/config'; * * export default defineConfig({ * security: { * csp: { * scriptDirective: { * hashes: [ * "sha384-scriptHash", * "sha512-scriptHash", * "sha256-scriptHash" * ] * } * } * } * }); * ``` * * After the build, the `<meta>` element will include your additional hashes in the `script-src` directives: * * ```html * <meta * http-equiv="content-security-policy" * content=" * script-src 'self' 'sha384-scriptHash' 'sha512-scriptHash' 'sha256-scriptHash' 'sha256-generatedByAstro'; * " * > * ``` * * Scoping a hash to `"element"` stores it in `script-src-elem` instead. Astro's generated hashes move there too: * * ```js title="astro.config.mjs" * import { defineConfig } from 'astro/config'; * * export default defineConfig({ * security: { * csp: { * scriptDirective: { * hashes: [{ hash: "sha256-scriptHash", kind: "element" }] * } * } * } * }); * ``` * * After the build, the `<meta>` element will include the hash in the `script-src-elem` directive instead of `script-src`: * * ```html * <meta * http-equiv="content-security-policy" * content=" * script-src 'self'; * script-src-elem 'self' 'sha256-scriptHash' 'sha256-generatedByAstro'; * " * > * ``` */ hashes?: CspHashEntry[]; /** * @docs * @name security.csp.scriptDirective.resources * @kind h6 * @type {CspResourceEntry[]} * @default `[]` * @version 6.0.0 * @description * * A list of valid sources for the `script-src` directives to override Astro's default sources. This will not include `'self'` by default, and must be included in this list if you wish to keep it. These resources are added to all pages. * * Since Astro v7.1, each entry can be a string or an object. The object allows changing the scope of the source via the `kind` field. The `kind` field accepts: * - `"element"`: it will store the source in the `script-src-elem` directive * - `"attribute"`: it will store the source in the `script-src-attr` directive * - `"default"`: it will store the source in the `script-src` directive * * `"attribute"` sources must be one of `'none'`, `'unsafe-hashes'`, `'unsafe-inline'`, or `'report-sample'`, and `'unsafe-hashes'` cannot be used with `"element"`. * * Unlike a hash, a `"default"` source is never moved and stays on `script-src` only. This does not apply where you also scope `"element"` or `"attribute"` sources, since browsers do not fall back. Astro warns when this happens. Add it to the more specific directive as well, if necessary. * * ```js title="astro.config.mjs" * import { defineConfig } from 'astro/config'; * * export default defineConfig({ * security: { * csp: { * scriptDirective: { * resources: [ * "'self'", "https://cdn.example.com" * ] * } * } * } * }); * ``` * * After the build, the `<meta>` element will instead apply your sources to the `script-src` directives: * * ```html * <head> * <meta * http-equiv="content-security-policy" * content=" * script-src 'self' https://cdn.example.com 'sha256-somehash'; * " * > * </head> * ``` * * A `"default"` source is not copied into the more specific directives. Here, a `"default"` source and an `"element"` source render in different directives: * * ```js title="astro.config.mjs" * import { defineConfig } from 'astro/config'; * * export default defineConfig({ * security: { * csp: { * scriptDirective: { * resources: [ * "https://cdn.example.com", * { resource: "https://elements.cdn.example.com", kind: "element" } * ] * } * } * } * }); * ``` * * After the build, the `<meta>` element keeps `https://cdn.example.com` on `script-src` only. This means that this value is not added to `script-src-elem` and does not apply to `<script>` elements (the generated hash, by contrast, does move there): * * ```html * <meta * http-equiv="content-security-policy" * content=" * script-src https://cdn.example.com; * script-src-elem https://elements.cdn.example.com 'sha256-generatedByAstro'; * " * > * ``` * * When resources are inserted multiple times or from multiple sources (e.g. defined in your `csp` config and added using [the CSP runtime API](/en/reference/api-reference/#csp)), Astro will merge and deduplicate all resources to create your `<meta>` element. */ resources?: CspResourceEntry[]; /** * @docs * @name security.csp.scriptDirective.strictDynamic * @kind h6 * @type {boolean} * @default `false` * @version 6.0.0 * @description * * Enables [the `strict-dynamic` keyword](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP#the_strict-dynamic_keyword) to support the dynamic injection of scripts. * * ```js title="astro.config.mjs" * import { defineConfig } from 'astro/config'; * * export default defineC