# Set up smart banners

> Link your website, add the Web SDK, design and target a banner, and tell it what each page is about so the app opens on the right screen.

Source: https://docs.grovs.io/docs/links/smart-banners/set-up

The example is Streamly, a video app. Its banner shows on show pages and opens the app on the show the visitor was viewing.

### 1. Link your website domain

Go to **Links → Smart Banners**. Until your site is linked, the page shows a setup checklist. Click **Set up Web SDK** and add the domain your site runs on.

The Web SDK refuses any domain not linked to your project.

### 2. Add the Web SDK to every page

Install [Web SDK 2.1.0](https://docs.grovs.io/docs/sdk/web) or later and configure it on every page where a banner could show:

**npm**

```bash
npm install grovs
```

```javascript
import Grovs from "grovs";

Grovs.configure({ apiKey: "your-api-key" });
```

**Script tag**

```html
<script src="/assets/grovs.global.js"></script>
<script>
  Grovs.configure({ apiKey: "your-api-key" });
</script>
```

Banners are on once `configure()` runs, with no other code. The v1 constructor (`new Grovs(apiKey, …)`) never shows banners.

### 3. Create a banner

Click **Create your first banner**, or the create button above the list. The editor has five sections.

****Details****

- **Name**: for your team only, up to 100 characters.
- **Platforms**: **iOS** (iPhone and iPad), **Android**, or both.

****Targeting****

Leave **Show on all pages** on, or turn it off and list paths:

- **Only on pages**: one path per line, starting with `/`. `*` matches anything, including `/`. For Streamly: `/shows/*`.
- **Except on pages**: optional, and wins over the list above. For example `/checkout*`.

Up to 20 paths in each list, 256 characters each. See [how paths match](https://docs.grovs.io/docs/links/smart-banners/behaviour#which-pages-show-it).

****Content****

| Field           | Limit                                                                                                        |
| --------------- | ------------------------------------------------------------------------------------------------------------ |
| **Title**       | Required, up to 80 characters. Shown on one line                                                             |
| **Subtitle**    | Optional, up to 120 characters. Shown on one line                                                            |
| **Button text** | Required, up to 24 characters. Default `Open`                                                                |
| **App icon**    | Optional. A square PNG, JPEG or WebP, at least 180×180 px, up to 1 MB. Without one, the banner shows no icon |

****Style****

- **Position**: **Top** sits above the page and pushes it down. **Bottom** is fixed to the bottom of the screen, over the page.
- **Colours**: **Background**, **Text**, **Button** and **Button text**, as six-digit hex colours such as `#4F46E5`.

****Behaviour****

- **When a visitor closes it**: how long to hide it after they tap ×. Default 7 days.
- **When a visitor taps Open**: how long to hide it after they tap the button. Default 30 days.

Choose **Until the next page**, 1 to 90 days, or **Custom…** up to 365 days.

**Preview on** shows the banner on an iPhone in Safari and an Android phone in Chrome.

### 4. Publish

Click **Publish** to make the banner live, or **Save draft** to finish later. A live banner reaches visitors within about 10 minutes; the list of banners is cached for that long.

### 5. Tell the banner what the page is about (recommended)

By default the button uses the banner's default link, with no page data. To open the app on the current show, call `setLinkData` on each page:

```javascript
Grovs.smartBanner.setLinkData({ data: { show_id: "4815" } });
```

Your app receives `data` plus `page_path`, the page's path, through its normal deep link callback. Pass your own `page_path` to override it.

In a single-page app, call it again after each route change. A call made before `configure()` is kept and applied once it runs. Values that are `undefined` or `null` are left out, so `{ show_id: show?.id }` is fine.

| Rule          | Limit                                                                |
| ------------- | -------------------------------------------------------------------- |
| Keys          | Up to 20, each up to 64 characters                                   |
| Values        | Strings up to 512 characters, numbers or booleans. No nested objects |
| `page_path`   | Starts with `/`, up to 512 characters                                |
| Whole payload | Up to 4 KB                                                           |

Data over a limit isn't sent: the banner keeps its default link and the SDK logs a warning. The same data always gets the same link, so busy pages don't create a new link per visit. Full API: [Web SDK smart banners](https://docs.grovs.io/docs/sdk/web/smart-banners).

## Make room for the banner

A top banner pushes the page down; a bottom banner floats over it. If your site has its own fixed header or footer, offset it with the two CSS variables the SDK sets on `<html>`:

```css
.site-header { top: var(--grovs-smart-banner-top, 0); }
.cookie-bar { bottom: var(--grovs-smart-banner-bottom, 0); }
```

`--grovs-smart-banner-top` follows the top banner's visible height and shrinks to 0 as the page scrolls it away. Both are removed when the banner goes.

## Control it from code

```javascript
Grovs.smartBanner.hide();      // hide on this page only; not a dismissal
Grovs.smartBanner.refresh();   // run the banner selection again
Grovs.configure({ apiKey: "your-api-key", smartBanner: false }); // never show banners
```

Pass `smartBanner: false` inside your own app's web views, where the banner would otherwise show to people who already have the app.

If you use `requireConsent`, the banner waits for `grantConsent()`.

## Manage banners

The list shows each banner's **Priority**, **Status**, **Platforms**, **Position** and its last 30 days: **Views**, **Clicks**, **CTR**, **Dismisses**, **Dismiss rate** and **Installs**.

- **Order.** When several banners match a page, the one highest in the list shows. Drag a banner, or use **Move to top** and **Move to bottom**. Clear the search and filters to reorder.
- **Status.** **Publish** or **Resume** makes a banner live; **Pause** stops it. **Archive** moves it to the archived banners and out of the order; **Restore** brings it back paused, at the bottom.
- ****Duplicate**** copies every setting and the icon into a new draft with its own default link.
- ****Delete**** removes the banner. Links it already handed out keep working.

## Related

- [How banners behave](https://docs.grovs.io/docs/links/smart-banners/behaviour)
- [Smart banners in the Web SDK](https://docs.grovs.io/docs/sdk/web/smart-banners)
