# Smart Banners

A smart banner is a bar on your website that lets visitors open the page in your
app. A tap on it is a regular Detour link, so store redirects, deferred matching
and attribution work without extra setup.

This page describes how to add the banner script to your site, how to build a
banner in the dashboard, how Detour picks which banner to show, and how
impressions and taps are counted.

:::note[Plan requirement]
Smart banners are available on **Starter** and above, where you build each
banner from a template. On **Scale** and above you can also write the banner in
your own HTML. See [Billing & Payments](https://detour.swmansion.com/docs/platform/fundamentals/billing).
:::

---

## Install the script

One snippet per app, pasted once into your site's `<head>`. The dashboard shows
it filled in under the app's **Smart Banners** section:

```html
<script
  async
  src="https://<your-org>.godetour.link/banner/v1.js"
  data-detour-app="<your-app-hash>"
></script>
```

Two properties of the snippet:

- **It carries the app hash, not a link URL.** The link base, the layouts and
  the targeting rules all arrive from Detour on each page view, so changing a
  banner in the dashboard takes effect without changing your site again.
- **It loads from your organization's own link subdomain**, not from a shared
  host used by every Detour customer. A shared marketing-script host is the kind
  of host privacy blocklists tend to cover, and a per-organization one is not.

The script is `async` and every part of it is guarded. If anything fails, no
banner is shown and your page is unaffected.

:::note[Smart banners and custom domains]
A banner tap opens the app's ordinary Detour link, so it uses whichever host the
app currently serves links from, a [custom domain](https://detour.swmansion.com/docs/platform/advanced/custom-domain)
included. The script tag is the exception: it always loads from your
organization's `.godetour.link` subdomain, and stays there when a custom domain
is attached, unassigned or reverted. The snippet therefore does not need to be
changed.
:::

### Restrict where it may run

By default the banner renders **anywhere the snippet is pasted**, including sites
you did not paste it on yourself. Narrow that with the **Websites allowed to show
it** list on the same page. Subdomains count as the same website, so listing
`example.com` also covers `www.example.com`.

The check runs in the browser before anything is rendered, and again on the
server before an impression is recorded.

---

## Build a banner

Each banner is built in a four-step wizard, and an app can have several. Statuses
are **Draft**, **Live**, **Paused**, plus **Scheduled** and **Ended**, which are
derived from a live banner's date window.

### 1. Who sees it

| Setting          | Options                                          |
| ---------------- | ------------------------------------------------ |
| Pages            | Every page, or only pages that match your rules  |
| Device           | The platforms the banner can show on             |
| Language         | Any, English, Polish, German, Spanish or French  |
| Country          | Worldwide, EU or US                              |
| Desktop behavior | Nothing, a link, or a QR code                    |

**Page rules** check the full address, path and query, with one of the operators
**contains**, **does not contain**, **is exactly** or **starts with**.

**Language** is read from the browser. The region subtag is ignored.

**Desktop behavior** applies because a computer cannot install the app. A link
can point to a URL of your own or to the store's web page. A QR banner has no tap
target, because the visitor continues on their phone.

### 2. Where it goes

Choose the screen a tap opens:

| Destination          | What opens                                        |
| -------------------- | ------------------------------------------------- |
| Same page in the app | The app screen mapped from the website path       |
| A fixed screen       | The same screen for every tap                     |

For **Same page in the app**, each `*` in a website path captures a part, and the
captures fill the `*` in the app screen in order:

```text
Rule:    /products/*       →  /product/*
Result:  /products/shoes   →  /product/shoes
```

Set an **unmatched screen** for addresses that no rule covers.

You can also set:

- **Campaign** — your own label, sent as `utm_campaign`.
- **Extra link parameters** — added to the link.

Every banner link is your app's link plus the screen, with three parameters that
Detour adds:

| Parameter      | Value                                                 |
| -------------- | ----------------------------------------------------- |
| `utm_source`   | Always `smart_banner`                                 |
| `utm_campaign` | The campaign field, or the banner name if it is empty |
| `dtb`          | The banner ID, used to count taps                     |

:::note[These three parameters are reserved]
Extra link parameters cannot overwrite them, and a screen that sets one loses that
value. Taps are counted by `dtb`, not `utm_campaign`, because a campaign label can
be renamed and reused across banners.
:::

### 3. How it looks

Four ready-made layouts, **top**, **bottom**, **floating** and **interstitial**,
each with headline, subline, button text, app icon, colors, corner radius, text
size and shadow. The editor preview renders the banner exactly as visitors see it.

The banner mounts into a shadow root on your page: your stylesheet does not apply
inside it, and its styles do not apply to your site. The interstitial layout
locks page scrolling while it is open and always shows a visible close control.

#### Custom HTML

On **Scale and Enterprise**, a banner can be written as raw HTML instead. Two
markers connect your markup to Detour:

| Marker                | Meaning                                                                   |
| --------------------- | ------------------------------------------------------------------------- |
| `{{LINK}}`            | Replaced with the resolved link. Every occurrence, so put it in `href="…"`. |
| `id="detour-banner-close"` | Any element carrying this id becomes the dismiss control.            |

The same limits as the [custom redirect pages](https://detour.swmansion.com/docs/platform/advanced/custom-html-redirects#limits-and-security)
apply: **50 KB** maximum, no scripts, and external assets served over HTTPS from
your own host.

If the plan later drops below Scale, the saved markup is kept but not served.
The banner falls back to its template, and starts rendering again on an
upgrade. A custom-HTML banner with empty markup is skipped rather than shown as
an empty box.

### 4. When it runs

- **Schedule** — always, or between two dates. Outside the window a live banner
  reports as **Scheduled** or **Ended** and is not served.
- **Dismissal period** — how long a dismissal lasts, either the session, an hour,
  a day, a week, or forever.
- **Frequency cap** — show it at most once, three times, five times, or without
  a cap.

Both are remembered in the visitor's own browser storage. In a browser that
blocks storage the banner is shown again. Nothing else is affected.

---

## How one banner is chosen

Banners are evaluated in the order you arrange them and **the first match wins**.
A visitor sees one banner or none, never two.

A banner is skipped when its rules do not match, when the visitor dismissed it and
the dismissal has not expired, or when the frequency cap is reached.

:::note[Country targeting fails closed]
If the country lookup is unavailable, a banner narrowed to a region is **not**
shown. Showing it worldwide instead would deliver the banner outside the
configured region, with no signal in the dashboard.
:::

On a single-page app, call `window.DetourBanner.refresh()` after a route change so
page rules and the destination are re-evaluated for the new address.

---

## Impressions, taps and billing

The banner list shows **seen** and **taps** per banner over the last 30 days.

- **Impressions are free.** They are reported as a daily aggregate and are not
  metered.
- **A tap costs a click**, through the ordinary redirect flow, the same click
  your plan limit and analytics already count. See
  [Click Handling & Redirect Flow](https://detour.swmansion.com/docs/platform/architecture/click-handling).

Taps are counted from the `dtb` parameter on the click, so they also appear in
your link analytics alongside every other parameter breakdown.

## Related pages

[Custom HTML Redirects](https://detour.swmansion.com/docs/platform/advanced/custom-html-redirects/)
  [Custom Domain](https://detour.swmansion.com/docs/platform/advanced/custom-domain/)
  [Analytics](https://detour.swmansion.com/docs/platform/fundamentals/analytics/)
  [Billing & Payments](https://detour.swmansion.com/docs/platform/fundamentals/billing/)