---
title: CSP Provider
subtitle: Configures CSP-related behavior for inline tags rendered by Base UI components.
description: A CSP provider component that applies a nonce to inline <style> and <script> tags rendered by Base UI components, and can disable inline <style> elements.
---

> FineSoft Components documentation. Independent Stencil port; not the official Base UI website.
>
> React API text and `@base-ui/react` examples are upstream references. FineSoft Stencil examples use `finesoft-components`. Do not treat the two packages as interchangeable.

# CSP Provider

A CSP provider component that applies a nonce to inline \<style> and \<script> tags rendered by Base UI components, and can disable inline \<style> elements.

## Demo

### CSS Modules

This example shows how to implement the component using CSS Modules.

```css
/* index.module.css */
.Example {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  width: 16rem;
  color: oklch(14.5% 0 0deg);

  @media (prefers-color-scheme: dark) {
    color: white;
  }
}
.Label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
}
.Root {
  height: 10rem;
  width: 100%;
  box-sizing: border-box;
  border: 1px solid oklch(14.5% 0 0deg);
  background-color: white;

  @media (prefers-color-scheme: dark) {
    border-color: white;
    background-color: oklch(14.5% 0 0deg);
  }
}
.Viewport {
  width: 100%;
  height: 100%;
  overscroll-behavior: contain;
}
.Content {
  padding: 0.75rem;
}
.Content p {
  margin: 0 0 1rem;
}
.Scrollbar {
  display: flex;
  width: 0.25rem;
  margin: 0.5rem;
  opacity: 0;
  transition: opacity 150ms;
}
.Scrollbar[data-hovering],
.Scrollbar[data-scrolling] {
  opacity: 1;
}
.Thumb {
  width: 100%;
  background-color: oklch(14.5% 0 0deg);
  border-radius: 0.25rem;

  @media (prefers-color-scheme: dark) {
    background-color: white;
  }
}
```

```tsx
/* docs-comparison.tsx */
import { StencilComparison } from 'docs/src/components/StencilComparison';
import ReactExample from './react-csp-provider';
import StencilExample from './stencil-csp-provider';
import { StencilCspView } from './stencil-csp-view';
export default function Comparison() {
  return <StencilComparison component="csp-provider" react={<ReactExample />} stencil={<StencilCspView disabled={false} />} clientStencil={<StencilExample />} />;
}
```

```tsx
/* react-csp-provider.tsx */
'use client';
import * as React from 'react';
import { CSPProvider } from '@base-ui/react/csp-provider';
import { ScrollArea } from '@base-ui/react/scroll-area';
import styles from './index.module.css';

export default function ReactCspProvider() {
  const [disabled, setDisabled] = React.useState(false);
  return (
    <div className={styles.Example}>
      <label className={styles.Label}>
        <input type="checkbox" checked={disabled} onChange={event => setDisabled(event.target.checked)} />
        Disable style elements
      </label>
      <CSPProvider nonce="demo-nonce" disableStyleElements={disabled}>
        <ScrollArea.Root className={styles.Root}>
          <ScrollArea.Viewport className={styles.Viewport}>
            <ScrollArea.Content className={styles.Content}>
              {[
                'Components can attach a nonce to the styles they generate.',
                'Scroll this content to see the custom scrollbar.',
                'Disable style elements to supply these rules in your own stylesheet.',
                'Nested providers configure their own subtree.',
              ].map(text => (
                <p key={text}>{text}</p>
              ))}
            </ScrollArea.Content>
          </ScrollArea.Viewport>
          <ScrollArea.Scrollbar className={styles.Scrollbar}>
            <ScrollArea.Thumb className={styles.Thumb} />
          </ScrollArea.Scrollbar>
        </ScrollArea.Root>
      </CSPProvider>
    </div>
  );
}
```

```tsx
/* stencil-csp-provider.tsx */
'use client';
import * as React from 'react';
import { StencilCspView } from './stencil-csp-view';
export default function StencilCspProvider() {
  const [disabled, setDisabled] = React.useState(false);
  return <StencilCspView disabled={disabled} onChange={setDisabled} />;
}
```

