Early Adopter's guide to Umbraco v14 - Content apps
Tags: umbraco
Published: 2024-02-02 08:30:00

One of the main extendible features of the Umbraco Ui since version 8 has been content apps. 

Content apps allow you to add an extra 'tab' to a content page, with an icon in the top right of the page. Content apps, orignally where just for content, but now you can add them to media, document types and i thin media types ??. 

In umbraco 14, content apps are gone ☹️ - but don't worry, they have really just got a new name, and are way more flexible than before. 

## Content Apps => Workspace views

In Umbraco 14 most of the interface is built up of workspaces, and while you can create your own custom workspaces and workspace views to add to them. you can also add your own workspace views to anywhere in the umbraco UI that uses, them, so at the moment thats.. well amost everything, content, media, doctypes, datatypes,  users, event the log viewer is using workspaces, so you can add to them. 

## Document workspace example (or a Content App!)

Starting with the config, you define your own WorkspaceView, but this time, we set the conditional alias to that of the Content page. `Umb.Workspace.Document`

```ts
var workspaceView : ManifestWorkspaceView = {
    type: 'workspaceView',
    alias: 'time.document.workspace',
    name: 'time contentapp',
    js: () => import('./views/time-workspace-view.js'),
    weight: 10,
    meta: {
        icon: 'icon-alarm-clock',
        pathname: 'time',
        label: 'time'
    },
    conditions: [
        {
            alias: 'Umb.Condition.WorkspaceAlias',
            match: 'Umb.Workspace.Document'
        },
    ],    
}
```

This defines where and how our workspace will appear. As before weight goes from high -> low, so high is on the left, low on the right ?

all we need to do now is define the element for the app. 

```ts
@customElement('time-document-workspace-view')
export class TimeDocumentWorkspaceElement 
    extends UmbElementMixin(LitElement) {

    render() {
        return html`
            <uui-box headline="A content app?">

            </uui-box>
        `;
    }

    static styles = css`
        uui-box {
            margin: 20px;
        }
    `
}
```

![An empty content app.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uowem7ucg5zwnkszmvrg.png)

## Connecting to the document. 

once we have a content app, really we want to know what is going on with the document we are attached to. you can do this by consuming the `UMB_WORKSPACE_CONTEXT` which will give you the current context for the document you are on. 

> fun fact, this is the generic interface, so you can attach you view to any workspace and you will always be able to consume the `UMB_WORKSPACE_CONTEXT` and get the right context for where you are.

```ts

 constructor() {
    super();

    this.consumeContext(UMB_WORKSPACE_CONTEXT,
         (nodeContext) => {
              var variantContext = (nodeContext as UmbVariantableWorkspaceContextInterface);
              console.log(variantContext.getName());         
         });
}
```

now because the `UMB_WORKSPAGE_CONTEXT` is always generic if you want to to anything document based, you will need to cast it. 

in this case i've gone for `UmbVariantableWorkspaceContextInterface`

i am not sure if it's right, but it lets me get the name, and variant values from the page, so it might be : ) 

so quite quickly , we gotten a content app (workspace view!) and connected to the document. 

![Workspace view with some document info.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ov9yrczuq8glqz6tsbw.png)