This control allows you to render a user persona that, when clicked or hovered, opens the native Microsoft 365 profile card — the same one used throughout SharePoint, Teams, and Outlook.
Building Rich User Profile Cards in SPFx with PnP LivePersona
One of the most useful controls in the PnP SPFx React Controls Library is LivePersona.
This control allows you to render a user persona that, when clicked or hovered, opens the native Microsoft 365 profile card — the same one used throughout SharePoint, Teams, and Outlook.
Official documentation:
LivePersona Official Documentation
This makes it extremely useful for:
- Employee directories
- Approval workflows
- Document ownership displays
- Project team pages
- Contact cards inside custom web parts
- Knowledge management portals
Why LivePersona Matters
Normally, in SPFx, displaying user data means:
- Fetching profile information
- Rendering UI manually
- Handling images
- Building links to profile pages
With LivePersona, Microsoft already does all of this for you.
When you provide the UPN:
user@company.com
Microsoft 365 automatically resolves:
- Name
- Job title
- Department
- Manager
- Contact info
- Organization chart
- Teams status
- Delve card
- Presence
That is a huge productivity gain.
Architecture
The flow is simple:
SPFx Context ↓ServiceScope ↓LivePersona ↓Microsoft 365 Profile Card
The important part here is:
serviceScope
This allows the PnP control to use internal SharePoint services.
The Complete Component
This is the final working example.
import * as React from 'react';import { Persona } from '@fluentui/react/lib/Persona';import { LivePersona } from '@pnp/spfx-controls-react/lib/LivePersona';import { ServiceScope } from '@microsoft/sp-core-library';export interface ILivePersonaWpProps { serviceScope: ServiceScope;}const LivePersonaWp: React.FC<ILivePersonaWpProps> = ({ serviceScope }) => { return ( <LivePersona upn="edvaldo@kljhgg.com" template={ <Persona text="Edvaldo Filho" secondaryText="edvaldo@kljhgg.com" coinSize={48} /> } serviceScope={serviceScope as any} /> );};export default LivePersonaWp;
Understanding the Imports
React
import * as React from 'react';
Base React dependency.
Persona
import { Persona } from '@fluentui/react/lib/Persona';
The visual card used as the base rendering.
This comes from Fluent UI React.
Important:
Use Fluent UI v8.
Not:
fluentui/react-components
because that is Fluent UI v9.
LivePersona
import { LivePersona } from '@pnp/spfx-controls-react/lib/LivePersona';
This wraps the Persona and adds Microsoft 365 live profile behavior.
Source:
PnP SPFx React Controls
ServiceScope
import { ServiceScope } from '@microsoft/sp-core-library';
This provides SharePoint dependency injection.
LivePersona depends on it.
Props Interface
export interface ILivePersonaWpProps { serviceScope: ServiceScope;}
We pass the SharePoint service scope into the React component.
Without it:
LivePersona will not initialize correctly.
The UPN
upn="edvaldo@ekis.com.br"
UPN = User Principal Name.
This is how Microsoft 365 identifies the user.
Usually:
email = UPN
But not always.
Example:
display email: edvaldo@ekis.com.brUPN: edvaldo.filho@tenant.onmicrosoft.com
The UPN must match the actual Microsoft 365 account.
Template Rendering
This is the visual part:
template={ <Persona text="Edvaldo Filho" secondaryText="edvaldo@com" coinSize={48} />}
Properties:
| Property | Purpose |
|---|---|
| text | Main display name |
| secondaryText | Secondary information |
| coinSize | Avatar size |
Why as any Was Needed
In this project, TypeScript produced:
Type 'ServiceScope' is not assignable to type 'ServiceScope'
This happens when:
Multiple SPFx core library versions exist in node_modules
Typical structure:
node_modules/@microsoft/sp-core-librarynode_modules/@pnp/spfx-controls-react/node_modules/@microsoft/sp-core-library
Since ServiceScope has private members, TypeScript treats them as different types.
Temporary fix:
serviceScope={serviceScope as any}
Recommended long-term fix:
npm dedupeRemove-Item node_modules -Recurse -ForceRemove-Item package-lock.json -Forcenpm install
Passing ServiceScope from the Web Part
In the SPFx web part:
const element: React.ReactElement<ILivePersonaWpProps> = React.createElement( LivePersonaWp, { serviceScope: this.context.serviceScope });
This is mandatory.
What Happens at Runtime
When rendered:
User sees Persona ↓User clicks or hovers ↓Microsoft Profile Card opens ↓Graph + SharePoint profile data load
The user can then see:
- Contact details
- Teams actions
- Manager
- Direct reports
- Organization chart
- Presence
Real World Scenarios
Document Owner
Show who owns a file.
Team Directory
Render all employees.
Project Members
Display stakeholders.
Approval Flow
Show approvers.
Knowledge Base
Display content authors.
Performance Notes
LivePersona is lightweight because:
- It lazy-loads profile data
- Microsoft handles profile rendering
- No custom Graph code required
Best practice:
Use it when user identity matters.
Final Thoughts
LivePersona is one of those controls that looks simple but adds enterprise-grade value immediately.
Instead of manually building user profile components, you leverage Microsoft’s native ecosystem.
Benefits:
- Faster development
- Native M365 integration
- Better UX
- Less code
- Future-proof
For any SPFx solution involving people, this control is highly recommended.
This is WP26 in the PnP Controls roadmap.
