Render GoodData.UI React components in Angular
To use the GoodData.UI React components in an Angular app, wrap each one in an Angular component that renders it with React’s createRoot API. GoodData.UI needs TypeScript 5.8.3 or newer, which Angular supports from version 19.2. See Platform compatibility for the rest of the toolchain.
Install the packages
Install React and the GoodData.UI packages. GoodData.UI works with React 18 and 19:
npm install react react-dom @gooddata/sdk-ui-all @gooddata/sdk-backend-tiger
npm install --save-dev @types/react @types/react-dom
@gooddata/sdk-ui-all re-exports the model, core UI, charts, geo, pivot, filters, and InsightView packages. It doesn’t include @gooddata/sdk-ui-dashboard or the AI packages; install those separately if you need them.
Update the global configuration
- Add
(window as any).global = window;topolyfills.tsto provide the missingglobal. - Add
"skipLibCheck": trueto yourtsconfig.jsonto avoid misleading errors during compilation.
Declare the Angular wrapper component
The wrapper renders a React component into its own DOM node and renders it again when an input changes. You can wrap each GoodData.UI component separately, or write one generic wrapper that takes the React component as an input.
The following example wraps the Kpi component. It creates the backend with ContextDeferredAuthProvider, which uses the GoodData session cookie and redirects to the GoodData sign-in when the session is missing. See Authenticate to the backend for the other options.
// kpi.component.ts
import { createElement } from "react";
import { createRoot, type Root } from "react-dom/client";
import { AfterViewInit, Component, Input, OnChanges, OnDestroy } from "@angular/core";
import { type IFilter, type IKpiProps, Kpi, newMeasure } from "@gooddata/sdk-ui-all";
import {
ContextDeferredAuthProvider,
redirectToTigerAuthentication,
tigerFactory,
} from "@gooddata/sdk-backend-tiger";
// For illustration only: create the backend once in your app and import it here.
const backend = tigerFactory()
.onHostname("https://example.gooddata.com")
.withAuthentication(new ContextDeferredAuthProvider(redirectToTigerAuthentication));
@Component({
selector: "app-kpi",
template: '<span [id]="rootDomId"></span>',
})
export class KpiComponent implements OnChanges, AfterViewInit, OnDestroy {
@Input() measureId = "";
@Input() format?: string;
@Input() workspace = "";
@Input() filters: IFilter[] = [];
public readonly rootDomId = crypto.randomUUID();
private root: Root | null = null;
private getRootDomNode(): HTMLElement {
const node = document.getElementById(this.rootDomId);
if (!node) {
throw new Error(`Node '${this.rootDomId}' not found.`);
}
return node;
}
private getProps(): IKpiProps {
const { workspace, measureId, filters, format } = this;
return {
backend,
workspace,
measure: newMeasure(measureId, (m) => (format ? m.format(format) : m)),
filters,
};
}
private render(): void {
if (!this.root && document.getElementById(this.rootDomId)) {
this.root = createRoot(this.getRootDomNode());
}
this.root?.render(createElement(Kpi, this.getProps()));
}
ngOnChanges(): void {
this.render();
}
ngAfterViewInit(): void {
this.render();
}
ngOnDestroy(): void {
this.root?.unmount();
this.root = null;
}
}
Render charts
Charts fill their container, so give the wrapper’s root DOM node a size:
// column-chart.component.ts
@Component({
selector: "app-column-chart",
template: '<div style="height: 300px" [id]="rootDomId"></div>',
})
export class ColumnChartComponent {
// Same structure as KpiComponent, rendering ColumnChart from @gooddata/sdk-ui-all.
}
Import the chart styles into your global styles, either in styles.css:
@import "@gooddata/sdk-ui-charts/styles/css/main.css";
or in angular.json:
{
"architect": {
"build": {
"options": {
"styles": ["src/styles.css", "node_modules/@gooddata/sdk-ui-charts/styles/css/main.css"]
}
}
}
}
If you use the pivot table, also import @gooddata/sdk-ui-pivot/styles/css/main.css. For more about global styles, see the Angular workspace configuration.
Use the component
Use the wrapped component in your templates and bind its inputs:
<app-kpi workspace="<workspace-id>" measureId="<measure-id>"></app-kpi>
To handle the loading and error states yourself, pass components that render nothing in getProps:
return {
// ...the props above
LoadingComponent: () => null,
ErrorComponent: () => null,
};
See LoadingComponent and ErrorComponent.
Related
Embed GoodData dashboards, visualizations, and the AI Assistant in an Angular app with the Web Components library, custom element schemas, and event listeners.
Add GoodData.UI to an existing React application by installing packages and styles, configuring backend and workspace contexts, CORS, and authentication.
Pick how your GoodData.UI application authenticates against GoodData Cloud or GoodData.CN — the GoodData session cookie, a JWT from your own portal, or an API token — and set it up.
Review officially supported frameworks (React, Web Components) plus Angular, Next.js, and Vue guides, with an external reference for SvelteKit.