> ## Documentation Index
> Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a custom widget

> How to create and register a custom widget in Atoti UI using the WidgetPlugin interface and WidgetPluginProps type, including defining the component, key, and initialState, wiring it into the widgetPlugins array, and optionally connecting it to the server via useQueryResult.

To create and add a new widget to Atoti UI, follow these steps:

* Create a new widget file. The widget file holds the code to describe the widget.
* Use pluginWidget to make the new widget available to the UI
* Register the new widget to make it visible for users on the dashboard.

## Widget file

You need to create a widget file that contains the widget component. In this example, you can name it `CustomWidget.tsx`.

```tsx theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
import React, { FC } from "react";

import { WidgetPluginProps } from "@activeviam/atoti-ui-sdk";

export const CustomWidget: FC<WidgetPluginProps> = (props) => {
  return <div>Hello World!</div>;
};
```

`CustomWidget` is a function component that accepts `WidgetPluginProps` and simply returns a `div` containing *"Hello World!"*.

## Plugin widget file

The [**widget plugin**](../../reference/types#widgetplugin) is an object containing all the information needed to register a new widget in Atoti.

Here you can create a second file in the same location and call it `pluginWidgetCustomWidget.ts`.

<Tip>
  **TIP: Naming plugins**

  Take note of the naming here. When defining plugins it's good practice to use a consistent naming convention. For example:

  1. Start with `"plugin"`.
  2. Reveal the type of `"plugin"`. In this case it is a `"widget"`, but it also could have been a `"cell"` or a `"menuItem"`.
  3. Provide the underlying component's name . In this case it is called `"customWidget"`.
</Tip>

This gives a final name of `pluginWidgetCustomWidget`.

`pluginWidgetCustomWidget` contains several properties:

* The **component** is the thing that actually gets displayed. In this case it is `CustomWidget`.
* The **key** is added to each widget to register the widget. This detail can be used to allow users to visualise the widget.
* The **initialState** describes the look of the widget when it is first added to a dashboard.
* icon
* translations

By editing this object, you can change how this widget will look and behave.

```tsx theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
import { WidgetPlugin } from "@activeviam/atoti-ui-sdk";

import { CustomWidget } from "./CustomWidget";

const widgetKey = "customWidget";
export const pluginWidgetCustomWidget: WidgetPlugin = {
  Component: CustomWidget,
  initialState: { widgetKey },
  key: widgetKey,
};
```

## Register a new widget type

To use this widget in your application:

* Open up `plugins.tsx`.
* Add `pluginWidgetCustomWidget` into the `widgetPlugins` array.

<Note>
  The **widgetPlugins** array is eventually passed to the plugin registry. This
  is how Atoti UI knows what plugins it has.
</Note>

```diff theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
+ import { pluginWidgetCustomWidget } from "./pluginWidgetCustomWidget";

...

// Make sure to put it at the top of `widgetPlugins` so it becomes the first widget in the Widgets Panel. This will make it easier to find in the coming steps.
const widgetPlugins: Array<WidgetPlugin> = [

+ pluginWidgetCustomWidget,
  pluginWidgetPivotTable,
  ...
  ]

```

## Connect a widget to the server

Depending on your needs, you may want to add [`useQueryResult`](../../reference/hooks#usequeryresult) to the widget. This hook allows the user to run a query from the dashboard and see the retrieved data displayed in the widget.
If `useQueryResult` is not added to the widget, the widget does not retrieve and display data from the server.
