Would you like to display current user profile information using a SharePoint Framework user profile web part? We can do this by retrieving the current logged-in user’s information from the Azure Active Directory into the SPFx web part using the Microsoft Graph API.
In the example below, you can see that we have retrieved the current logged-in user’s information, including their full name, department, job title, email address, employee ID, manager’s name, and more.

Follow the section below to achieve this!
Create SPFx Solution – Install & Setup Bootstrap, MS Graph API
Let’s first create a SharePoint Framework solution and then implement the Microsoft Graph API requests to fetch the current user’s information from Azure Active Directory.
- Open the Windows command prompt or any other command prompt. Create a directory for the SPFx solution and then navigate into that directory with the following commands.
md SPFXProfileForm
cd SPFXProfileForm
- Run the command below to create the solution using Yeoman.
yo @microsoft/sharepoint
- Now, it will ask you a few details, as shown below. Provide the answers as I have given, or you can change them.
- What is your solution name? spfx-profile-form
- Which type of client-side component to create? WebPart
- Add new Web part to solution spfx-profile-form.
- What is your Web part name? UserDetailsForm
- Which template would you like to use? React

Then, it will take some time, and the SPFx solution will be created, after which you will see a successful message.
- In this solution, we are using Bootstrap for styling. To use Bootstrap classes locally in our solution, run the command below. Once it is installed, run the Code . to open the solution in VS Code.
npm install bootstrap
- We need to import the following statement in the React component (.tsx file) to use Bootstrap CSS.
import 'bootstrap/dist/css/bootstrap.min.css';
- To retrieve the current user information from the AAD using the Microsoft Graph API, we need to do three main things:
- Configure the permissions in the package-solution.json
- Use MSGraphClient
- Request admin consent for those permissions (one-time in the tenant).
- Open the config/package-solution.json file. Add the below permission as shown in the image below.
"webApiPermissionRequests": [
{
"resource": "Microsoft Graph",
"scope": "User.Read"
}
]
Here, the User.Read is the basic Graph permission that allows us to: Retrieve the signed-in user’s profile, including their photo, name, email, job title, department, phone number, and other relevant details.

- Now we’ll update the props interface to include MSGraphClientV3 so that we can use Microsoft Graph within the component.
import { MSGraphClientV3 } from '@microsoft/sp-http';
export interface IUserDetailsFormProps {
description: string;
isDarkTheme: boolean;
environmentMessage: string;
hasTeamsContext: boolean;
userDisplayName: string;
graphClient: MSGraphClientV3;
}
- Next, in the UserDetailsFormWebpart.ts file, we need to use “msGraphClientFactory” to get an instance of “MSGraphClientV3” and pass it to our component via props.
So, import the below statement and update the render() function.
import { MSGraphClientV3 } from '@microsoft/sp-http';
public render(): void {
this.context.msGraphClientFactory.getClient('3').then((client:MSGraphClientV3) =>{
const element: React.ReactElement<IUserDetailsFormProps> = React.createElement(
UserDetailsForm,
{
description: this.properties.description,
isDarkTheme: this._isDarkTheme,
environmentMessage: this._environmentMessage,
hasTeamsContext: !!this.context.sdks.microsoftTeams,
userDisplayName: this.context.pageContext.user.displayName,
graphClient: client
}
);
ReactDom.render(element, this.domElement);
})
}
It allows the component to make Microsoft Graph API calls.

