diff --git a/.changeset/wise-hairs-pay.md b/.changeset/wise-hairs-pay.md
new file mode 100644
index 0000000000..7d96c1daab
--- /dev/null
+++ b/.changeset/wise-hairs-pay.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: always inject styles when compiling as a custom element
diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js
index d407b44556..cd44fd998a 100644
--- a/packages/svelte/src/compiler/phases/2-analyze/index.js
+++ b/packages/svelte/src/compiler/phases/2-analyze/index.js
@@ -451,6 +451,8 @@ export function analyze_component(root, source, options) {
}
}
+ const is_custom_element = !!options.customElementOptions || options.customElement;
+
// TODO remove all the ?? stuff, we don't need it now that we're validating the config
/** @type {ComponentAnalysis} */
const analysis = {
@@ -500,13 +502,13 @@ export function analyze_component(root, source, options) {
needs_props: false,
event_directive_node: null,
uses_event_attributes: false,
- custom_element: options.customElementOptions ?? options.customElement,
- inject_styles: options.css === 'injected' || options.customElement,
- accessors: options.customElement
- ? true
- : (runes ? false : !!options.accessors) ||
- // because $set method needs accessors
- options.compatibility?.componentApi === 4,
+ custom_element: is_custom_element,
+ inject_styles: options.css === 'injected' || is_custom_element,
+ accessors:
+ is_custom_element ||
+ (runes ? false : !!options.accessors) ||
+ // because $set method needs accessors
+ options.compatibility?.componentApi === 4,
reactive_statements: new Map(),
binding_groups: new Map(),
slot_names: new Map(),
diff --git a/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js b/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js
index 124438a9da..a56aca9c5f 100644
--- a/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js
+++ b/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js
@@ -621,8 +621,9 @@ export function client_component(analysis, options) {
);
}
- if (analysis.custom_element) {
- const ce = analysis.custom_element;
+ const ce = options.customElementOptions ?? options.customElement;
+
+ if (ce) {
const ce_props = typeof ce === 'boolean' ? {} : ce.props || {};
/** @type {ESTree.Property[]} */
diff --git a/packages/svelte/tests/runtime-runes/samples/custom-element-injected-styles/Thing.svelte b/packages/svelte/tests/runtime-runes/samples/custom-element-injected-styles/Thing.svelte
new file mode 100644
index 0000000000..0a2b139274
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/custom-element-injected-styles/Thing.svelte
@@ -0,0 +1,9 @@
+