| name | umbraco-user-profile-app |
| description | Implement user profile apps in Umbraco backoffice using official docs |
| version | 1.0.0 |
| location | managed |
| allowed-tools | Read, Write, Edit, WebFetch |
Umbraco User Profile App
What is it?
User Profile Apps are custom views/tabs that appear in the current user's profile section. They allow you to add custom functionality to the user profile area, such as preferences, activity logs, connected accounts, or any user-specific settings.
Documentation
Always fetch the latest docs before implementing:
Related Foundation Skills
Workflow
- Fetch docs - Use WebFetch on the URLs above
- Ask questions - What functionality? What data to display?
- Generate files - Create manifest + element based on latest docs
- Explain - Show what was created and how to test
Minimal Examples
Manifest (manifests.ts)
import type { ManifestUserProfileApp } from '@umbraco-cms/backoffice/extension-registry';
const manifest: ManifestUserProfileApp = {
type: 'userProfileApp',
alias: 'My.UserProfileApp.Preferences',
name: 'User Preferences',
element: () => import('./preferences-app.element.js'),
meta: {
label: 'Preferences',
pathname: 'preferences',
},
};
export const manifests = [manifest];
Profile App Element (preferences-app.element.ts)
import { html, css, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user';
@customElement('my-preferences-app')
export class MyPreferencesAppElement extends UmbLitElement {
@state()
private _userName?: string;
@state()
private _emailNotifications = true;
@state()
private _darkMode = false;
constructor() {
super();
this.consumeContext(UMB_CURRENT_USER_CONTEXT, (context) => {
this.observe(context.currentUser, (user) => {
this._userName = user?.name;
});
});
}
#handleEmailToggle() {
this._emailNotifications = !.;
.#();
}
#() {
. = !.;
.#();
}
#() {
.(, .({
: .,
: .,
}));
}
() {
html`;
}
styles = css`;
}
;
{
{
: ;
}
}
Activity Log App
@customElement('my-activity-log-app')
export class MyActivityLogAppElement extends UmbLitElement {
@state()
private _activities: Array<{ action: string; date: string }> = [];
async connectedCallback() {
super.connectedCallback();
await this.#loadActivities();
}
async #loadActivities() {
const response = await fetch('/api/user/activities');
this._activities = await response.json();
}
render() {
return html`
<uui-box headline="Recent Activity">
<uui-table>
<uui-table-head>
<uui-table-head-cell>Action</uui-table-head-cell>
<>Date
;
}
}
Connected Accounts App
const manifest: ManifestUserProfileApp = {
type: 'userProfileApp',
alias: 'My.UserProfileApp.ConnectedAccounts',
name: 'Connected Accounts',
element: () => import('./connected-accounts.element.js'),
meta: {
label: 'Connected Accounts',
pathname: 'connected-accounts',
},
};
Meta Properties
| Property | Description |
|---|
label | Tab label displayed in profile |
pathname | URL path segment for deep linking |
Accessing User Context
import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user';
this.consumeContext(UMB_CURRENT_USER_CONTEXT, (context) => {
this.observe(context.currentUser, (user) => {
console.log(user?.name, user?.email, user?.unique);
});
});
That's it! Always fetch fresh docs, keep examples minimal, generate complete working code.