Skip to content

feat: support CSP nonce on injected style elements#9655

Open
costajohnt wants to merge 2 commits intoadobe:mainfrom
costajohnt:fix/csp-nonce-usepress-8273
Open

feat: support CSP nonce on injected style elements#9655
costajohnt wants to merge 2 commits intoadobe:mainfrom
costajohnt:fix/csp-nonce-usepress-8273

Conversation

@costajohnt
Copy link

Summary

Fixes #8273

Adds CSP nonce support to dynamically injected <style> elements in usePress and usePreventScroll. Without a nonce, these inline styles are blocked by strict Content Security Policy headers.

Approach

Following the approach suggested by @devongovett, this PR adds a getNonce() utility that reads the nonce from existing pseudo-standards:

function getNonce(): string | undefined {
  let meta = document.querySelector('meta[property="csp-nonce"]');
  return meta?.nonce || meta?.content || globalThis['__webpack_nonce__'];
}

This automatically works with:

  • Vite — via html.cspNonce config (injects <meta property="csp-nonce">)
  • webpack — via the __webpack_nonce__ global
  • Any framework — that adds <meta property="csp-nonce" content="..."> to the document head

Changes

  • @react-aria/utils: Added getNonce() utility + export
  • @react-aria/interactions: Applied nonce to the <style> element in usePress
  • @react-aria/overlays: Applied nonce to the <style> element in usePreventScroll

Test plan

  • Added 5 unit tests for getNonce() covering: no config, meta nonce attribute, meta content attribute, webpack global, precedence
  • All existing usePress tests pass (90/90)
  • All existing overlay tests pass (191/191)

@github-actions github-actions bot added the RAC label Feb 13, 2026
Add getNonce() utility that reads CSP nonce from <meta property="csp-nonce">
or __webpack_nonce__, and apply it to <style> elements injected by usePress
and usePreventScroll. This fixes CSP violations when a strict style-src
directive is in effect.

Fixes adobe#8273
@costajohnt costajohnt force-pushed the fix/csp-nonce-usepress-8273 branch from fece367 to 72626e4 Compare February 13, 2026 16:41
@costajohnt costajohnt marked this pull request as ready for review February 13, 2026 16:41
Copy link
Member

@reidbarber reidbarber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

  1. I think we can add globalThis: "readonly" to the languageOptions.globals in eslint.config.mjs (at line 460) to fix the lint step failing.
  2. You also need to sign the CLA, then close and re-open the PR and the build should pass.

The .js test file was missing globalThis in ESLint globals since
the TypeScript config block (which declares it) only applies to
.ts/.tsx files. This resolves the no-undef lint failure.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

usePress style insertion is blocked and logging an error when a strict CSP directive is in effect

2 participants