```tsx
/* stencil-csp-view.tsx */
import './stencil.css';

export function StencilCspView({ disabled, onChange }: { disabled: boolean; onChange?: (value: boolean) => void }) {
  return (
    <div className="demo-utils-csp-provider-hero-example">
      <label className="demo-utils-csp-provider-hero-label">
        <input type="checkbox" checked={disabled} onChange={event => onChange?.(event.target.checked)} />
        Disable style elements
      </label>
      <fs-csp-provider-root nonce="demo-nonce" disableStyleElements={disabled}>
        <fs-scroll-area-root data-fs-variant="panel">
          <fs-scroll-area-viewport>
            <fs-scroll-area-content>
              {[
                'Components can attach a nonce to the styles they generate.',
                'Scroll this content to see the custom scrollbar.',
                'Disable style elements to supply these rules in your own stylesheet.',
                'Nested providers configure their own subtree.',
              ].map(text => (
                <p key={text}>{text}</p>
              ))}
            </fs-scroll-area-content>
          </fs-scroll-area-viewport>
          <fs-scroll-area-scrollbar>
            <fs-scroll-area-thumb />
          </fs-scroll-area-scrollbar>
        </fs-scroll-area-root>
      </fs-csp-provider-root>
    </div>
  );
}
```

```css
/* stencil.css */
/* Example layout and visual exceptions. Default component styles come from the theme. */
@layer fs-theme {
  .demo-utils-csp-provider-hero-example {
    display: flex;
    flex-direction: column;
    gap: var(--fs-space-4);
    width: 16rem;
    --fs-scroll-area-width: 100%;
    --fs-scroll-area-height: 10rem;
    color: var(--fs-color-foreground);
  }
  .demo-utils-csp-provider-hero-label {
    display: flex;
    align-items: center;
    gap: var(--fs-space-2);
    font-size: var(--fs-font-size-sm);
  }
  .demo-utils-csp-provider-hero-example p {
    margin: 0 0 var(--fs-space-4);
  }
}
```

## Anatomy

Import the component and wrap it around your app:

```jsx title="Anatomy"
import { CSPProvider } from '@base-ui/react/csp-provider';

// prettier-ignore
<CSPProvider nonce="...">
  {/* Your app or a group of components */}
</CSPProvider>
```

Some Base UI components render inline `<style>` or `<script>` tags for functionality such as removing scrollbars or pre-hydration behavior. Under a strict Content Security Policy (CSP), these tags may be blocked unless they include a matching [nonce](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/nonce) attribute.

`CSPProvider` allows configuring this behavior globally for all Base UI components within its tree.

## Supplying a nonce

If you enforce a CSP that blocks inline tags by default, configure your server to:

1. Generate a random nonce per request
2. Include it in your CSP header (via `style-src-elem`/`script-src`)
3. Pass the same nonce into `CSPProvider` during rendering

```ts title="Example"
const nonce = crypto.randomUUID();

// Example CSP header
const csp = [`default-src 'self'`, `script-src 'self' 'nonce-${nonce}'`, `style-src-elem 'self' 'nonce-${nonce}'`].join('; ');
```

Then:

```jsx title="Providing the nonce"
import { CSPProvider } from '@base-ui/react/csp-provider';

function App({ nonce }) {
  return <CSPProvider nonce={nonce}>{/* ... */}</CSPProvider>;
}
```

This will ensure that all inline `<style>` and `<script>` tags rendered by Base UI components include the correct nonce attribute, allowing them to function under your CSP.

## Disable inline style elements

You can avoid supplying a `nonce` if you disable inline `<style>` elements entirely and rely on external stylesheets only. The relevant components are `<ScrollArea.Viewport>` and `<Select.Popup>` or `<Select.List>` when `alignItemWithTrigger` is enabled, which inject a style tag to disable native scrollbars.

```html
<style>
  .base-ui-disable-scrollbar {
    scrollbar-width: none;
  }
  .base-ui-disable-scrollbar::-webkit-scrollbar {
    display: none;
  }
</style>
```

Specify `disableStyleElements` to remove these tags:

