diff --git a/src/Umbraco.Web.UI.Client/examples/modal-routed/dashboard.element.ts b/src/Umbraco.Web.UI.Client/examples/modal-routed/dashboard.element.ts
new file mode 100644
index 0000000000..b7d8714b7d
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/examples/modal-routed/dashboard.element.ts
@@ -0,0 +1,72 @@
+import { css, html, LitElement } from 'lit';
+import { customElement, state } from 'lit/decorators.js';
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
+import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
+import { UmbModalRouteRegistrationController, UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router';
+import { EXAMPLE_ROUTED_MODAL } from './modal/example-modal-token';
+
+@customElement('umb-dashboard')
+export class UmbDashboardElement extends UmbElementMixin(LitElement) {
+
+ #workspaceModal?: UmbModalRouteRegistrationController;
+
+ @state()
+ private _routes: UmbRoute[] = [
+ {
+ path: `/tab1`,
+ component: () => import('./tabs/tab1.element.js'),
+ setup: (component, info) => {
+ },
+ },
+ {
+ path: `/tab2`,
+ component: () => import('./tabs/tab2.element.js'),
+ setup: (component, info) => {
+ },
+ },
+ {
+ path: '',
+ redirectTo: 'tab1',
+ },
+ ];
+
+ /**
+ *
+ */
+ constructor() {
+ super();
+ console.log('modal element loaded');
+ }
+
+ override render() {
+ return html`
+
+ umb-example modal
+
+
+
{
+ console.log('modal routes init');
+ }}
+ @change=${(event: UmbRouterSlotChangeEvent) => {
+ console.log('modal routes change');
+ }}>
+
+ `;
+ }
+
+ static override styles = [UmbTextStyles, css``];
+}
+
+export default UmbDashboardElement
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'umb-dashboard': UmbDashboardElement;
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/examples/modal-routed/dashboard2.element.ts b/src/Umbraco.Web.UI.Client/examples/modal-routed/dashboard2.element.ts
new file mode 100644
index 0000000000..cd08bae781
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/examples/modal-routed/dashboard2.element.ts
@@ -0,0 +1,36 @@
+import { css, html, LitElement } from 'lit';
+import { customElement, state } from 'lit/decorators.js';
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
+import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
+import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router';
+import { EXAMPLE_ROUTED_MODAL } from './modal/example-modal-token';
+
+@customElement('umb-dashboard2')
+export class UmbDashboard2Element extends UmbElementMixin(LitElement) {
+
+ constructor() {
+ super();
+ }
+
+ override render() {
+ return html`
+
+
Link to modal route
+
This page only shows how to link to the routed modal that is placed on a tab on the "Modal Dashboard". Clicking this link will not load the slots inside the modal, however, going to the "Modal Dashboard", clicking on tab 2 and opening the modal from there will work.
+
Open Modal Route
+
+ `
+
+ }
+
+ static override styles = [UmbTextStyles, css``];
+}
+
+export default UmbDashboard2Element
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'umb-dashboard2': UmbDashboard2Element;
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/examples/modal-routed/index.ts b/src/Umbraco.Web.UI.Client/examples/modal-routed/index.ts
new file mode 100644
index 0000000000..21a3f2085e
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/examples/modal-routed/index.ts
@@ -0,0 +1,48 @@
+import { ManifestDashboard, ManifestModal, ManifestSection } from '@umbraco-cms/backoffice/extension-registry';
+
+// const section : ManifestSection = {
+// type: "section",
+// alias: 'demo.section',
+// name: "Demo Section",
+// meta: {
+// label: "Demo",
+// pathname: "demo"
+// }
+// }
+
+let dashboard : ManifestDashboard = {
+ type: 'dashboard',
+ name: 'Example Modal Dashboard',
+ alias: 'example.dashboard.dataset',
+ element: () => import('./dashboard.element.js'),
+ weight: 15000,
+ meta: {
+ label: 'Modal Dashboard',
+ pathname: 'example',
+ },
+};
+
+let dashboard2 : ManifestDashboard = {
+ type: 'dashboard',
+ name: 'Example Modal Dashboard2',
+ alias: 'example.dashboard.dataset2',
+ element: () => import('./dashboard2.element.js'),
+ weight: 15001,
+ meta: {
+ label: 'Link Dashboard',
+ pathname: 'example-2',
+ },
+};
+
+const modal : ManifestModal = {
+ type: 'modal',
+ name: 'Example Modal',
+ alias: 'example.routed.modal',
+ element : () => import('./modal/example-modal.element.js'),
+};
+
+export const manifests = [
+ dashboard,
+ dashboard2,
+ modal
+];
diff --git a/src/Umbraco.Web.UI.Client/examples/modal-routed/modal/example-modal-token.ts b/src/Umbraco.Web.UI.Client/examples/modal-routed/modal/example-modal-token.ts
new file mode 100644
index 0000000000..0668cd9993
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/examples/modal-routed/modal/example-modal-token.ts
@@ -0,0 +1,15 @@
+import { UmbModalToken } from "@umbraco-cms/backoffice/modal";
+
+export type Data = {}
+export type RetData = {}
+
+export const EXAMPLE_ROUTED_MODAL = new UmbModalToken<
+Data,
+RetData
+>('example.routed.modal', // this needs to match the alias of the modal registered in manifest.ts
+{
+ modal : {
+ type : 'dialog',
+ size : 'full'
+ }
+});
diff --git a/src/Umbraco.Web.UI.Client/examples/modal-routed/modal/example-modal.element.ts b/src/Umbraco.Web.UI.Client/examples/modal-routed/modal/example-modal.element.ts
new file mode 100644
index 0000000000..25992faf05
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/examples/modal-routed/modal/example-modal.element.ts
@@ -0,0 +1,66 @@
+import { css, html, LitElement } from 'lit';
+import { customElement, state } from 'lit/decorators.js';
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
+import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
+import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
+import { UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router';
+
+@customElement('umb-example-modal')
+export class UmbExampleModal extends UmbModalBaseElement {
+
+ @state()
+ private _routes: UmbRoute[] = [
+ {
+ path: `/overview`,
+ component: () => import('./steps/example-modal-step1.element.js'),
+ setup: (component, info) => {
+ },
+ },
+ {
+ path: `/details`,
+ component: () => import('./steps/example-modal-step2.element.js'),
+ setup: (component, info) => {
+ },
+ },
+ {
+ path: '',
+ redirectTo: 'overview',
+ },
+ ];
+
+ /**
+ *
+ */
+ constructor() {
+ super();
+ console.log('modal element loaded');
+ }
+
+ override render() {
+ return html`
+
+ umb-example modal
+
+ {
+ console.log('modal routes init');
+ }}
+ @change=${(event: UmbRouterSlotChangeEvent) => {
+ console.log('modal routes change');
+ }}>
+
+ `;
+ }
+
+ static override styles = [UmbTextStyles, css``];
+}
+
+export default UmbExampleModal;
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'umb-example-modal': UmbExampleModal;
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/examples/modal-routed/modal/steps/example-modal-step1.element.ts b/src/Umbraco.Web.UI.Client/examples/modal-routed/modal/steps/example-modal-step1.element.ts
new file mode 100644
index 0000000000..35f39147fd
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/examples/modal-routed/modal/steps/example-modal-step1.element.ts
@@ -0,0 +1,31 @@
+import { css, html, LitElement } from 'lit';
+import { customElement } from 'lit/decorators.js';
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
+import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
+import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
+import { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router';
+
+@customElement('umb-example-modal-step1')
+export class UmbExampleModalStep1 extends UmbModalBaseElement {
+
+ override render() {
+ return html`
+
+ example modal step1
+
+
+
+ `;
+ }
+
+ static override styles = [UmbTextStyles, css``];
+}
+
+export default UmbExampleModalStep1;
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'umb-example-modal-step1': UmbExampleModalStep1;
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/examples/modal-routed/modal/steps/example-modal-step2.element.ts b/src/Umbraco.Web.UI.Client/examples/modal-routed/modal/steps/example-modal-step2.element.ts
new file mode 100644
index 0000000000..32dadca5b8
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/examples/modal-routed/modal/steps/example-modal-step2.element.ts
@@ -0,0 +1,31 @@
+import { css, html, LitElement } from 'lit';
+import { customElement } from 'lit/decorators.js';
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
+import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
+import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
+import { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router';
+
+@customElement('umb-example-modal-step2')
+export class UmbExampleModalStep2 extends UmbModalBaseElement {
+
+ override render() {
+ return html`
+
+ example modal step1
+
+
+
+ `;
+ }
+
+ static override styles = [UmbTextStyles, css``];
+}
+
+export default UmbExampleModalStep2;
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'umb-example-modal-step2': UmbExampleModalStep2;
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/examples/modal-routed/tabs/tab1.element.ts b/src/Umbraco.Web.UI.Client/examples/modal-routed/tabs/tab1.element.ts
new file mode 100644
index 0000000000..1c361976a0
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/examples/modal-routed/tabs/tab1.element.ts
@@ -0,0 +1,41 @@
+import { css, html, LitElement } from 'lit';
+import { customElement, state } from 'lit/decorators.js';
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
+import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
+import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router';
+import { EXAMPLE_ROUTED_MODAL } from './modal/example-modal-token';
+
+@customElement('umb-dashboard-tab1')
+export class UmbDashboardTab1Element extends UmbElementMixin(LitElement) {
+
+ #workspaceModal?: UmbModalRouteRegistrationController;
+
+ @state()
+ _editLinkPath?: string;
+
+ constructor() {
+ super();
+
+ }
+
+ override render() {
+ return html`
+
+
tab 1
+
+
+ `
+
+ }
+
+ static override styles = [UmbTextStyles, css``];
+}
+
+export default UmbDashboardTab1Element
+
+declare global {
+ interface UmbDashboardTab1Element {
+ 'umb-dashboard-tab1': UmbDashboardTab1Element;
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/examples/modal-routed/tabs/tab2.element.ts b/src/Umbraco.Web.UI.Client/examples/modal-routed/tabs/tab2.element.ts
new file mode 100644
index 0000000000..85c761a461
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/examples/modal-routed/tabs/tab2.element.ts
@@ -0,0 +1,59 @@
+import { css, html, LitElement } from 'lit';
+import { customElement, state } from 'lit/decorators.js';
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
+import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
+import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router';
+import { EXAMPLE_ROUTED_MODAL } from './../modal/example-modal-token';
+
+@customElement('umb-dashboard-tab2')
+export class UmbDashboardTab2Element extends UmbElementMixin(LitElement) {
+
+ #workspaceModal?: UmbModalRouteRegistrationController;
+
+ @state()
+ _editLinkPath?: string;
+
+ constructor() {
+ super();
+
+ // Using workspace modal context
+ this.#workspaceModal?.destroy();
+ this.#workspaceModal = new UmbModalRouteRegistrationController(this, EXAMPLE_ROUTED_MODAL)
+ .addAdditionalPath('view/:entityKey')
+ .onSetup(() => {
+ return {
+ data: {},
+ value: {}
+ };
+ })
+ .observeRouteBuilder((routeBuilder) => {
+ this._editLinkPath = routeBuilder({entityKey : 'abc123'});
+ });
+ }
+
+ override render() {
+ return html`
+
+
tab 2
+
This element hosts the UmbModalRouteRegistrationController
+
+
Open modal
+
+
+ Path: ${this._editLinkPath}
+
+ `
+
+ }
+
+ static override styles = [UmbTextStyles, css``];
+}
+
+export default UmbDashboardTab2Element
+
+declare global {
+ interface UmbDashboardTab2Element {
+ 'umb-dashboard-tab2': UmbDashboardTab2Element;
+ }
+}