Quick start
Scaffold a GoodData.UI React app with app-toolkit, render a dashboard and a chart you define in code, read raw data, apply a theme, and connect your own workspace.
The fastest way to see GoodData.UI working is @gooddata/app-toolkit. It scaffolds a small React app that is already connected to a public demo workspace, so the first chart renders before you configure anything. This tutorial takes you from that command to your own data.
You need Node.js >=24.12.0 (an LTS release is recommended) and npm. You don’t need a GoodData account yet.
Create the project
Run the toolkit and answer its one prompt, the language (TypeScript or JavaScript):
npx @gooddata/app-toolkit@latest init my-analytics-app
The toolkit unpacks the react-app template into my-analytics-app/ and installs its dependencies with npm. Prefer yarn, or want to skip the prompt? Pass --package-manager yarn, --language ts, or --skip-install; npx @gooddata/app-toolkit@latest init --help lists every option.
Start the dev server:
cd my-analytics-app
npm start
Your browser opens on https://127.0.0.1:3000 with a page that says “Hello GoodWorld!” and renders a pie chart of product categories from the demo workspace. That chart is a saved visualization, rendered by the InsightView component. The dev server uses a self-signed certificate, so accept the browser’s warning once. Set the PORT environment variable if 3000 is taken; the dev server fails rather than picking another port.
Look around the project
There is no framework hiding anything. Every file is yours to edit:
my-analytics-app/
├── package.json # Dependencies, scripts, and the gooddata block
├── vite.config.ts # Vite build and dev server, including the API proxy
├── index.html # Page that Vite serves; loads src/index.tsx
├── tsconfig.json # TypeScript configuration (TypeScript projects only)
├── .env # Holds TIGER_API_TOKEN, empty for now
├── .gitignore # Already ignores .env
├── README.md
├── public/ # Static files served as-is, currently the favicon
└── src/
├── index.tsx # React entry point; imports the SDK stylesheets
├── App.tsx # The sample component. Start here
├── backend.ts # Analytical backend instance and auth provider
├── catalog.ts # Generated workspace metadata, don't edit by hand
├── index.css # Styles for the sample page
├── typings.d.ts # Ambient types for SVG and CSS imports and WORKSPACE_ID
└── assets/ # Logo and background image used by the sample page
If you chose JavaScript at the prompt, the same files use .jsx and .js extensions, including vite.config.js, and there’s no tsconfig.json or typings.d.ts.
Three files do most of the work:
src/App.tsx is where you’ll spend your time. It wraps the app in BackendProvider and WorkspaceProvider and renders a single InsightView. Every step below edits this file, and each starts from the sample as the toolkit generated it, so take them in any order.
That’s why the catalog constant is Insights and the component is InsightView.
src/catalog.ts is generated. @gooddata/catalog-export reads your workspace and writes a typed constant for each visualization, dashboard, measure, and attribute. In TypeScript, a mistyped reference then fails at compile time rather than at runtime. Run npm run refresh-md to regenerate it.
package.json carries a gooddata block that the rest of the setup reads:
"gooddata": {
"hostname": "https://public-examples.gooddata.com",
"workspaceId": "demo",
"backend": "tiger",
"catalogOutput": "src/catalog.ts"
}
The dev server proxies API calls to hostname, so the browser never makes a cross-origin request. Vite’s define option injects workspaceId into the app as the WORKSPACE_ID global, and refresh-md writes to catalogOutput. You’ll change the first two values when you connect your own data.
The scripts you’ll use:
npm startstarts the dev server.npm run buildbundles the production version of the app intodist/.npm run refresh-mdregenerates the metadata catalog.
Render a dashboard
The sample renders one saved visualization. Let’s render a whole saved dashboard instead, with its filters, layout, and cross-filtering. Two edits in App.tsx:
Import the
Dashboardcomponent and theDashboardscatalog constants.- import { InsightView } from "@gooddata/sdk-ui-ext"; + import { Dashboard } from "@gooddata/sdk-ui-dashboard"; - import { Insights } from "./catalog.js"; + import { Dashboards } from "./catalog.js";Swap the component in JSX and point it at a dashboard from the catalog.
- <InsightView insight={Insights.ProductCategoriesPieChart} showTitle /> + <Dashboard dashboard={Dashboards._1Overview} />
The dev server reloads and the “1. Overview” dashboard from the demo workspace fills the page. Read more about the Dashboard component.
The catalog constant is handy here, but real apps usually don’t hardcode a dashboard. They list the workspace’s dashboards at runtime and render the one the user picks. Add GoodData.UI to an existing React app shows that pattern.
Build a chart in code
You don’t have to save a visualization first. Any chart component accepts measures and attributes straight from the catalog. Let’s build the same pie chart by hand:
Import
PieChartand the measure and attribute it needs.- import { InsightView } from "@gooddata/sdk-ui-ext"; + import { PieChart } from "@gooddata/sdk-ui-charts"; - import { Insights } from "./catalog.js"; + import { Category_1, PercentRevenue } from "./catalog.js";Replace the component in JSX, passing a measure and an attribute to slice it by.
- <InsightView insight={Insights.ProductCategoriesPieChart} showTitle /> + <PieChart measures={[PercentRevenue]} viewBy={Category_1} />
Every chart component works this way. You pass measures plus one or more attribute props such as viewBy or stackBy. Read more about PieChart and the rest of the visualizations.
Read the raw data
Sometimes you want the numbers rather than a chart, maybe to feed your own visualization library or your app’s business logic. The useInsightDataView hook runs the same execution a chart would and hands you the result.
Create
src/MyTable.tsx, which renders the pie chart’s data as a plain table:import { useInsightDataView } from "@gooddata/sdk-ui"; import { idRef } from "@gooddata/sdk-model"; import { Insights } from "./catalog.js"; export function MyTable() { const { result, error, status } = useInsightDataView({ insight: idRef(Insights.ProductCategoriesPieChart), }); if (error) { console.error(error); return <div>Error...</div>; } if (status !== "success" || !result) { return <div>Loading...</div>; } const slices = result.data().slices().toArray(); return ( <table> <tbody> {slices.map((slice) => { const title = slice.sliceTitles().join(" - "); const value = slice .dataPoints() .map((dp) => dp.rawValue) .join(", "); return ( <tr key={title}> <td>{title}</td> <td>{value}</td> </tr> ); })} </tbody> </table> ); }Render it from
App.tsx:- import { InsightView } from "@gooddata/sdk-ui-ext"; + import { MyTable } from "./MyTable.js";- <InsightView insight={Insights.ProductCategoriesPieChart} showTitle /> + <MyTable />
Read more about useInsightDataView and the rest of the data layer.
Apply a theme
Theming makes embedded analytics look like part of your app rather than a widget dropped in. ThemeProvider loads the theme configured on your GoodData server and lets you override any part of it in code. In App.tsx:
Import
ThemeProvider.+ import { ThemeProvider } from "@gooddata/sdk-ui-theme-provider";Wrap the content inside
WorkspaceProvider.<WorkspaceProvider workspace={workspaceId}> + <ThemeProvider> <div className="app"> ... </div> + </ThemeProvider> </WorkspaceProvider>If your workspace has a custom theme defined on the server, it is applied now.
Override how tooltips look:
- <ThemeProvider> + <ThemeProvider theme={{ + chart: { + tooltipBackgroundColor: "#333", + tooltipBorderColor: "#555", + tooltipLabelColor: "#eaeaea", + tooltipValueColor: "#fff" + } + }}>
Read more about theming and try the theming example in the gallery.
Connect your own data
So far the app has been reading the public demo workspace, the same data a GoodData Cloud or GoodData.CN trial starts with. Point it at your workspace in four steps:
In
package.json, replacehostnameandworkspaceId:- "hostname": "https://public-examples.gooddata.com", - "workspaceId": "demo", + "hostname": "https://<your-gooddata-instance-host>", + "workspaceId": "<your-workspace-id>",Create an API token and paste it into the
.envfile in the project root. The dev-server proxy attaches it to every API call, andrefresh-mduses it too:TIGER_API_TOKEN=<your_api_token>The file is already listed in
.gitignore. Never commit it.Regenerate the catalog for the new workspace:
npm run refresh-mdUpdate
App.tsx. The demo visualization no longer exists in your workspace, so pick one of yours from the regeneratedInsightsconstants:- <InsightView insight={Insights.ProductCategoriesPieChart} showTitle /> + <InsightView insight={Insights.<YourVisualization>} showTitle />
Restart npm start and your own data renders. Putting the token in the dev proxy is fine for development only. Before you ship, switch to the sign-in flow described in Authenticate to the backend and allow your app’s origin in CORS settings.
Next steps
Your app renders your data. From here, pick the guide that matches what you’re building:
- Add GoodData.UI to an existing React app applies the same setup to a React app you already have.
- Embed dashboards drops a full dashboard into your app and configures it.
- Apply theming matches embedded analytics to your brand.
- Filters let users narrow down what a chart or dashboard shows.
- The Angular, Vue, and Next.js guides take GoodData.UI outside a plain React app.
Related
Add GoodData.UI to an existing React application by installing the packages, importing the styles, connecting the analytical backend, and rendering a dashboard your users pick from a list.
Embed a saved dashboard with Dashboard, read its state through selectors, dispatch commands, handle events, configure behavior, and access its store externally.
Shared behavior of GoodData.UI visual components — responsive sizing, the style and data props model, and the visualization lifecycle callbacks.
Fetch execution data as a DataViewFacade from a prepared execution or inline seriesBy/slicesBy configuration.
Apply custom themes to GoodData.UI dashboards and visualizations by wrapping your app in ThemeProvider.