|
1 | 1 | --- |
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. |
3 | 3 | --- |
4 | 4 |
|
5 | 5 | # Global Context |
6 | 6 |
|
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. |
10 | 8 |
|
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. |
12 | 18 |
|
13 | 19 | ## Registration of a Global Context |
14 | 20 |
|
15 | | -You can register a global context like so: |
| 21 | +Global Context extensions can be registered using a manifest file like `umbraco-package.json`. |
16 | 22 |
|
17 | | -```typescript |
| 23 | +{% code title="umbraco-package.json" %} |
| 24 | +```json |
18 | 25 | { |
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 | + } |
23 | 156 | } |
24 | 157 | ``` |
| 158 | +{% endcode %} |
0 commit comments