diff --git a/packages/svelte/src/compiler/index.js b/packages/svelte/src/compiler/index.js
index f1a15f2ebf..be1b17b1b1 100644
--- a/packages/svelte/src/compiler/index.js
+++ b/packages/svelte/src/compiler/index.js
@@ -30,7 +30,7 @@ export function compile(source, options) {
const {
customElement: customElementOptions,
- customRenderer,
+ customRenderer: custom_renderer,
...parsed_options
} = parsed.options || {};
@@ -43,7 +43,7 @@ export function compile(source, options) {
runes: 'runes' in parsed_options ? () => parsed_options.runes : validated.runes,
experimental: {
...validated.experimental,
- ...(customRenderer !== undefined ? { customRenderer } : {})
+ ...(custom_renderer !== undefined ? { customRenderer: () => custom_renderer } : {})
}
};
diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js
index dec0081aa9..946ac578c5 100644
--- a/packages/svelte/src/compiler/phases/2-analyze/index.js
+++ b/packages/svelte/src/compiler/phases/2-analyze/index.js
@@ -467,6 +467,7 @@ export function analyze_component(root, source, options) {
const custom_element_from_option = options.customElement({ filename: options.filename });
const css = options.css({ filename: options.filename });
+ const custom_renderer = options.experimental.customRenderer({ filename: options.filename });
const custom_element = options.customElementOptions ?? custom_element_from_option;
const is_custom_element = !!options.customElementOptions || custom_element_from_option;
@@ -529,6 +530,7 @@ export function analyze_component(root, source, options) {
event_directive_node: null,
uses_event_attributes: false,
custom_element,
+ custom_renderer,
inject_styles: css === 'injected' || is_custom_element,
accessors:
is_custom_element ||
diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/Attribute.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/Attribute.js
index 320760235f..f9e3e18724 100644
--- a/packages/svelte/src/compiler/phases/2-analyze/visitors/Attribute.js
+++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/Attribute.js
@@ -60,7 +60,7 @@ export function Attribute(node, context) {
}
// we can't delegate event handlers in a non dom environment
- if (!context.state.options.experimental.customRenderer) {
+ if (!context.state.analysis.custom_renderer) {
node.metadata.delegated =
parent?.type === 'RegularElement' && can_delegate_event(node.name.slice(2));
}
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 e447507fbe..f32e249b4c 100644
--- a/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js
+++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js
@@ -112,7 +112,7 @@ export function RegularElement(node, context) {
// We mark the subtree as dynamic so parent elements properly include the child init code
if (
(is_customizable_select_element(node) || node.name === 'selectedcontent') &&
- !context.state.options.experimental.customRenderer
+ !context.state.analysis.custom_renderer
) {
// Mark the element's own fragment as dynamic so it's not treated as static
node.fragment.metadata.dynamic = true;
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 fb467403be..115910b751 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
@@ -163,7 +163,7 @@ export function client_component(analysis, options) {
scopes: analysis.module.scopes,
is_instance: false,
hoisted: [
- ...custom_renderer_imports(options.experimental.customRenderer),
+ ...custom_renderer_imports(analysis.custom_renderer),
...analysis.instance_body.hoisted
],
node: /** @type {any} */ (null), // populated by the root node
@@ -406,7 +406,7 @@ export function client_component(analysis, options) {
);
}
- if (options.experimental.customRenderer) {
+ if (analysis.custom_renderer) {
component_block.body.unshift(
b.var('$$pop_renderer', b.call('$.push_renderer', b.id('$renderer')))
);
@@ -585,7 +585,7 @@ export function client_component(analysis, options) {
// disclose version attach the svelte version to `window` which is not guaranteed
// to be a thing in custom renderers environments
- if (options.discloseVersion && !options.experimental.customRenderer) {
+ if (options.discloseVersion && !analysis.custom_renderer) {
body.unshift(b.imports([], 'svelte/internal/disclose-version'));
}
diff --git a/packages/svelte/src/compiler/phases/3-transform/client/transform-template/index.js b/packages/svelte/src/compiler/phases/3-transform/client/transform-template/index.js
index cae9c94f4d..3dcc8c228a 100644
--- a/packages/svelte/src/compiler/phases/3-transform/client/transform-template/index.js
+++ b/packages/svelte/src/compiler/phases/3-transform/client/transform-template/index.js
@@ -36,7 +36,7 @@ function build_locations(nodes) {
*/
export function transform_template(state, namespace, flags = 0) {
// custom renderers needs a tree to work because there's no template element we can use
- const tree = state.options.fragments === 'tree' || !!state.options.experimental.customRenderer;
+ const tree = state.options.fragments === 'tree' || !!state.analysis.custom_renderer;
const expression = tree ? state.template.as_tree() : state.template.as_html();
diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js
index 76152b28ed..468eadca87 100644
--- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js
+++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js
@@ -41,7 +41,7 @@ export function RegularElement(node, context) {
const is_html =
context.state.metadata.namespace === 'html' &&
node.name !== 'svg' &&
- !context.state.options.experimental.customRenderer;
+ !context.state.analysis.custom_renderer;
const name = is_html ? node.name.toLowerCase() : node.name;
context.state.template.push_element(name, node.start, is_html);
@@ -51,8 +51,7 @@ export function RegularElement(node, context) {
}
// we never treat elements as custom element in custom renderers, since we don't want to apply special handling to them (e.g. class merging)
- const is_custom_element =
- is_custom_element_node(node) && !context.state.options.experimental.customRenderer;
+ const is_custom_element = is_custom_element_node(node) && !context.state.analysis.custom_renderer;
// cloneNode is faster, but it does not instantiate the underlying class of the
// custom element until the template is connected to the dom, which would
@@ -258,7 +257,7 @@ export function RegularElement(node, context) {
if (name !== 'class' || value) {
context.state.template.set_prop(attribute.name, value === true ? '' : value);
}
- } else if (name === 'autofocus' && !context.state.options.experimental.customRenderer) {
+ } else if (name === 'autofocus' && !context.state.analysis.custom_renderer) {
let { value } = build_attribute_value(attribute.value, context);
context.state.init.push(b.stmt(b.call('$.autofocus', node_id, value)));
} else if (name === 'class') {
@@ -280,7 +279,7 @@ export function RegularElement(node, context) {
name,
value,
attributes,
- !!context.state.options.experimental.customRenderer
+ !!context.state.analysis.custom_renderer
);
(has_state ? context.state.update : context.state.init).push(b.stmt(update));
@@ -357,7 +356,7 @@ export function RegularElement(node, context) {
const empty_string = value.type === 'Literal' && value.value === '';
if (!empty_string) {
- if (context.state.options.experimental.customRenderer) {
+ if (context.state.analysis.custom_renderer) {
// custom renderers need to use the method to invoke the renderer
context.state.template.push_text([
{
@@ -377,10 +376,7 @@ export function RegularElement(node, context) {
);
}
}
- } else if (
- is_customizable_select_element(node) &&
- !context.state.options.experimental.customRenderer
- ) {
+ } else if (is_customizable_select_element(node) && !context.state.analysis.custom_renderer) {
// For