diff --git a/code/renderers/svelte/src/decorators.ts b/code/renderers/svelte/src/decorators.ts
index abf9d80b7a31..07fb1753b56d 100644
--- a/code/renderers/svelte/src/decorators.ts
+++ b/code/renderers/svelte/src/decorators.ts
@@ -1,78 +1,84 @@
 import type { DecoratorFunction, StoryContext, LegacyStoryFn } from '@storybook/types';
 import { sanitizeStoryContextUpdate } from '@storybook/preview-api';
-import SlotDecorator from '../templates/SlotDecorator.svelte';
+// ! DO NOT change this SlotDecorator import to a relative path, it will break it.
+// ! A relative import will be compiled at build time, and Svelte will be unable to
+// ! render the component together with the user's Svelte components
+// ! importing from @storybook/svelte will make sure that it is compiled at runtime
+// ! with the same bundle as the user's Svelte components
+// eslint-disable-next-line import/no-extraneous-dependencies
+import SlotDecorator from '@storybook/svelte/templates/SlotDecorator.svelte';
 import type { SvelteRenderer } from './types';
 
 /**
- * Check if an object is a svelte component.
- * @param obj Object
- */
-function isSvelteComponent(obj: any) {
-  return obj.prototype && obj.prototype.$destroy !== undefined;
-}
-
-/**
- * Handle component loaded with esm or cjs.
+ * Handle component loaded with ESM or CJS,
+ * by getting the 'default' property of the object if it exists.
  * @param obj object
  */