So far, we have seen how to create a SPFx solution using the React framework and how to install and set up Bootstrap, as well as the setup of Microsoft Graph. Let’s see the actual implementation for retrieving user information using Microsoft Graph in the section below.
Read SharePoint Framework CRUD Operations using React
SharePoint Framework – Retrieve User Profile Information
In this section, we will cover retrieving current user information and designing the web part UI using Bootstrap CSS. Follow the steps below!
- Open the UserDetailsForm.tsx file and add the states interface just below the import statements.
interface IUserProfileState {
displayName: string;
department: string;
jobTitle: string;
email: string;
phone: string;
officeLocation: string;
manager: string;
birthday: string;
photoUrl: string;
companyName: string;
hireDate: string;
employeeId: string;
streetAddress: string;
city: string;
stateOrProvince: string;
postalCode: string;
businessPhone: string;
mobilePhone: string;
}
- Then, include the IUserProfileState interface in the export default class and initialize the state in the constructor, as shown in the image below.
export default class UserDetailsForm extends React.Component<IUserDetailsFormProps, IUserProfileState> {
constructor(props: IUserDetailsFormProps) {
super(props);
this.state = {
displayName: '',
department: '',
jobTitle: '',
email: '',
phone: '',
officeLocation: '',
manager: '',
birthday: '',
photoUrl: '',
companyName: '',
hireDate: '',
employeeId: '',
streetAddress: '',
city: '',
stateOrProvince: '',
postalCode: '',
businessPhone: '',
mobilePhone: ''
};
}

In the above image, the state initialization is not fully shown, but you can refer to the provided code and update it accordingly. Don’t get confused.
- Now, we need to import the ResponseType to get the user’s profile photo as a Blob.
import { ResponseType } from '@microsoft/microsoft-graph-client';
- Next, we need to create the componentDidMount() method to fetch user details from AAD using the Microsoft Graph API.
public componentDidMount(): void {
const client = this.props.graphClient;
client.api('/me?$select=displayName,department,jobTitle,mail,userPrincipalName,businessPhones,officeLocation,birthday,companyName,employeeHireDate,employeeId,streetAddress,city,state,postalCode,mobilePhone').get().then((user: any) => {
this.setState({
displayName: user.displayName,
department: user.department,
jobTitle: user.jobTitle,
email: user.mail || user.userPrincipalName,
phone: user.businessPhones?.[0] || '',
officeLocation: user.officeLocation,
birthday: user.birthday
? new Date(user.birthday).toLocaleDateString('en-GB')
: '',
companyName: user.companyName || '',
hireDate: user.employeeHireDate ? new Date(user.employeeHireDate).toLocaleDateString('en-GB') : '',
employeeId: user.employeeId || '',
streetAddress: user.streetAddress || '',
city: user.city || '',
stateOrProvince: user.state || '',
postalCode: user.postalCode || '',
businessPhone: user.businessPhones?.[0] || '',
mobilePhone: user.mobilePhone || ''
});
});
// User's Manager info
client.api('/me/manager').get().then((manager: any) => {
this.setState({
manager: manager.displayName
});
});
// User photo
client.api('/me/photo/$value')
.responseType(ResponseType.BLOB)
.get()
.then((imageBlob: Blob) => {
const imageUrl = URL.createObjectURL(imageBlob);
this.setState({ photoUrl: imageUrl });
})
.catch(() => {
this.setState({ photoUrl: 'https://via.placeholder.com/100' });
});
}
Here,
- client = We get the Microsoft Graph client from this.props.graphClient.
- client.api(‘/me?..’) = Then, we called the Graph API endpoint /me and used the $select parameter to retrieve specific user fields, such as display name, department, job title, etc., and update the states with the fetched details.
- client.api(‘me/manager’) = Here, we call this endpoint to retrieve the current user’s manager name and store it in the state.
- client.api(‘/me/photo/$value’) = This gets the current user’s photo.
- .responseType(ResponseType.BLOB) = It informs the graph to return the image in a binary format.
- URL.createObjectURL(imageBlob) = Converts the Blob to a viewable image URL. If the image fails to load, we use a default placeholder photo.
- Then, update your render() method with the below one. This method displays all retrieved user information in the web part. We’ve also used Bootstrap classes to style the web part UI.
public render(): React.ReactElement<IUserDetailsFormProps> {
return (
<section className={`${styles.userDetailsForm}`}>
<div className="container mt-4">
<div className="card shadow-sm">
<div className="card-header text-white text-center" style={{background: 'linear-gradient(to bottom right, #2c3e50, #4ca1af)',borderTopLeftRadius: '10px', borderTopRightRadius: '10px'}}>
<h4 className="mb-0 fw-bold">Employee Profile</h4>
</div>
<div className="card-body">
<div className="row">
{/* Profile image */}
<div className="col-md-4" style={{
background: 'linear-gradient(to bottom right, #2c3e50, #4ca1af)',
color: 'white',
borderRadius: '10px',
padding: '20px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'start',
minHeight: '100%'
}}>
<img
src={this.state.photoUrl}
alt="User"
className="rounded-circle img-fluid mb-3"
style={{ width: '120px', height: '120px', objectFit: 'cover', border: '2px solid white' }}
/>
<h5 className="mb-1 fw-bold">{this.state.displayName}</h5>
<p className="mb-1">{this.state.jobTitle}</p>
<p>{this.state.department}</p>
</div>
{/*Detailed information */}
<div className="col-md-8">
<div style={{ paddingLeft: '12px' }}>
<div className="mb-4">
<h5 className="bg-light p-2 fw-bold">User Identity</h5>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px', paddingLeft: '30 px'}}>Email:</div><div>{this.state.email}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Mobile Phone:</div><div>{this.state.mobilePhone}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Birthday:</div><div>{this.state.birthday}</div></div>
</div>
<div className="mb-4">
<h5 className="bg-light p-2 fw-bold">Job Information</h5>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Employee ID:</div><div>{this.state.employeeId || 'N/A'}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Company Name:</div><div>{this.state.companyName}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Hire Date:</div><div>{this.state.hireDate}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Business Phone:</div><div>{this.state.businessPhone}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Manager:</div><div>{this.state.manager}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Office Location:</div><div>{this.state.officeLocation}</div></div>
</div>
<div className="mb-4">
<h5 className="bg-light p-2 fw-bold">Contact Information</h5>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Street Address:</div><div>{this.state.streetAddress}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>City:</div><div>{this.state.city}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>State/Province:</div><div>{this.state.stateOrProvince}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Postal Code:</div><div>{this.state.postalCode}</div></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
);
}
In the above method, we fetch all the user information through the state, such as: {this.state.displayName}, {this.state.jobTitle}, {this.state.department},etc. Then, we used the bootstrap classes like:
- <div className=”container mt-4″> = container is a Bootstrap class that provides a responsive fixed-width container. “mt-4” adds top margin to give space above the card.
- <div className=”card shadow-sm”> = The card is a flexible and extensible content container, including options for headers and footers, etc. “shadow-sm” adds a small box shadow.
- <div className=”card-header text-white text-center”…> = Here, “card-header” is a special class for the top section of the card, to make the text color white [text-white], and then to make the text center [text-center], style for the custom gradient background color at the top section.
- <div className=”card-body”><div className=”row”> = “card-body” for the main content area inside the card. row to create two columns left and right inside the card.
- <div className=”col-md-4″> = col-md-4 this column takes 4 out of 12 columns on medium and above the screens. Within this, we are displaying the user’s photo, name, job title, and department.
- <img className=”rounded-circle img-fluid mb-3″> = Here, the round-circle makes the image circular, img-fluid makes the image responsive, and then mb-3 gives a bottom margin to the image.
- <div className=”col-md-8″> = This time it takes 8 out of 12 columns to sit next to the left column, and this div element contains three main sections: user identity, job information, and contact information.
- <h5 className=”bg-light p-2 fw-bold”> = Here, “bg-light” applies a light gray background for the title bars, “p-2” for padding around the heading, then “fw-bold” to make font weight bold.
- <div className=”mb-2 d-flex”><div className=”fw-semibold me-2″> = Here,
- “mb-2” gives the bottom margin between rows,
- “d-flex” makes the label and value display side by side horizontally,
- “fw-semibold” to make the label text font weight semi bold.
- “me-2” adds the margin-end between the label and value.
- So finally, we have a card body with a single row and two columns:
- left (col-md-4)
- right (col-md-8)
- On medium screens and above, it displays side by side; on smaller screens, it displays vertically.
- Here is the final .tsx file code for reference.
import * as React from 'react';
import styles from './UserDetailsForm.module.scss';
import type { IUserDetailsFormProps } from './IUserDetailsFormProps';
import 'bootstrap/dist/css/bootstrap.min.css';
import { ResponseType } from '@microsoft/microsoft-graph-client';
interface IUserProfileState {
displayName: string;
department: string;
jobTitle: string;
email: string;
phone: string;
officeLocation: string;
manager: string;
birthday: string;
photoUrl: string;
companyName: string;
hireDate: string;
employeeId: string;
streetAddress: string;
city: string;
stateOrProvince: string;
postalCode: string;
businessPhone: string;
mobilePhone: string;
}
export default class UserDetailsForm extends React.Component<IUserDetailsFormProps, IUserProfileState> {
constructor(props: IUserDetailsFormProps) {
super(props);
this.state = {
displayName: '',
department: '',
jobTitle: '',
email: '',
phone: '',
officeLocation: '',
manager: '',
birthday: '',
photoUrl: '',
companyName: '',
hireDate: '',
employeeId: '',
streetAddress: '',
city: '',
stateOrProvince: '',
postalCode: '',
businessPhone: '',
mobilePhone: ''
};
}
public componentDidMount(): void {
const client = this.props.graphClient;
client.api('/me?$select=displayName,department,jobTitle,mail,userPrincipalName,businessPhones,officeLocation,birthday,companyName,employeeHireDate,employeeId,streetAddress,city,state,postalCode,mobilePhone').get().then((user: any) => {
this.setState({
displayName: user.displayName,
department: user.department,
jobTitle: user.jobTitle,
email: user.mail || user.userPrincipalName,
phone: user.businessPhones?.[0] || '',
officeLocation: user.officeLocation,
birthday: user.birthday
? new Date(user.birthday).toLocaleDateString('en-GB')
: '',
companyName: user.companyName || '',
hireDate: user.employeeHireDate ? new Date(user.employeeHireDate).toLocaleDateString('en-GB') : '',
employeeId: user.employeeId || '',
streetAddress: user.streetAddress || '',
city: user.city || '',
stateOrProvince: user.state || '',
postalCode: user.postalCode || '',
businessPhone: user.businessPhones?.[0] || '',
mobilePhone: user.mobilePhone || ''
});
});
// User's Manager info
client.api('/me/manager').get().then((manager: any) => {
this.setState({
manager: manager.displayName
});
});
// User photo
client.api('/me/photo/$value')
.responseType(ResponseType.BLOB)
.get()
.then((imageBlob: Blob) => {
const imageUrl = URL.createObjectURL(imageBlob);
this.setState({ photoUrl: imageUrl });
})
.catch(() => {
this.setState({ photoUrl: 'https://via.placeholder.com/100' });
});
}
public render(): React.ReactElement<IUserDetailsFormProps> {
return (
<section className={`${styles.userDetailsForm}`}>
<div className="container mt-4">
<div className="card shadow-sm">
<div className="card-header text-white text-center" style={{background: 'linear-gradient(to bottom right, #2c3e50, #4ca1af)',borderTopLeftRadius: '10px', borderTopRightRadius: '10px'}}>
<h4 className="mb-0 fw-bold">Employee Profile</h4>
</div>
<div className="card-body">
<div className="row">
{/* Profile image */}
<div className="col-md-4" style={{
background: 'linear-gradient(to bottom right, #2c3e50, #4ca1af)',
color: 'white',
borderRadius: '10px',
padding: '20px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'start',
minHeight: '100%'
}}>
<img
src={this.state.photoUrl}
alt="User"
className="rounded-circle img-fluid mb-3"
style={{ width: '120px', height: '120px', objectFit: 'cover', border: '2px solid white' }}
/>
<h5 className="mb-1 fw-bold">{this.state.displayName}</h5>
<p className="mb-1">{this.state.jobTitle}</p>
<p>{this.state.department}</p>
</div>
{/*Detailed information */}
<div className="col-md-8">
<div style={{ paddingLeft: '12px' }}>
<div className="mb-4">
<h5 className="bg-light p-2 fw-bold">User Identity</h5>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px', paddingLeft: '30 px'}}>Email:</div><div>{this.state.email}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Mobile Phone:</div><div>{this.state.mobilePhone}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Birthday:</div><div>{this.state.birthday}</div></div>
</div>
<div className="mb-4">
<h5 className="bg-light p-2 fw-bold">Job Information</h5>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Employee ID:</div><div>{this.state.employeeId || 'N/A'}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Company Name:</div><div>{this.state.companyName}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Hire Date:</div><div>{this.state.hireDate}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Business Phone:</div><div>{this.state.businessPhone}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Manager:</div><div>{this.state.manager}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Office Location:</div><div>{this.state.officeLocation}</div></div>
</div>
<div className="mb-4">
<h5 className="bg-light p-2 fw-bold">Contact Information</h5>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Street Address:</div><div>{this.state.streetAddress}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>City:</div><div>{this.state.city}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>State/Province:</div><div>{this.state.stateOrProvince}</div></div>
<div className="mb-2 d-flex"><div className="fw-semibold me-2" style={{ width: '160px' }}>Postal Code:</div><div>{this.state.postalCode}</div></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
);
}
}
- To test this web part locally, run the command below. Then, it will open the local workbench with the sharepoint site URL you have provided in the serve.json file.
gulp serve
Once you add the web part to the local workbench page, it will appear as shown below.

Now it’s time to deploy this web part to the SharePoint Online app catalog so that we can use it on the SharePoint site.
Deploy SPFx Retrieve User Profile Information Webpart
As mentioned earlier in step 6, after configuring the required permissions and using the MSGraphClient, the next step is to deploy the solution to the App Catalog and request approval from the tenant admin for the Microsoft Graph API permissions.
Note: User.Read is a delegated permission that lets the signed-in user access their own profile and is granted by default, so it doesn’t require admin consent.
Follow the steps below to complete the deployment process.
- Save the file and build the project with the following commands:
gulp clean
gulp build
gulp bundle --ship
gulp package-solution --ship
- Upload the .sppkg file to your SharePoint tenant’s App Catalog or site collection app catalog, based on your requirements. Here, I’m uploaded to the tenant app catalog.
- Once uploaded, a pop-up will appear on the right side. Choose the option based on your requirements under App availability, and click Enable App.

Now, this web part is available in all SharePoint sites. In any SharePoint site, edit the site page and try to add the web part; you will be able to find this web part and add it.
Download the SPFx Solution
Download the SPFx solution from the link below, then run the command below to install all required packages before starting the setup.
npm install
This way, we can easily get the current user information in the SPFx web part using the Microsoft Graph API.
I hope you found this article helpful!, In this article, I explain how to retrieve the current logged-in user information from Azure Active Directory using the Microsoft Graph API Additionally, I also explain how to utilize Bootstrap classes for designing the SPFx web part UI. This way, you can create an SPFx user profile web part.
Also, you may like:
- SPFx Upload File to SharePoint Document Library With Metadata
- Restrict SPFx List View Command Set Extension to Specific List/Library
- SPFx fluent UI react dropdown example
- Create and deploy SharePoint Framework (SPFx) listview command set extension
- SPFx SwatchColorPicker Office UI Fabric React Control example
- How to add new webpart in spfx solution
- Create and Deploy SharePoint Framework (SPFx) extension field customizer
- SharePoint Framework (SPFx) Extensions Application Customizer Example

Hey! I’m Bijay Kumar, founder of SPGuides.com and a Microsoft Business Applications MVP (Power Automate, Power Apps). I launched this site in 2020 because I truly enjoy working with SharePoint, Power Platform, and SharePoint Framework (SPFx), and wanted to share that passion through step-by-step tutorials, guides, and training videos. My mission is to help you learn these technologies so you can utilize SharePoint, enhance productivity, and potentially build business solutions along the way.