diff --git a/src/compiler/compile/render_ssr/index.ts b/src/compiler/compile/render_ssr/index.ts
index e256ba78fbf0..670aa9baeb3b 100644
--- a/src/compiler/compile/render_ssr/index.ts
+++ b/src/compiler/compile/render_ssr/index.ts
@@ -198,7 +198,7 @@ export default function ssr(
instance_javascript,
...parent_bindings,
css.code && b`$$result.css.add(#css);`,
- main
+ b`return @no_current_component(() => { ${main} });`
].filter(Boolean);
const css_sourcemap_enabled = check_enable_sourcemap(options.enableSourcemap, 'css');
diff --git a/src/runtime/internal/Component.ts b/src/runtime/internal/Component.ts
index a8a500b25b02..c29bd68f0821 100644
--- a/src/runtime/internal/Component.ts
+++ b/src/runtime/internal/Component.ts
@@ -1,5 +1,5 @@
import { add_render_callback, flush, flush_render_callbacks, schedule_update, dirty_components } from './scheduler';
-import { current_component, set_current_component } from './lifecycle';
+import { current_component, no_current_component, set_current_component } from './lifecycle';
import { blank_object, is_empty, is_function, run, run_all, noop } from './utils';
import { children, detach, start_hydrating, end_hydrating } from './dom';
import { transition_in } from './transitions';
@@ -121,26 +121,29 @@ export function init(component, options, instance, create_fragment, not_equal, p
ready = true;
run_all($$.before_update);
- // `false` as a special case of no DOM component
- $$.fragment = create_fragment ? create_fragment($$.ctx) : false;
-
- if (options.target) {
- if (options.hydrate) {
- start_hydrating();
- const nodes = children(options.target);
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- $$.fragment && $$.fragment!.l(nodes);
- nodes.forEach(detach);
- } else {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- $$.fragment && $$.fragment!.c();
- }
+ no_current_component(() => {
+ // `false` as a special case of no DOM component
+ $$.fragment = create_fragment ? create_fragment($$.ctx) : false;
+
+
+ if (options.target) {
+ if (options.hydrate) {
+ start_hydrating();
+ const nodes = children(options.target);
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ $$.fragment && $$.fragment!.l(nodes);
+ nodes.forEach(detach);
+ } else {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ $$.fragment && $$.fragment!.c();
+ }
- if (options.intro) transition_in(component.$$.fragment);
- mount_component(component, options.target, options.anchor, options.customElement);
- end_hydrating();
- flush();
- }
+ if (options.intro) transition_in(component.$$.fragment);
+ mount_component(component, options.target, options.anchor, options.customElement);
+ end_hydrating();
+ flush();
+ }
+ });
set_current_component(parent_component);
}
diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts
index e75bbdc501f4..a69483ac3f2c 100644
--- a/src/runtime/internal/lifecycle.ts
+++ b/src/runtime/internal/lifecycle.ts
@@ -11,6 +11,14 @@ export function get_current_component() {
return current_component;
}
+export function no_current_component(callback: () => void) {
+ const old_current_component = current_component;
+ current_component = undefined;
+ const value = callback();
+ current_component = old_current_component;
+ return value;
+}
+
/**
* Schedules a callback to run immediately before the component is updated after any state change.
*
diff --git a/test/runtime/samples/context-api-in-element-1/_config.js b/test/runtime/samples/context-api-in-element-1/_config.js
new file mode 100644
index 000000000000..79b5908ab718
--- /dev/null
+++ b/test/runtime/samples/context-api-in-element-1/_config.js
@@ -0,0 +1,3 @@
+export default {
+ error: 'Function called outside component initialization'
+};
diff --git a/test/runtime/samples/context-api-in-element-1/main.svelte b/test/runtime/samples/context-api-in-element-1/main.svelte
new file mode 100644
index 000000000000..584d2bb05389
--- /dev/null
+++ b/test/runtime/samples/context-api-in-element-1/main.svelte
@@ -0,0 +1,5 @@
+
+
+{getContext('test')}
diff --git a/test/runtime/samples/context-api-in-element-2/_config.js b/test/runtime/samples/context-api-in-element-2/_config.js
new file mode 100644
index 000000000000..79b5908ab718
--- /dev/null
+++ b/test/runtime/samples/context-api-in-element-2/_config.js
@@ -0,0 +1,3 @@
+export default {
+ error: 'Function called outside component initialization'
+};
diff --git a/test/runtime/samples/context-api-in-element-2/main.svelte b/test/runtime/samples/context-api-in-element-2/main.svelte
new file mode 100644
index 000000000000..c852c7f5d7ad
--- /dev/null
+++ b/test/runtime/samples/context-api-in-element-2/main.svelte
@@ -0,0 +1,5 @@
+
+
+xxx
diff --git a/test/runtime/samples/context-api-in-element-3/_config.js b/test/runtime/samples/context-api-in-element-3/_config.js
new file mode 100644
index 000000000000..79b5908ab718
--- /dev/null
+++ b/test/runtime/samples/context-api-in-element-3/_config.js
@@ -0,0 +1,3 @@
+export default {
+ error: 'Function called outside component initialization'
+};
diff --git a/test/runtime/samples/context-api-in-element-3/main.svelte b/test/runtime/samples/context-api-in-element-3/main.svelte
new file mode 100644
index 000000000000..04f969fff35f
--- /dev/null
+++ b/test/runtime/samples/context-api-in-element-3/main.svelte
@@ -0,0 +1,5 @@
+
+
+{getContext('test')}