```jsx title="Disabling style elements"
<CSPProvider disableStyleElements>{/* ... */}</CSPProvider>
```

`<script>` tags across all components are opt-in, so they are not affected by this prop and don't have their own disable flag. A `nonce` is required if any component uses inline scripts.

## Inline style attributes

`CSPProvider` covers inline `<style>` and `<script>` tags rendered as elements, but it does not cover inline style attributes (for example, `<div style="...">`). The `style-src-attr` directive in CSP governs inline style attributes encountered when parsing HTML from server pre-rendered components (it does not affect client-side JavaScript that sets styles).

In CSP, `style-src` applies to both `<style>` elements and `style=""` attributes. If you only want to control `<style>` elements, use `style-src-elem` instead.

If your CSP blocks inline style _attributes_ in addition to _elements_, you have a few options:

1. Relax your CSP by adding `'unsafe-inline'` to the `style-src-attr` directive (or using only `style-src-elem` instead of `style-src`). Style attributes specifically pose a less severe security risk than style elements, but this approach may not be acceptable in high-security environments.
2. Render the affected components only on the client, so that no inline styles are present in the initial HTML.
3. Manually unset inline styles and specify them in your CSS instead. Any component can have its inline styles unset, such as `<ScrollArea.Viewport style={{ overflow: undefined  }}>`. Note that you'll need to ensure you vet upgrades for any new inline styles added by Base UI components.

## Stencil API

The Stencil provider is `fs-csp-provider-root`. Import the automatic registration entry, or call `defineCustomElements()` from `finesoft-components/define-custom-elements` before using the elements.

```html
<fs-csp-provider-root nonce="request-nonce" disable-style-elements="false">
  <fs-scroll-area-root><!-- Scroll Area parts --></fs-scroll-area-root>
</fs-csp-provider-root>
```

| Property               | HTML attribute           | Default     |
| ---------------------- | ------------------------ | ----------- |
| `nonce`                | `nonce`                  | `undefined` |
| `disableStyleElements` | `disable-style-elements` | `false`     |

The nearest provider replaces the complete configuration. A nested provider with no props enables style elements without inheriting the outer nonce. Portals retain their declaration scope. `useCSPContext(element)` reads the current configuration for custom consumers.

Like the frozen React style resource, the scrollbar stylesheet is emitted once per document or shadow root and remains after its consumers unmount. The first emission determines its nonce. `disableStyleElements` prevents emission; changing it later does not remove an existing shared stylesheet. Set the request nonce and disable flag before mounting consumers.

This provider configures the optional scrollbar `<style>` tags in Scroll Area and Select and the opt-in Tabs Indicator prehydration script. It leaves native `style` attributes unchanged. When disabling these tags, put the `.base-ui-disable-scrollbar` rules above in an external stylesheet.

Stencil also installs global component layout styles. Configure their nonce separately, before registration, with `<meta name="csp-nonce" content="request-nonce">` or `setNonce(requestNonce)` from `finesoft-components/define-custom-elements`. Use the same request nonce in your CSP response header. A nested provider does not change the document-wide Stencil runtime nonce.

## API reference

### CSPProvider

Provides a default Content Security Policy (CSP) configuration for Base UI components that
require inline `<style>` or `<script>` tags.

**CSPProvider Props:**

| Prop                 | Type              | Default | Description                                                                                                                                                                      |
| :------------------- | :---------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| disableStyleElements | `boolean`         | `false` | Whether inline `<style>` elements created by Base UI components should not be rendered. Instead, components must specify the CSS styles via custom class names or other methods. |
| nonce                | `string`          | -       | The nonce value to apply to inline `<style>` and `<script>` tags.                                                                                                                |
| children             | `React.ReactNode` | -       | -                                                                                                                                                                                |

### CSPProvider.Props

Re-export of [CSPProvider](/react/utils/csp-provider.md) props.

### CSPProvider.State

```typescript
type CSPProviderState = {};
```

## Canonical Types

Maps `Canonical`: `Alias` — Use Canonical when its namespace is already imported; otherwise use Alias.

- `CSPProvider.State`: `CSPProviderState`
- `CSPProvider.Props`: `CSPProviderProps`
