# Sidebar extension quickstart

Sidebar extension quickstart, with a step by step explanation on how to build a Google SERP Preview Sidebar UI Extension.

## Introduction

**Sidebar UI Extensions** allows you to add custom widgets to Hygraph content editor sidebar.

You can add widgets to interact with specific fields on your editor like translations, to display information from 3rd party services, or to just display read-only information such as analytics data.

## What you will build

We will be building **Google SERP Preview** Sidebar UI Extension. It will display a preview of how your content would appear on Google Search Results.

You will also learn how to add custom configurations, like an API Key to connect to a 3rd party service provider, or a configuration to the widget instance like Background Color.

[Video](https://www.youtube.com/watch?v=7k4kDf7zTfQ)

## Prerequisites

To complete this tutorial:

- You need the latest LTS version of Node.js installed on your machine. If you don't have it, you can [download it here](https://nodejs.org/en/download/)
- You should be comfortable using a command line tool and any IDE or text editor of your choice
- You should be familiar with JavaScript and React
- You need a free Hygraph account and a project. You can [signup here](https://app.hygraph.com/signup).

**Note:**
  If you're new to Hygraph, [create a
  project](https://app.hygraph.com/create?template=da55760a30f64230904493051ce39062)
  using the Blog Starter template

## What you will learn

In this tutorial, you will learn:

- How to create a Sidebar UI Extension
- How to run and test Sidebar Extension UI Extension on your local development environment
- How to add Sidebar UI Extension to your Schema
- How to add custom configuration to your Extension, like an API Key
- How to deploy your Sidebar UI Extension to Vercel
- How to install and use your Sidebar UI Extension in production

## Step 1: Creating a UI extension

**1. Create React project**

```bash
# create a project with npm
npx create-react-app uix-google-serp-preview

# change directory
cd uix-google-serp-preview
```

Now, open the project in the code editor of your preference.

**2. Create a new React component**

```jsx
// src/extensions/GoogleSerpPreview.js

const SerpPreview = () => {
  return <div>Google Serp Preview</div>;
};

const GoogleSerpPreview = () => {
  return <SerpPreview />;
};

export default GoogleSerpPreview;
```

**3. Import the component into your app**

```jsx
// src/App.js

import GoogleSerpPreview from './extensions/GoogleSerpPreview';

function App() {
  return <GoogleSerpPreview />;
}

export default App;
```

**Note:**

You can replace all content of App.js with the code above

**4. Run the app locally**

```
npm run start
```

By visiting [http://localhost:3000](http://localhost:3000) on your browser, you should see a very basic HTML input field.

Now, let's transform it into a Hygraph UI Extension!

## Step 2: Using Hygraph React SDK

**1. Installing the React SDK**

In order to transform it into a UI Extension, you must install Hygraph React SDK as a dependency on your project. You can do it running the following command on your Terminal:

```bash
yarn add @graphcms/uix-react-sdk
```

**2. Adding React SDK**

Now, let's import some SDK components and hooks from Hygraph SDK.

Start with importing the `Wrapper` component and `useFormSidebarExtension` hook from the library inside your React application.

You should add the following code at the top of the `GoogleSerpPreview.js` file.

```jsx
// src/extensions/GoogleSerpPreview.js

import { Wrapper, useFormSidebarExtension } from '@graphcms/uix-react-sdk';
```

Then, add `useFormSidebarExtension` hook into `SerpPreview` and adjust the code accordingly, like the following example:

```jsx
import { Wrapper, useFormSidebarExtension } from '@graphcms/uix-react-sdk';

const SerpPreview = () => {
  const { extension } = useFormSidebarExtension();

  return (
    <>
      <h3>{extension.name}</h3>
      <div>{extension.description}</div>
    </>
  );
};
```

Then, we need to add the [extension declaration](https://hygraph.com/classic-docs/ui-extensions/sidebar-extension/declaration):

```jsx
const declaration = {
  extensionType: 'formSidebar',
  name: 'Google SERP Preview',
  description: 'Preview your content on Google',
};
```

**Note:**
  UI extensions declaration must be
  [re-loaded](https://hygraph.com/classic-docs/ui-extensions/getting-started/extension-declaration#applying-declaration-changes)
  every time the declaration changes.

Finally, let's wrap our custom input field with the `Wrapper` component. Remember to pass in declaration:

```jsx
const GoogleSerpPreview = () => {
  return (
    <Wrapper declaration={declaration}>
      <SerpPreview />
    </Wrapper>
  );
};

export default GoogleSerpPreview;
```

Your complete custom UI Extension code should look like this:

```jsx
// src/extensions/GoogleSerpPreview.js

import { Wrapper, useFormSidebarExtension } from '@graphcms/uix-react-sdk';

const SerpPreview = () => {
  const { extension } = useFormSidebarExtension();

  return (
    <>
      <h3>{extension.name}</h3>
      <div>{extension.description}</div>
    </>
  );
};

const declaration = {
  extensionType: 'formSidebar',
  name: 'Google SERP Preview',
  description: 'Preview your content on Google',
};

const GoogleSerpPreview = () => {
  return (
    <Wrapper declaration={declaration}>
      <SerpPreview />
    </Wrapper>
  );
};

export default GoogleSerpPreview;
```

```js
// App.js

import GoogleSerpPreview from './extensions/GoogleSerpPreview';

function App() {
  return (
    <div className="App">
      <GoogleSerpPreview />
    </div>
  );
}

export default App;
```

**3. Testing UI extension on Localhost**

At this point, you should see the "SDK connection error, check logs" message in your browser. The reason is that it's expected to be running from Hygraph application. So, you should just ignore this message for now.

Now, let's install and test your new Sidebar UI Extension on localhost by following these steps:

1.  Go to [https://app.hygraph.com](https://app.hygraph.com) and open any existing project

          **Note:**

          If you don't have a project yet, [use the Blog starter](https://app.hygraph.com/create?template=da55760a30f64230904493051ce39062)

2.  Navigate to **Project Settings > UI Extensions**
3.  Click on **Add UI Extension** button
4.  On **Extension URL** field, enter [http://localhost:3000](http://localhost:3000)
5.  Click on **Run compatibility test** button
6.  Finally, click on **Authorize & Install**.

If everything went well, you should see something like this:

![UI Extension Install](https://hygraph.com/images/classic-docs/ui-extensions/building-ui-extensions/ui-extension-install.png)

## Step 3: Adding your sidebar UI extension to a schema

Now, it's time to use your new Sidebar UI Extension.

Follow these steps:

1. Go to **Schema**
1. On the left, click on the model you want to add the new Sidebar UI Extension
1. Now, click on Sidebar tab
1. On the right, under Custom Widgets section, you should see your new Sidebar UI Extension
1. Click on Google Serp Preview to add the widget to the sidebar
1. Enter the display name (Optional)
1. Finally, click on **Create** button

**Note:**

You can reorder your widget to any position in the sidebar. You can also remove other widgets.

## Step 4: Using your sidebar UI extension

1. On the left navigation, go to **Content**
2. Select the model you've added the Sidebar UI extension in the previous step
3. Click on **Create Item** button on the top right corner or **Edit** and existing one

You should see Google Serp Preview in the sidebar. Now, let's add some funcionality to that!

## Step 5: Adding interaction between widget and content editor

First, let's add some styling to the widget, so that it looks like Google Search Results.

Go back to your Code Editor, open `src/extensions/GoogleSerpPreview.js`, and change `SerpPreview` component like so:

```js
// src/extensions/GoogleSerpPreview.js

const SerpPreview = () => {
  const { extension } = useFormSidebarExtension();

  return (
    <div
      style={{
        padding: '10px',
        backgroundColor: '#fff',
      }}
    >
      <div
        style={{
          fontSize: '12px',
          marginBottom: '5px',
        }}
      >
        website.com
      </div>
      <div
        style={{
          fontSize: '16px',
          fontWeight: 'bold',
          color: 'blue',
          marginBottom: '5px',
        }}
      >
        Title here
      </div>
      <div>This is the description</div>
    </div>
  );
};
```

The widget should look like this:
![Google SERP Preview Sidebar Widget](https://hygraph.com/images/classic-docs/ui-extensions/sidebar-extension/google-serp-preview-sidebar-ui-extension.png)

Now, we need to display three information from the current content: Site URL, title, and description. Therefore, we should do two things:

1. Pick site URL
2. Map content title and description to be displayed in the widget

For that, we'll add custom settings to our Sidebar UIX: global and instance settings. Both should be added to extension declaration.

### Step 5.1: Displaying site URL

Once site URL is the same for the whole website, we'll add it to the extension declaration as a global configuration.

On your code editor, add the following code to extension declaration:

```js
// src/extensions/GoogleSerpPreview.js

const declaration = {
  extensionType: 'formSidebar',
  name: 'Google SERP Preview',
  description: 'Preview your content on Google',
  config: {
    SITE_URL: {
      type: 'string',
      displayName: 'Site URL',
      required: true,
    },
  },
};
```

Then, change `SerpPreview` component like so:

```js
const SerpPreview = () => {
  const { extension } = useFormSidebarExtension();
  const siteUrl = extension.config.SITE_URL;

  return (
    <div
      style={{
        padding: '10px',
        backgroundColor: '#fff',
      }}
    >
      <div
        style={{
          fontSize: '12px',
          marginBottom: '5px',
        }}
      >
        {siteUrl}
      </div>
      <div
        style={{
          fontSize: '16px',
          fontWeight: 'bold',
          color: 'blue',
          marginBottom: '5px',
        }}
      >
        Title here
      </div>
      <div>This is the description</div>
    </div>
  );
};
```

1. Go back to your browser and open your project dashboard
2. Go to **Project Settings > UI Extension**
3. On Google Serp Preview, click on the **three dots** and then click on **Edit**
4. Click **Refresh** next to the **Edit** button

Now, you should see the new Site URL field. Once it's a required one, enter any URL and hit the **Update** button.

Finally, go to any content and the URL should appear in the widget.

### Step 5.2: Displaying content title and description

Now, you should map the content fields that you want to display in the widget as Title and Description. Therefore, we'll add sidebar instance configuration, which you allow you to set these fields for each model.

Go back to `GoogleSerpPreview.js` in your code editor and do the following steps:

Import `useState` and `useEffect` hooks at the top of the file:

```js
import { useState, useEffect } from 'react';
```

Then, change `SerpPreview` component like the following code:

```js
const SerpPreview = () => {
  const {
    extension,
    form: { subscribeToFieldState },
  } = useFormSidebarExtension();
  const [title, setTitle] = useState('This is the title');
  const [description, setDescription] = useState('This is the description');

  const siteUrl = extension.config.SITE_URL;
  const sidebarConfig = extension.sidebarConfig;

  useEffect(() => {
    const unsubscribe = async () => {
      await subscribeToFieldState(
        sidebarConfig.TITLE_FIELD,
        (state) => {
          setTitle(state.value);
        },
        { value: true }
      );
    };
    return () => unsubscribe();
  }, [subscribeToFieldState, sidebarConfig.TITLE_FIELD]);

  useEffect(() => {
    const unsubscribe = async () => {
      await subscribeToFieldState(
        sidebarConfig.DESCRIPTION_FIELD,
        (state) => {
          setDescription(state.value);
        },
        { value: true }
      );
    };
    return () => unsubscribe();
  }, [subscribeToFieldState, sidebarConfig.DESCRIPTION_FIELD]);

  return (
    <div
      style={{
        padding: '10px',
        backgroundColor: '#fff',
      }}
    >
      <div
        style={{
          fontSize: '12px',
          marginBottom: '5px',
        }}
      >
        {siteUrl || 'website.com'}
      </div>
      <div
        style={{
          fontSize: '16px',
          fontWeight: 'bold',
          color: 'blue',
          marginBottom: '5px',
        }}
      >
        {title || 'Title here'}
      </div>
      <div>{description?.substring(0, 155) || 'Description here'}...</div>
    </div>
  );
};
```

Finally, change extension `declaration` like so:

```js
const declaration = {
  extensionType: 'formSidebar',
  name: 'Google SERP Preview',
  description: 'Preview your content on Google',
  config: {
    SITE_URL: {
      type: 'string',
      displayName: 'Site URL',
      required: true,
    },
  },
  sidebarConfig: {
    TITLE_FIELD: {
      type: 'string',
      displayName: 'Title Field',
      required: true,
    },
    DESCRIPTION_FIELD: {
      type: 'string',
      displayName: 'Description Field',
      required: true,
    },
  },
};
```

Let me explain the code above:

- `sidebarConfig` is the object that stores sidebar configuration data. By declaring that, you should see two fields on sidebar widget dialog, where you will be able to enter the field names for title and description, respectively.
- `form.subscribeToFieldState` is a method from the Hygraph SDK to interact with form fields in the content editor. In this case, we'll update Google Serp Preview widget while user update information in the fields that stores Title and Description. You'll see that happening in a moment.

Once we've updated extension declaration again, we need to refresh UI Extension installation.

1. On Hygraph app, go to **Project Settings > UI Extension**
1. On Google Serp Preview, click on the **three dots** and then click on **Edit**
1. Click **Refresh** next to the **Edit** button
1. Finally, click on **Update**

Now, let's map Schema fields to the sidebar widget:

1. Go to **Schema**
1. Click on the model you've added the widget
1. Click in the pencil icon to edit widget

You should see 2 new fields: Title and Description. You just need to enter the `appId` of the fields you want to display as Title and Description, respectively. Then, click **Update**.

Finally, go to **Content** and click on any existing content to edit it or click on Create Item.

As you type in the Title or Description fields, you should see it being updated in realtime on Google Serp Preview widget!

## Step 6: Deploying your UI extension

To use your UI Extension in a live website or application, you should host it somewhere on the internet. For the sake of this tutorial, we will deploy it on Vercel. But you can use any hosting service.

Do the following steps:

1. Open your Terminal
2. Navigate into your project root directory and run `npx vercel`

```bash
cd google-serp-preview-uix
npx vercel
```

1. Follow the step-by-step guide on your Terminal
2. Once it's deployed, the extension URL will be automatically copied to your clipboard
3. Open your project dashboard on your browser
4. Go to **Project Settings > UI Extension**
5. On Hello UIX World, click on the **three dots,** then click on **Edit**
6. Click on **Edit** button next to the Extension URL field
7. Replace **Extension URL** field with the new URL
8. Click on the **OK** button
9. Finally, click on the **Update** button

## Congratulations!

You've just learned how to build **Sidebar UI Extensions** for Hygraph!

Take a look into these [UI extensions examples](https://github.com/hygraph/hygraph-examples#ui-extensions) for inspiration.

**Additional resources**

- [React SDK](https://hygraph.com/classic-docs/ui-extensions/libraries/react-sdk)
- [Extension declaration](https://hygraph.com/classic-docs/ui-extensions/getting-started/extension-declaration)
- [Interacting with the form and other fields](https://hygraph.com/classic-docs/ui-extensions/getting-started/interacting-with-fields)
