For weeks I have been looking to find out if it is possible to write back office extensions in razor. As Umbraco is written primarily in ASP.NET Core / C# it seemed like an obvious option but I can’t see how it’s possible.
Has anyone achieved this?
For weeks I have been looking to find out if it is possible to write back office extensions in razor. As Umbraco is written primarily in ASP.NET Core / C# it seemed like an obvious option but I can’t see how it’s possible.
Has anyone achieved this?
At first I wanted to say you cannot as your primary assumption is not quite precise - Umbraco is rather SPA application, where most of the interactions happen in the client side.
But then, started envisioning some hybrid solution. Probably some basics will require JS/TS to just ensure the extension integrates properly with the Umbraco backoffice and wire events properly, but the core of your extension can be potentially loaded into the IFRAME and interact with server directly. For read-only controls/reports/information, this could be enough. For better UX, in-page scripting can be provided in something as simple as jQuery or HTMX without interfering the Umbraco solution at all.
Such wrapper could be created as generic nuget package for everyone to use - just bring your razor views and controllers, configure the integration and voilà - your plugin is ready.
It seems to be quite interesting concept - especially for read-only plugins or to features that call some external features, with limited integration with the system itself.
The Umbaco backoffice is a completely seperate Single Page Application that contains no C#. Every interaction is done through the Management API. So technically you could replace the Umbraco backoffice with something else or you could perform all Umbraco actions using the content management API. So the backoffice is a frontend for the C# ‘core’ that communicate with an API. The C# part is completely seperate from the javascript backoffice SPA.
I guess the closest thing to using C# for backoffice extensions is using Blazor. In the end, if it’s a web component, you can use it in the backoffice, it doesn’t matter how to you get to the web component (vue, react, Blazor).
I was thinking more for dashboard/settings components that are maybe not as complex. I have managed to get razor pages with Blazor components. Unfortunately, the Umbraco package files are geared towards JS/TS etc, making it a little tricky for the backoffice to implement my pages. If it is indeed possible, I’d love to be pointed to a practical example.
I will say, being new to Umbraco, it seems like an amazing CMS. I’m looking forward to getting to know it better.
It would be interesting to see if someone could get Blazor to render in the Backoffice. I suppose running Blazor in server mode isn’t feasible due to the route hijacking - the backoffice client has its own router.
Perhaps if you ran Blazor in WASM mode and loaded up the bundle in the Backoffice, you could then load Blazor components in the Backoffice? It would only require a thin Web Component shell to render the HTML.
The only requirement of Backoffice extensions is that the first level is a Web Component, for example (untested code):
// blazor-loader.js
export default class BlazorLoader extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
width: 100%;
height: 100%;
position: relative;
}
</style>
<my-blazor-component></my-blazor-component>
`;
}
}
customElements.define('blazor-loader', BlazorLoader);
To register that as a dashboard, and load in the Blazor wasm bundle, you need to register a Backoffice Entry Point:
// entrypoint.js
import '/path/to/blazor.wasm.js';
export const onInit = (host, registry) => {
registry.register({
type: 'dashboard',
element: () => import('blazor-loader.js'),
name: 'dashboard',
alias: 'my.dashboard',
meta: {
label: "Welcome Dashboard",
pathname: "welcome-dashboard"
},
conditions: [
{
alias: "Umb.Condition.SectionAlias",
match: "Umb.Section.Content"
}
]
})
}
Then finally a manifest file to load the entry point:
//umbraco-package.json
{
"name": "My package",
"alias": "my.package",
"extensions": [
{
"type": "backofficeEntryPoint",
"alias": "my.entrypoint",
"name": "My Backoffice Entry Point",
"js": "entrypoint.js"
}
]
}
This is, of course, highly experimental and a very naïve approach. I don’t know if you can load in the Blazor wasm module from somewhere else, nor do I know if you can use Blazor components like I do in the dashboard ("<my-blazor-component></my-blazor-component>"
).