Embed PowerBI reports in React application.

Swati Wuppuluri
5 min readFeb 9, 2021

Github:- https://github.com/swati1707/react-powerbi

This blog explains how to embed PowerBI reports in React application.

Prerequisites:-

  • PowerBI pro or premium account
  • PowerBI charts published into your workspace
  • Azure AD service principal or master account

Now before getting into the code, there are some concepts which you need to be clear with before embedding reports into your application.

There are two ways by which we can embed PowerBI dashboards:-

  1. User owns Data:- This approach is for Embedding for your Organization. For this type of embedding, application users need to sign into the PowerBI service to view content.
  2. App owns Data:- This approach is for Embedding for your Customers. For this type of embedding, application users need not have PowerBI account to view dashboards or reports.

Based on the users who’ll be viewing the embedded reports, you need to select one of the above approaches.

In this article, we’ll be looking into the App owns Data approach.

Step 1:- Register an Azure AD application.

To use PowerBI embedded, you need to register an Azure Active Directory application in Azure. The Azure AD app establishes permissions for Power BI REST resources, and allows access to the PowerBI Rest API’s. Your application will use one of the following methods to authenticate against Power BI:

  • Master user account (a Power BI Pro license used for signing in to Power BI)
  • Service principal

After registering your application in Azure portal, you need to give API permissions to the application to access PowerBI services.

Step 2:- Get embedding parameter values

Before embedding reports into your application, you need to have certain parameter values:- Client ID, Report ID, Workspace ID, Client Secret, Dataset ID.

From the Azure AD application, you’ll get Client ID and Client Secret.

Then, navigate to your published reports in your PowerBI workspace. There you’ll get Workspace ID and Report ID.

https://app.powerbi.com/groups/workspace-id/reports/report-id

Then navigate to dataset for the published report in your workspace, there you’ll get dataset id.

https://app.powerbi.com/groups/workspace-id/settings/dataset/dataset-id

Step 3:- Enable workspace access

To enable your Azure AD app access reports, dashboards and datasets in the Power BI service, add the service principal or master user, as a admin to your workspace.

  • Sign in to PowerBI service
  • Go to your workspace. Select workspace access.
  • Add service principal or master user as admin.

Step 4:- Embed your content.

Open VSCode and run below commands:

npx create-react-app react-powerbi
cd react-powerbi
npm install powerbi-client
npm start

Now let’s create app component.

App.jsx

