diff --git a/src/compile/render-dom/index.ts b/src/compile/render-dom/index.ts
index a6ef0ac69c..eede9d2aa0 100644
--- a/src/compile/render-dom/index.ts
+++ b/src/compile/render-dom/index.ts
@@ -22,6 +22,8 @@ export default function dom(
block.has_outro_method = true;
+ const should_use_shadow_dom = options.customElement && options.shadowDom !== false;
+
// prevent fragment being created twice (#1063)
if (options.customElement) block.builders.create.add_line(`this.c = @noop;`);
@@ -64,7 +66,7 @@ export default function dom(
// TODO injecting CSS this way is kinda dirty. Maybe it should be an
// explicit opt-in, or something?
const should_add_css = (
- !options.customElement &&
+ !should_use_shadow_dom &&
component.stylesheet.has_styles &&
options.css !== false
);
@@ -445,8 +447,9 @@ export default function dom(
constructor(options) {
super();
- ${css.code && `this.shadowRoot.innerHTML = \`\`;`}
+ ${css.code && should_use_shadow_dom && `this.shadowRoot.innerHTML = \`\`;`}
+ // TODO: Figure out what target should point to
@init(this, { target: this.shadowRoot }, ${definition}, create_fragment, ${not_equal}, ${prop_names});
${dev_props_check}
diff --git a/src/interfaces.ts b/src/interfaces.ts
index fd34f31ea1..806ef43e2d 100644
--- a/src/interfaces.ts
+++ b/src/interfaces.ts
@@ -54,6 +54,7 @@ export interface CompileOptions {
hydratable?: boolean;
legacy?: boolean;
customElement?: boolean;
+ shadowDom?: boolean;
tag?: string;
css?: boolean;
diff --git a/src/internal/Component.js b/src/internal/Component.js
index 530a48da59..6c0dfc0dfa 100644
--- a/src/internal/Component.js
+++ b/src/internal/Component.js
@@ -117,7 +117,9 @@ if (typeof HTMLElement !== 'undefined') {
SvelteElement = class extends HTMLElement {
constructor() {
super();
- this.attachShadow({ mode: 'open' });
+ if (options.shadowDom !== false) {
+ this.attachShadow({ mode: 'open' });
+ }
}
connectedCallback() {