we don't need to traverse these nodes
or
these
ones
diff --git a/.changeset/wild-moose-destroy.md b/.changeset/wild-moose-destroy.md
new file mode 100644
index 0000000000..9dfc8d2bc1
--- /dev/null
+++ b/.changeset/wild-moose-destroy.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: don't skip custom elements with attributes
diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js
index 16be82ed2c..dc283db7e2 100644
--- a/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js
+++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js
@@ -7,10 +7,11 @@ import {
} from '../../../../html-tree-validation.js';
import * as e from '../../../errors.js';
import * as w from '../../../warnings.js';
-import { create_attribute } from '../../nodes.js';
+import { create_attribute, is_custom_element_node } from '../../nodes.js';
import { regex_starts_with_newline } from '../../patterns.js';
import { check_element } from './shared/a11y.js';
import { validate_element } from './shared/element.js';
+import { mark_subtree_dynamic } from './shared/fragment.js';
/**
* @param {RegularElement} node
@@ -88,6 +89,11 @@ export function RegularElement(node, context) {
node.metadata.svg = is_svg(node.name);
node.metadata.mathml = is_mathml(node.name);
+ if (is_custom_element_node(node) && node.attributes.length > 0) {
+ // we're setting all attributes on custom elements through properties
+ mark_subtree_dynamic(context.path);
+ }
+
if (context.state.parent_element) {
let past_parent = false;
let only_warn = false;
diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js
index cbe0272827..6dcb794f2c 100644
--- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js
+++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js
@@ -1,6 +1,6 @@
/** @import { Expression } from 'estree' */
/** @import { ExpressionTag, SvelteNode, Text } from '#compiler' */
-/** @import { ComponentClientTransformState, ComponentContext } from '../../types' */
+/** @import { ComponentContext } from '../../types' */
import { is_event_attribute, is_text_attribute } from '../../../../../utils/ast.js';
import * as b from '../../../../../utils/builders.js';
import { build_template_literal, build_update } from './utils.js';
diff --git a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js
index 5eacd941ea..4f59c4932e 100644
--- a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js
+++ b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js
@@ -1,7 +1,7 @@
import "svelte/internal/disclose-version";
import * as $ from "svelte/internal/client";
-var root = $.template(` we don't need to traverse these nodes or these ones we don't need to traverse these nodes or these ones we don't need to traverse these nodes or these ones we don't need to traverse these nodes or these ones
${$.escape(title)}
${$.escape(title)}
ones
{@html content} + +