Conversation
There was a problem hiding this comment.
Pull request overview
Adds first-class support for running Dockview under strict Content Security Policy (CSP) configurations by allowing callers to provide a CSP nonce for the <style> elements created during popout window style replication, and updates documentation/testing accordingly.
Changes:
- Introduces a
nonceoption (CspNonce) onDockviewOptionsand wires it through popout window style injection. - Updates DOM utilities to apply the nonce to generated
<style>elements and batches style insertions via aDocumentFragment. - Replaces
innerHTML = ''withreplaceChildren()in the tab group indicator and adds a new “Content Security Policy” docs page plus unit tests foraddStyles.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/docs/docs/advanced/csp.mdx | New documentation page describing strict CSP setup, nonce wiring, and Trusted Types notes. |
| packages/dockview-core/src/popoutWindow.ts | Threads nonce into addStyles when copying styles into popout windows. |
| packages/dockview-core/src/dom.ts | Adds CspNonce/AddStylesOptions and applies nonce to created <style> elements. |
| packages/dockview-core/src/dockview/options.ts | Adds nonce?: CspNonce to DockviewOptions and re-exports CspNonce. |
| packages/dockview-core/src/dockview/dockviewComponent.ts | Passes nonce from Dockview options into PopoutWindowOptions. |
| packages/dockview-core/src/dockview/components/titlebar/tabGroupIndicator.ts | Uses replaceChildren() instead of innerHTML = '' for Trusted Types compatibility. |
| packages/dockview-core/src/tests/dom.spec.ts | Adds unit tests covering addStyles nonce behavior and ordering behavior. |
| packages/dockview-angular/src/lib/dockview/dockview-angular.component.ts | Exposes nonce as an Angular @Input() and forwards it via PROPERTY_KEYS_DOCKVIEW. |
| generated/dockview-core-exports.txt | Updates generated export surface to include CspNonce. |
Files not reviewed (1)
- generated/dockview-core-exports.txt: Language not supported
Comments suppressed due to low confidence (1)
packages/dockview-core/src/dom.ts:235
- In
addStyles, whenstyleSheet.hrefis present you always append a<link>and then still fall through to readcssRulesand inject<style>elements for the same sheet. That can duplicate rules (and potentially trigger extra/incorrect asset URL fetches) and also logs warnings for cross-origin sheets even though the<link>path is sufficient. Considercontinue-ing after appending the link, or only appending a link as a fallback whencssRulesaccess fails.
if (styleSheet.href) {
const link = document.createElement('link');
link.href = styleSheet.href;
link.type = styleSheet.type;
link.rel = 'stylesheet';
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - `RANDOM_NONCE` must be regenerated per response. It should be the same nonce that your server-rendered HTML applies to its own `<script>` / `<style>` tags. | ||
| - If your popout is same-origin (the default for `window.open(url)` where `url` is on your origin), the popout document inherits your CSP and nonce, so the same nonce works for both windows. | ||
|
|
There was a problem hiding this comment.
The note that a same-origin popout "inherits your CSP and nonce" is misleading/incorrect for window.open(url, ...) (as used in PopoutWindow): the popout is a separate HTTP response with its own CSP header and per-response nonce, so the opener's nonce generally won’t be valid there. This also contradicts the later explanation that popout.html has its own freshly-generated nonce.
Hey! Thanks for the great library — I'm running it on a project with strict CSP, and saw a good opportunity to land first-class support for it.
Adds a
nonceoption to DockviewOptions (and the React, Vue and Angular wrappers) so Dockview works under a CSP that forbidsstyle-src 'unsafe-inline'. The nonce is applied to the<style>elements created when the parent window's stylesheets are copied into a popout. It accepts a string or a(targetDocument) => string | undefinedfunction — the function form is what you want in production, since the popout is a separate response with its own fresh nonce and usually exposes it via<meta name="csp-nonce">.Also swaps two
innerHTML = ''calls in tabGroupIndicator forreplaceChildren()so the library is compatible withrequire-trusted-types-for 'script'. New "Content Security Policy" page under Advanced covers the header, nonce wiring, and Trusted Types note.Let me know what you think!