Skip to content

Commit 136fefe

Browse files
Ben Szymanskibszyman
authored andcommitted
Rewrote global context article to include insights from community meetup, examples of how to create a context and how to consume a context.
1 parent f9f8e83 commit 136fefe

File tree

1 file changed

+145
-11
lines changed

1 file changed

+145
-11
lines changed
Lines changed: 145 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,158 @@
11
---
2-
description: Establish the bond for extensions to communication across the application
2+
description: Global contexts in Umbraco provide a clean, type-safe way to share functionality across the backoffice.
33
---
44

55
# Global Context
66

7-
{% hint style="warning" %}
8-
This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
9-
{% endhint %}
7+
The Global Context extension type allows extension authors to create a custom context of data and functions and make it available across the entire backoffice. Unlike other contexts that might be scoped to a specific workspace or view, a global context is available everywhere. These contexts are kept alive through the entire backoffice session.
108

11-
A global context manages the logic code from your Lit Element controllers.
9+
Consider using a global context when you need to:
10+
11+
- **Share state across multiple extensions** - Track user preferences or application-wide settings
12+
- **Provide utility functions** - Common operations that multiple parts of an extension
13+
- **Manage centralized services** - API clients, notification handlers, or data repositories
14+
- **Coordinate between different extensions** - Communication layer between dashboards, property editors, and other components
15+
- **Share functionality with other extensions** - Allow other package developers to access features and functionality within the package
16+
17+
Extension authors should prefer to use other context types [Workspace Contexts](workspaces/workspace-context.md) over Global Contexts. Umbraco itself uses Global Contexts sparingly, for clipboard, current user, and icons.
1218

1319
## Registration of a Global Context
1420

15-
You can register a global context like so:
21+
Global Context extensions can be registered using a manifest file like `umbraco-package.json`.
1622

17-
```typescript
23+
{% code title="umbraco-package.json" %}
24+
```json
1825
{
19-
type: 'globalContext',
20-
alias: 'My.GlobalContext.Products',
21-
name: 'My Products Context',
22-
api: 'my-products.context.js',
26+
"$schema": "../../umbraco-package-schema.json",
27+
"name": "My Global Context Package",
28+
"version": "1.0.0",
29+
"extensions": [
30+
{
31+
"type": "globalContext",
32+
"alias": "My.GlobalContext",
33+
"name": "My Global Context",
34+
"api": "/App_Plugins/my-global-context/dist/my-context.context.js"
35+
}
36+
]
37+
}
38+
```
39+
{% endcode %}
40+
41+
**Key fields:**
42+
- `type`: Must be `"globalContext"`, see: [ManifestGlobalContext](https://apidocs.umbraco.com/v16/ui-api/interfaces/packages_core_extension-registry.ManifestGlobalContext.html)
43+
- `alias`: A unique identifier for the context
44+
- `name`: A human-readable name
45+
- `api`: The path to the compiled JavaScript file
46+
47+
## Creating Your Global Context
48+
49+
### 1. Define a Context Token
50+
51+
First, create a context token. This is how other parts of an extension will reference the context:
52+
53+
{% code title="src/my-context.ts" %}
54+
```typescript
55+
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
56+
57+
export interface MyGlobalContextInterface {
58+
getCurrentUser(): Promise<string>;
59+
setPreference(key: string, value: any): void;
60+
getPreference(key: string): any;
61+
getHostElement(): Element;
62+
}
63+
64+
export const MY_GLOBAL_CONTEXT = new UmbContextToken<MyGlobalContextInterface>(
65+
'My.GlobalContext'
66+
);
67+
```
68+
{% endcode %}
69+
70+
### 2. Implement the Context Class
71+
72+
Next, implement the context class:
73+
74+
{% code title="src/my-context.ts" %}
75+
```typescript
76+
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
77+
import { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
78+
79+
export class MyGlobalContext extends UmbContextBase<MyGlobalContextInterface> implements MyGlobalContextInterface {
80+
#preferences: Map<string, any> = new Map();
81+
82+
constructor(host: UmbControllerHost) {
83+
super(host, MY_GLOBAL_CONTEXT);
84+
}
85+
86+
async getCurrentUser(): Promise<string> {
87+
// In a real implementation, you'd fetch this from the API
88+
return 'Current User';
89+
}
90+
91+
setPreference(key: string, value: any): void {
92+
this.#preferences.set(key, value);
93+
console.log(`Preference set: ${key} = ${value}`);
94+
}
95+
96+
getPreference(key: string): any {
97+
return this.#preferences.get(key);
98+
}
99+
100+
getHostElement(): Element {
101+
return this;
102+
}
103+
}
104+
105+
export default MyGlobalContext;
106+
```
107+
{% endcode %}
108+
109+
## Using Global Contexts
110+
111+
Once the global context extension is registered, it can be consumed in any web component throughout the backoffice.
112+
113+
{% code title="src/my-custom-dashboard.ts" %}
114+
```typescript
115+
import {
116+
LitElement,
117+
html,
118+
customElement,
119+
} from "@umbraco-cms/backoffice/external/lit";
120+
import { UmbElementMixin } from "@umbraco-cms/backoffice/element-api";
121+
import {
122+
MY_GLOBAL_CONTEXT,
123+
MyGlobalContextInterface,
124+
} from "./service-status-context.ts";
125+
126+
@customElement("my-custom-dashboard")
127+
export class MyCustomDashboard extends UmbElementMixin(LitElement) {
128+
#myContext?: MyGlobalContextInterface;
129+
130+
constructor() {
131+
super();
132+
133+
// Consume the global context
134+
this.consumeContext(MY_GLOBAL_CONTEXT, (instance) => {
135+
this.#myContext = instance;
136+
});
137+
}
138+
139+
async #handleClick() {
140+
if (!this.#myContext) return;
141+
142+
// Use the context
143+
const user = await this.#myContext.getCurrentUser();
144+
this.#myContext.setPreference("lastVisit", new Date().toISOString());
145+
146+
console.log(`Welcome back, ${user}!`);
147+
}
148+
149+
render() {
150+
return html`
151+
<uui-button @click=${this.#handleClick} look="primary">
152+
Check User
153+
</uui-button>
154+
`;
155+
}
23156
}
24157
```
158+
{% endcode %}

0 commit comments

Comments
 (0)