# Widgets

## <mark style="color:red;">Widget Orders</mark>

In certain cases, websites, particularly homepages, require frequent content updates. To eliminate the need for constantly editing code, a widget sorting system is used. This sorting widget is simple, featuring multiple text fields that facilitate the input of widget information and their reordering.

Once the Widget Order scheme has been integrated into Omnitron, the next step is to create a widget that allows for the addition of widget slugs. Instructions for creating this widget can be found below. The names of the created widgets are then entered based on this widget order.

## <mark style="color:red;">Example Widget Order Schema​</mark> <a href="#example-widget-order-schema" id="example-widget-order-schema"></a>

```
{
    "widget_order": {
        "multi": true,
        "data_type": "nested",
        "key": "widget_order",
        "label": "Widget Order",
        "schema": {
            "item_slug": {
                "data_type": "text",
                "key": "item_slug",
                "label": "Widget Slug"
            }
        }
    }
}
```

## <mark style="color:red;">Widget Integration​</mark> <a href="#widget-integration" id="widget-integration"></a>

### <mark style="color:red;">Home Page​</mark> <a href="#home-page" id="home-page"></a>

1. Create a Widget Order named **home-widget-order** and append the corresponding widget slug names to it.
2. To retrieve the widget slug names that have been added, use the **HOME\_WIDGETS** variable's slug name in the `src/widgets/index.ts` file along with the widget's relative path.

   ```
   export const HOME_WIDGETS: {
       [key: string]: ComponentType<WidgetResultType<unknown>>;
   } = {
       // @ts-expect-error Server Component
       'widget-slug-name': dynamic(async () => import('./widget-relative-path.ts'))
       };
   ```

### <mark style="color:red;">Using the Client Server​</mark> <a href="#using-the-client-server" id="using-the-client-server"></a>

1. In **'use client'** components, import the **useGetWidgetQuery** function into the component.

   ```
   import { useGetWidgetQuery } from '@akinon/next/data/client/misc';
   ```
2. Create a variable to hold the imported function, and pass the slug name of the targeted widget to this variable.

   ```
   const { data } = useGetWidgetQuery('slug-name');
   ```
3. Retrieve the widget's data and either send it to another component using `<ComponentName data={data} />` syntax or process it within the component where it was retrieved.

### <mark style="color:red;">Server-Only Components​</mark> <a href="#server-only-components" id="server-only-components"></a>

1. In **'server-only'** components, import the **getWidgetData** function into the component.

   ```
   import { getWidgetData } from '@akinon/next/data/server';
   ```
2. Prepare a type according to the schema of the created widget.

   **Example Type​**

   ```
   type  FooterMenuTitle = {
       value: string;
   };

   type  FooterMenuItem = [{
       kwargs: {
           data_type: 'nested';
           value: {
           is_side_column_item?: SideItem;
           is_target_blank: TargetBlank;
           };
       };
       value: {
           is_side_column_item?: string;
           is_target_blank: string;
           name: string;
           redirect_url: string;
       };
   }];

   type  FooterMenuType = {
       first_column_title: FooterMenuTitle;
       first_column_items: FooterMenuItem;
   };
   ```
3. Create a variable for the imported function. Add the type for the **getWidgetData** function to this variable, and provide the widget's slug name to the function.

   ```
   const data = await getWidgetData<FooterMenuType>({ slug: 'footer-menu' });
   ```
4. Obtain the data for the targeted widget as intended.

At times, there be a need to duplicate the same widget while supplying it with different data. In such situations, creating a widget content is necessary. To use the created widget, import the **dynamic** function.

```
import  dynamic  from  'next/dynamic';
```

After importing, create a variable to invoke the function, and call the function with the relative path of the preferred content as its argument.

```
const FooterMenuContent = dynamic(
    () => import('../views/widgets/footer-menu-content'),
    {ssr: false}
);
```

The `FooterMenuContent` component, which incorporates the desired content, is now available for use. To add this component, simply insert `<FooterMenuContent data={data} />` at the desired location.