-function unWrap(obj: any) {
-  return obj && obj.default ? obj.default : obj;
+function unWrap<T>(obj: { default: T } | T): T {
+  return obj && typeof obj === 'object' && 'default' in obj ? obj.default : obj;
 }
 
 /**
- * Transform a story to be compatible with the PreviewRender component.
+ * Prepare a story to be compatible with the PreviewRender component.
  *
- * - `() => MyComponent` is translated to `() => ({ Component: MyComponent })`
- * - `() => ({})` is translated to `() => ({ Component: <from context.component> })`
- * - A decorator component is wrapped with SlotDecorator. The decorated component is inject through
- * a <slot/>
+ * - `() => ({ Component: MyComponent, props: ...})` is already prepared, kept as-is
+ * - `() => MyComponent` is transformed to `() => ({ Component: MyComponent })`
+ * - `() => ({})` is transformed to component from context with `() => ({ Component: context.component })`
+ * - A decorator component is wrapped with SlotDecorator, injecting the decorated component in a <slot />
  *
  * @param context StoryContext
  * @param story  the current story
- * @param originalStory the story decorated by the current story
+ * @param innerStory the story decorated by the current story
  */
-function prepareStory(context: StoryContext<SvelteRenderer>, story: any, originalStory?: any) {
-  let result = unWrap(story);
-  if (isSvelteComponent(result)) {
-    // wrap the component
-    result = {
-      Component: result,
+function prepareStory(
+  context: StoryContext<SvelteRenderer>,
+  rawStory: SvelteRenderer['storyResult'],
+  rawInnerStory?: SvelteRenderer['storyResult']
+) {
+  const story = unWrap(rawStory);
+  const innerStory = rawInnerStory && unWrap(rawInnerStory);
+
+  let preparedStory;
+
+  if (!story || Object.keys(story).length === 0) {
+    // story is empty or an empty object, use the component from the context
+    preparedStory = {
+      Component: context.component,
+    };
+  } else if (story.Component) {
+    // the story is already prepared
+    preparedStory = story;
+  } else {
+    // we must assume that the story is a Svelte component
+    preparedStory = {
+      Component: story,
     };
   }
 
-  if (originalStory) {
-    // inject the new story as a wrapper of the original story
-    result = {
+  if (innerStory) {
+    // render a SlotDecorator with innerStory as its regular component,
+    // and the prepared story as the decorating component
+    return {
       Component: SlotDecorator,
       props: {
-        decorator: unWrap(result.Component),
-        decoratorProps: result.props,
-        component: unWrap(originalStory.Component),
-        props: originalStory.props,
-        on: originalStory.on,
+        // inner stories will already have been prepared, keep as is
+        ...innerStory,
+        decorator: preparedStory,
       },
     };
-  } else {
-    let cpn = result.Component;
-    if (!cpn) {
-      // if the component is not defined, get it the context
-      cpn = context.component;
-    }
-    result.Component = unWrap(cpn);
   }
-  return result;
+
+  return preparedStory;
 }
 
 export function decorateStory(storyFn: any, decorators: any[]) {
   return decorators.reduce(
-    (
-        previousStoryFn: LegacyStoryFn<SvelteRenderer>,
-        decorator: DecoratorFunction<SvelteRenderer>
-      ) =>
+    (decorated: LegacyStoryFn<SvelteRenderer>, decorator: DecoratorFunction<SvelteRenderer>) =>
       (context: StoryContext<SvelteRenderer>) => {
-        let story;
-        const decoratedStory = decorator((update) => {
-          story = previousStoryFn({
+        let story: SvelteRenderer['storyResult'] | undefined;
+
+        const decoratedStory: SvelteRenderer['storyResult'] = decorator((update) => {
+          story = decorated({
             ...context,
             ...sanitizeStoryContextUpdate(update),
           });
@@ -80,10 +86,10 @@ export function decorateStory(storyFn: any, decorators: any[]) {
         }, context);
 
         if (!story) {
-          story = previousStoryFn(context);
+          story = decorated(context);
         }
 
-        if (!decoratedStory || decoratedStory === story) {
+        if (decoratedStory === story) {
           return story;
         }
 
diff --git a/code/renderers/svelte/src/render.ts b/code/renderers/svelte/src/render.ts
index ad111dcf14c7..777997c09598 100644
--- a/code/renderers/svelte/src/render.ts
+++ b/code/renderers/svelte/src/render.ts
@@ -1,7 +1,11 @@
 /* eslint-disable no-param-reassign */
 import type { RenderContext, ArgsStoryFn } from '@storybook/types';
 import type { SvelteComponentTyped } from 'svelte';
-
+// ! DO NOT change this PreviewRender import to a relative path, it will break it.
+// ! A relative import will be compiled at build time, and Svelte will be unable to
+// ! render the component together with the user's Svelte components
+// ! importing from @storybook/svelte will make sure that it is compiled at runtime
+// ! with the same bundle as the user's Svelte components
 // eslint-disable-next-line import/no-extraneous-dependencies
 import PreviewRender from '@storybook/svelte/templates/PreviewRender.svelte';
 
diff --git a/code/renderers/svelte/src/types.ts b/code/renderers/svelte/src/types.ts
index 23e76243f702..e30b2e8f549d 100644
--- a/code/renderers/svelte/src/types.ts
+++ b/code/renderers/svelte/src/types.ts
@@ -48,4 +48,5 @@ export interface SvelteStoryResult<
     ? Record<string, (event: CustomEvent) => void>
     : { [K in keyof Events as string extends K ? never : K]?: (event: Events[K]) => void };
   props?: Props;
+  decorator?: ComponentType<Props>;
 }
diff --git a/code/renderers/svelte/template/stories/slot-decorators.stories.js b/code/renderers/svelte/template/stories/slot-decorators.stories.js
new file mode 100644
index 000000000000..759904403640
--- /dev/null
+++ b/code/renderers/svelte/template/stories/slot-decorators.stories.js
@@ -0,0 +1,42 @@
+import ButtonView from './views/ButtonView.svelte';
+import BorderDecoratorRed from './views/BorderDecoratorRed.svelte';
+import BorderDecoratorBlue from './views/BorderDecoratorBlue.svelte';
+import BorderDecoratorProps from './views/BorderDecoratorProps.svelte';
+
+export default {
+  component: ButtonView,
+  decorators: [() => BorderDecoratorRed],
+  args: {
+    primary: true,
+  },
+};
+
+export const WithDefaultRedBorder = {};
+export const WithBareBlueBorder = {
+  decorators: [() => BorderDecoratorBlue],
+};
+export const WithPreparedBlueBorder = {
+  decorators: [
+    () => ({
+      Component: BorderDecoratorBlue,
+    }),
+  ],
+};
+export const WithPropsBasedBorder = {
+  decorators: [
+    () => ({
+      Component: BorderDecoratorProps,
+      props: { color: 'green' },
+    }),
+  ],
+};
+export const WithArgsBasedBorderUnset = {
+  argTypes: {
+    color: { control: 'color' },
+  },
+  decorators: [(_, { args }) => ({ Component: BorderDecoratorProps, props: args })],
+};
+export const WithArgsBasedBorder = {
+  ...WithArgsBasedBorderUnset,
+  args: { color: 'lightblue' },
+};
diff --git a/code/renderers/svelte/template/stories/svelte-mdx.stories.mdx b/code/renderers/svelte/template/stories/svelte-mdx.stories.mdx
index 9d8fb482aa47..b8b3cabb51b0 100644
--- a/code/renderers/svelte/template/stories/svelte-mdx.stories.mdx
+++ b/code/renderers/svelte/template/stories/svelte-mdx.stories.mdx
@@ -1,6 +1,7 @@
 import globalThis from 'global';
 import { Meta, Story, Canvas } from '@storybook/addon-docs';
 import ButtonView from './views/ButtonView.svelte';
+import BorderDecoratorRed from './views/BorderDecoratorRed.svelte';
 
 <Meta title="stories/renderers/svelte/svelte-mdx" />
 
@@ -33,3 +34,15 @@ import ButtonView from './views/ButtonView.svelte';
     }}
   </Story>
 </Canvas>
+
+<Canvas>
+  <Story name="WithDecorator" decorators={[() => BorderDecoratorRed]}>
+    {{
+      Component: ButtonView,
+      props: {
+        primary: false,
+        text: 'Secondary text',
+      },
+    }}
+  </Story>
+</Canvas>
diff --git a/code/renderers/svelte/template/stories/views/BorderDecoratorBlue.svelte b/code/renderers/svelte/template/stories/views/BorderDecoratorBlue.svelte
new file mode 100644
index 000000000000..e0bb0db72e2f
--- /dev/null
+++ b/code/renderers/svelte/template/stories/views/BorderDecoratorBlue.svelte
@@ -0,0 +1,3 @@
+<div style="border: 3px solid blue; padding: 10px; margin: 10px;">
+  <slot />
+</div>
diff --git a/code/renderers/svelte/template/stories/views/BorderDecoratorProps.svelte b/code/renderers/svelte/template/stories/views/BorderDecoratorProps.svelte
new file mode 100644
index 000000000000..53fdd7c54f4a
--- /dev/null
+++ b/code/renderers/svelte/template/stories/views/BorderDecoratorProps.svelte
@@ -0,0 +1,7 @@
+<script>
+  export let color = 'violet';
+</script>
+
+<div style="border: 3px solid {color}; padding: 10px; margin: 10px;">
+  <slot />
+</div>
diff --git a/code/renderers/svelte/template/stories/views/BorderDecoratorRed.svelte b/code/renderers/svelte/template/stories/views/BorderDecoratorRed.svelte
new file mode 100644
index 000000000000..6c3f33e49a14
--- /dev/null
+++ b/code/renderers/svelte/template/stories/views/BorderDecoratorRed.svelte
@@ -0,0 +1,3 @@
+<div style="border: 3px solid red; padding: 10px; margin: 10px;">
+  <slot />
+</div>
diff --git a/code/renderers/svelte/templates/PreviewRender.svelte b/code/renderers/svelte/templates/PreviewRender.svelte
index 6ad197bea0f0..7747cd8fcaba 100644
--- a/code/renderers/svelte/templates/PreviewRender.svelte
+++ b/code/renderers/svelte/templates/PreviewRender.svelte
@@ -15,12 +15,10 @@
     props = {},
     /** @type {{[string]: () => {}}} Attach svelte event handlers */
     on,
-    Wrapper,
-    WrapperData = {},
   } = storyFn();
 
   // reactive, re-render on storyFn change
-  $: ({ Component, props = {}, on, Wrapper, WrapperData = {} } = storyFn());
+  $: ({ Component, props = {}, on } = storyFn());
 
   const eventsFromArgTypes = Object.fromEntries(
     Object.entries(storyContext.argTypes)
@@ -28,24 +26,16 @@
       .map(([k, v]) => [v.action, props[k]])
   );
 
-  const events = { ...eventsFromArgTypes, ...on };
-
   if (!Component) {
     showError({
       title: `Expecting a Svelte component from the story: "${name}" of "${kind}".`,
       description: dedent`
         Did you forget to return the Svelte component configuration from the story?
-        Use "() => ({ Component: YourComponent, data: {} })"
+        Use "() => ({ Component: YourComponent, props: {} })"
         when defining the story.
       `,
     });
   }
 </script>
 
-<SlotDecorator
-  decorator={Wrapper}
-  decoratorProps={WrapperData}
-  component={Component}
-  {props}
-  on={events}
-/>
+<SlotDecorator {Component} {props} on={{ ...eventsFromArgTypes, ...on }} />
diff --git a/code/renderers/svelte/templates/SlotDecorator.svelte b/code/renderers/svelte/templates/SlotDecorator.svelte
index 6b0d06337001..5bd0fdfe3455 100644
--- a/code/renderers/svelte/templates/SlotDecorator.svelte
+++ b/code/renderers/svelte/templates/SlotDecorator.svelte
@@ -1,10 +1,10 @@
 <script>
   import { onMount } from 'svelte';
-  export let decorator;
-  export let decoratorProps = {};
-  export let component;
+
+  export let decorator = undefined;
+  export let Component;
   export let props = {};
-  export let on;
+  export let on = undefined;
 
   let instance;
   let decoratorInstance;
@@ -23,9 +23,9 @@
 </script>
 
 {#if decorator}
-  <svelte:component this={decorator} {...decoratorProps} bind:this={decoratorInstance}>
-    <svelte:component this={component} {...props} bind:this={instance} />
+  <svelte:component this={decorator.Component} {...decorator.props} bind:this={decoratorInstance}>
+    <svelte:component this={Component} {...props} bind:this={instance} />
   </svelte:component>
 {:else}
-  <svelte:component this={component} {...props} bind:this={instance} />
+  <svelte:component this={Component} {...props} bind:this={instance} />
 {/if}