diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts index 9378d7219..70af88ed4 100644 --- a/packages/runtime-dom/__tests__/customElement.spec.ts +++ b/packages/runtime-dom/__tests__/customElement.spec.ts @@ -718,6 +718,23 @@ describe('defineCustomElement', () => { await nextTick() assertStyles(el, [`div { color: blue; }`, `div { color: red; }`]) }) + + test('with nonce', () => { + const Foo = defineCustomElement( + { + styles: [`div { color: red; }`], + render() { + return h('div', 'hello') + }, + }, + { nonce: 'xxx' }, + ) + customElements.define('my-el-with-nonce', Foo) + container.innerHTML = `` + const el = container.childNodes[0] as VueElement + const style = el.shadowRoot?.querySelector('style')! + expect(style.getAttribute('nonce')).toBe('xxx') + }) }) describe('async', () => { diff --git a/packages/runtime-dom/src/apiCustomElement.ts b/packages/runtime-dom/src/apiCustomElement.ts index 964f43441..6aa40c833 100644 --- a/packages/runtime-dom/src/apiCustomElement.ts +++ b/packages/runtime-dom/src/apiCustomElement.ts @@ -48,6 +48,7 @@ export type VueElementConstructor

= { export interface CustomElementOptions { styles?: string[] shadowRoot?: boolean + nonce?: string } // defineCustomElement provides the same type inference as defineComponent @@ -513,8 +514,10 @@ export class VueElement } this._styleChildren.add(owner) } + const nonce = this._def.nonce for (let i = styles.length - 1; i >= 0; i--) { const s = document.createElement('style') + if (nonce) s.setAttribute('nonce', nonce) s.textContent = styles[i] this.shadowRoot!.prepend(s) // record for HMR