Skip to content

feat: add nonce prop for CSP-compliant user-select style injection#808

Merged
STRML merged 1 commit into
masterfrom
feat/csp-nonce
Jun 18, 2026
Merged

feat: add nonce prop for CSP-compliant user-select style injection#808
STRML merged 1 commit into
masterfrom
feat/csp-nonce

Conversation

@STRML

@STRML STRML commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

The user-select hack injects a <style> element into the document <head> on drag start (enableUserSelectHack, on by default). Under a strict Content Security Policy that omits 'unsafe-inline' from style-src, the browser blocks that element and logs a violation.

This was raised in #791 and the follow-up comment 4743333644. The workaround offered there (pre-inject the element server-side) is awkward for client-only apps, which is the gap this closes.

This PR adds first-class CSP support:

  • New optional nonce?: string prop on DraggableCore. It's inherited by Draggable (which spreads undestructured props through) and flows to addUserSelectStyles, which applies it via setAttribute('nonce', ...).
  • When no nonce is passed, fall back to webpack's __webpack_nonce__ global when defined — read behind a typeof guard so non-webpack bundlers don't throw. This is the same convention styled-components / emotion use, and means most webpack users need zero config.
  • The nonce is applied only when the element is first created, preserving the existing skip-if-already-present behavior.
  • README documents the prop, the __webpack_nonce__ fallback, and enableUserSelectHack={false} as a no-prop opt-out.

Because react-resizable already spreads draggableOpts onto DraggableCore, its users get this for free via draggableOpts={{ nonce }} once this ships — no change needed there.

Test plan

  • yarn typecheck — clean
  • yarn lint — clean
  • yarn test — 204 passing, including 7 new tests:
    • addUserSelectStyles: no nonce by default, explicit nonce applied, not retroactively applied to an existing element, __webpack_nonce__ fallback, explicit-over-global precedence
    • DraggableCore: nonce reaches the injected element on a real drag start
  • yarn build — generated cjs/umd preserve the typeof __webpack_nonce__ reference (not mangled by esbuild) and public .d.ts exposes nonce?: string

Closes #791

The user-select hack injects a <style> element into the document head on
drag start. Under a strict Content Security Policy (style-src without
'unsafe-inline') the browser blocks it and logs a violation. This was
raised in #791 and the follow-up discussion (comment 4743333644), where
the only workaround offered required pre-injecting the element server-side
— awkward for client-only apps.

Add an optional nonce prop on DraggableCore (inherited by Draggable and
flowed through to addUserSelectStyles). When set, it's applied to the
injected element via setAttribute('nonce', ...). When omitted, fall back
to webpack's __webpack_nonce__ global if defined, read defensively behind
a typeof guard so non-webpack bundlers don't throw. The nonce is applied
only when the element is first created, preserving the existing
skip-if-present behavior.

Also documents enableUserSelectHack={false} as the no-prop opt-out.

Closes #791
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 187ac825-8e3f-4fc0-bb44-ce691db34e70

📥 Commits

Reviewing files that changed from the base of the PR and between 721287a and 9da7914.

📒 Files selected for processing (5)
  • README.md
  • lib/DraggableCore.tsx
  • lib/utils/domFns.ts
  • test/DraggableCore.test.jsx
  • test/utils/domFns.extra.test.js
 __________________________________
< Pretty fly for a code review AI. >
 ----------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/csp-nonce

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@STRML STRML merged commit 5611b11 into master Jun 18, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant