> Documentation index: https://www.gooddata.ai/docs/gooddata-ui/llms.txt lists every page of these docs as Markdown.

# Embed Analytical Designer

> Install @gooddata/sdk-ui-analytical-designer, load its styles, and render Analytical Designer on your backend in a React application.

API reference: [AnalyticalDesigner()](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-ui-analytical-designer/sdk-ui-analytical-designer.analyticaldesigner/index.md) (function, alpha), [IAnalyticalDesignerCacheReset](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-ui-analytical-designer/sdk-ui-analytical-designer.ianalyticaldesignercachereset/index.md) (interface, alpha)

When you finish, your React application renders Analytical Designer on its own backend instance, with the Analytical Designer styles and a cache that stays fresh when the user refreshes the catalog or edits a metric.

You need a React application with a GoodData backend set up. See [Authenticate to the backend](https://www.gooddata.ai/docs/gooddata-ui/latest/integrations/authentication/index.md).

## [Install the package](https://www.gooddata.ai/docs/gooddata-ui/latest/analytical-designer/embed-analytical-designer/#install-the-package)

The package has the version of the GoodData.UI release it was built with. Install it at the GoodData.UI version your application uses, with the `@gooddata/sdk-*` packages at the same version:

```bash
npm install @gooddata/sdk-ui-analytical-designer@<sdk-version> \
    @gooddata/sdk-backend-base@<sdk-version> \
    @gooddata/sdk-backend-spi@<sdk-version> \
    @gooddata/sdk-backend-tiger@<sdk-version> \
    @gooddata/sdk-ui@<sdk-version>
```

`react` and `react-dom` 18 or later are peer dependencies.

With the same version, your application and Analytical Designer share one copy of each SDK package. They share its React contexts, and your bundle contains one SDK. Analytical Designer also runs next to another SDK version, because it mounts its own backend, workspace, and theme providers, but then the bundle contains two SDK copies.

## [Import the styles](https://www.gooddata.ai/docs/gooddata-ui/latest/analytical-designer/embed-analytical-designer/#import-the-styles)

Importing the package loads no stylesheet. Import the SDK stylesheets Analytical Designer needs, then `main.css`, once, in the module that loads Analytical Designer. Keep this order, so the Analytical Designer rules win over the SDK rules:

```ts
import "@gooddata/sdk-ui-kit/styles/css/main.css";
import "@gooddata/sdk-ui-pivot/styles/css/main.css";
import "@gooddata/sdk-ui-geo/styles/css/main.css";
import "@gooddata/sdk-ui-charts/styles/css/main.css";
import "@gooddata/sdk-ui-filters/styles/css/measureValueFilter.css";
import "@gooddata/sdk-ui-filters/styles/css/dateFilter.css";
import "@gooddata/sdk-ui-filters/styles/css/rankingFilter.css";
import "@gooddata/sdk-ui-filters/styles/css/attributeFilterNext.css";
import "@gooddata/sdk-ui-ext/styles/css/main.css";
import "@gooddata/sdk-ui-semantic-search/styles/css/internal.css";
import "@gooddata/sdk-ui-analytical-designer/styles/css/main.css";
```

If your application already loads the SDK stylesheets, import only `main.css`.

`main.css` sets no page-level rules. Headings, paragraphs, and form controls are styled only inside the Analytical Designer root element. Your page reset, your `html` and `body` styles, and the dialogs that Analytical Designer opens in `document.body` keep your typography.

## [Set up the backend](https://www.gooddata.ai/docs/gooddata-ui/latest/analytical-designer/embed-analytical-designer/#set-up-the-backend)

Analytical Designer runs on your backend instance. If the backend caches, keep its `CacheControl` and give Analytical Designer the resets, so that the catalog **Refresh** button and a metric edit load fresh data:

```ts
// backend.ts
import {
    type CacheControl,
    RecommendedCachingConfiguration,
    withCaching,
} from "@gooddata/sdk-backend-base";
import {
    ContextDeferredAuthProvider,
    redirectToTigerAuthentication,
    tigerFactory,
} from "@gooddata/sdk-backend-tiger";
import { type IAnalyticalDesignerCacheReset } from "@gooddata/sdk-ui-analytical-designer";

let cacheControl: CacheControl | undefined;

export const backend = withCaching(
    tigerFactory()
        .onHostname("https://example.gooddata.com")
        .withAuthentication(new ContextDeferredAuthProvider(redirectToTigerAuthentication)),
    {
        ...RecommendedCachingConfiguration,
        onCacheReady: (control) => {
            cacheControl = control;
        },
    },
);

export const cacheReset: IAnalyticalDesignerCacheReset = {
    resetAll: () => cacheControl?.resetAll(),
    resetCatalogs: () => cacheControl?.resetCatalogs(),
};
```

## [Render the component](https://www.gooddata.ai/docs/gooddata-ui/latest/analytical-designer/embed-analytical-designer/#render-the-component)

Render [`AnalyticalDesigner`](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-ui-analytical-designer/sdk-ui-analytical-designer.analyticaldesigner/index.md) inside a [`BackendProvider`](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-ui/sdk-ui.backendprovider/index.md) and a [`WorkspaceProvider`](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-ui/sdk-ui.workspaceprovider/index.md), or pass `backend` and `workspace` to it. Analytical Designer fills its container, so give the container a height:

```tsx
// App.tsx
import { AnalyticalDesigner } from "@gooddata/sdk-ui-analytical-designer";
import { BackendProvider, WorkspaceProvider } from "@gooddata/sdk-ui";

import { backend, cacheReset } from "./backend.js";
import "./styles.js"; // the stylesheet imports from the previous step

export function App() {
    return (
        <BackendProvider backend={backend}>
            <WorkspaceProvider workspace="<workspace-id>">
                <div style={{ height: "100vh" }}>
                    <AnalyticalDesigner
                        insight="<visualization-id>"
                        config={{ locale: "en-US" }}
                        cacheReset={cacheReset}
                        onEvent={(event) => {
                            if (event.type === "visualizationSaved") {
                                console.log("saved", event.data.insight);
                            }
                        }}
                        onError={(error) => console.error("Analytical Designer cannot start", error)}
                    />
                </div>
            </WorkspaceProvider>
        </BackendProvider>
    );
}
```

Leave out `insight` to open an empty editor for a new visualization.

> **One instance per page:**
> Mounting a second [`AnalyticalDesigner`](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-ui-analytical-designer/sdk-ui-analytical-designer.analyticaldesigner/index.md) while one is mounted throws an error. Unmount the first one before you mount another.

Analytical Designer needs no bundler configuration in Vite or webpack. The metric editor ships its worker bundled with the package.

Where to go next:

- [Handle Analytical Designer events](https://www.gooddata.ai/docs/gooddata-ui/latest/analytical-designer/handle-analytical-designer-events/index.md) – react to saves and cancellations, and send commands.
- [Customize Analytical Designer](https://www.gooddata.ai/docs/gooddata-ui/latest/analytical-designer/customize-analytical-designer/index.md) – hide actions, filter the catalog, theme it, and replace its loading and error screens.