import React from "react";import { service, factories, models, IEmbedConfiguration } from "powerbi-client";import * as config from "./config";const powerbi = new service.Service(factories.hpmFactory, factories.wpmpFactory, factories.routerFactory);
let accessToken = "";let embedUrl = "";let embedToken = "";let reportContainer;let reportRef;let loading;class App extends React.Component {
constructor(props) {super(props);this.state = { accessToken: "", embedUrl: "", error: [], embedToken: "" };
reportRef = React.createRef();loading = (<divid="reportContainer"ref={reportRef} >Loading the report...</div>);}componentDidMount() {if (reportRef !== null) {reportContainer = reportRef["current"];}if (config.workspaceId === "" || config.reportId === "") {this.setState({ error: ["Please assign values for workspace id and report id"] })} else {this.getAccessToken();}}getAccessToken() {const thisObj = this;fetch(" https://login.microsoftonline.com/common/oauth2/v2.0/token", {headers: {"Content-type": "application/x-www-form-urlencoded"},method: "GET",body: {grant_type: "client_credentials",client_id: config.clientId,client_secret: config.clientSecret,scope: "https://analysis.windows.net/powerbi/api/.default"}}).then(function (response) {const errorMessage = [];errorMessage.push("Error occurred while fetching the access token of the report")errorMessage.push("Request Id: " + response.headers.get("requestId"));response.json().then(function (body) {if (response.ok) {accessToken = body["accessToken"];thisObj.setState({ accessToken: accessToken });}else {errorMessage.push("Error " + response.status + ": " + body.error.code);thisObj.setState({ error: errorMessage });}}).catch(function () {errorMessage.push("Error " + response.status + ": An error has occurred");thisObj.setState({ error: errorMessage });});}).catch(function (error) {thisObj.setState({ error: error });})}getEmbedUrl() {const thisObj = this;fetch("https://api.powerbi.com/v1.0/myorg/groups/" + config.workspaceId + "/reports/" + config.reportId, {headers: {"Authorization": "Bearer " + accessToken},method: "GET"}).then(function (response) {const errorMessage = [];errorMessage.push("Error occurred while fetching the embed URL of the report")errorMessage.push("Request Id: " + response.headers.get("requestId"));response.json().then(function (body) {if (response.ok) {embedUrl = body["embedUrl"];thisObj.setState({ accessToken: accessToken, embedUrl: embedUrl });}else {errorMessage.push("Error " + response.status + ": " + body.error.code);thisObj.setState({ error: errorMessage });}}).catch(function () {errorMessage.push("Error " + response.status + ": An error has occurred");thisObj.setState({ error: errorMessage });});}).catch(function (error) {thisObj.setState({ error: error });})}getEmbedToken() {const thisObj = this;fetch("https://api.powerbi.com/v1.0/myorg/GenerateToken" , {headers: {"Authorization": "Bearer " + this.state.accessToken},method: "POST",body: {"datasets": [{"id": config.datasetId}],"reports": [{"id": config.reportId}]}}).then(function (response) {const errorMessage = [];errorMessage.push("Error occurred while fetching the embed token of the report")errorMessage.push("Request Id: " + response.headers.get("requestId"));response.json().then(function (body) {if (response.ok) {embedToken = body["embedToken"];thisObj.setState({ accessToken: accessToken, embedToken: embedToken });}// If error message is availableelse {errorMessage.push("Error " + response.status + ": " + body.error.code);thisObj.setState({ error: errorMessage });}}).catch(function () {errorMessage.push("Error " + response.status + ": An error has occurred");thisObj.setState({ error: errorMessage });});}).catch(function (error) {thisObj.setState({ error: error });})}render() {if(this.state.accessToken !== "") {this.getEmbedToken();this.getEmbedUrl();}if (this.state.error.length) {reportContainer.textContent = "";this.state.error.forEach(line => {reportContainer.appendChild(document.createTextNode(line));reportContainer.appendChild(document.createElement("br"));});}else if (this.state.accessToken !== "" && this.state.embedUrl !== "" && this.state.embedToken !== "") {const countryFilter = {$schema: "http://powerbi.com/product/schema#basic",target: {table: "Country",column: "country_name"},operator: "In",values: [INDIA],filterType: 1,requireSingleSelection: false}const embedConfiguration = {type: "report",tokenType: models.TokenType.Embed,accessToken,embedUrl,id: config.reportId,settings: {background: models.BackgroundType.Transparent}};const report = powerbi.embed(reportContainer, embedConfiguration);report.off("loaded");report.on("loaded", function () {const existingFilters = report.getFilters().then(function(response) {const newFiltersArr = [...response, countryFilter];report.setFilters(newFiltersArr);});});report.off("rendered");
report.on("rendered", function () {console.log("Report render successful");});report.off("error");
report.on("error", function (event) {const errorMsg = event.detail;console.error(errorMsg);});}return loading;}componentWillUnmount() {powerbi.reset(reportContainer);}}export default App;

Add dataset Id, report ID, client ID and client Secret in config file.

config.js

export const clientId = "";export const clientSecret = '';export const reportId = "";export const workspaceId = "";export const datasetId = "";

The app component consists of the code to call API’s to get access token , embed token and embed url which are required to embed PowerBI report into your application.

You can also add extra filters into your published report at the time of embedding. Check for report onloaded function in app component:

report.on("loaded", function () {const existingFilters = report.getFilters().then(function(response) {const newFiltersArr = [...response, countryFilter];report.setFilters(newFiltersArr);});});

And that’s it…You’ve embedded PowerBI report into your React application.

--

--