Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/web/src/app/setup/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export default async function SetupPage() {
{formRows.length > 0 ? <h2 className={styles.groupTitle}>Forms</h2> : null}
{formRows.map(({ form, rules, version }) => {
const url = `${base}/f/${form.slug}`;
const snippet = `<div data-switchboard-form="${form.slug}"></div>\n<script src="${base}/embed.js" defer></script>`;
const snippet = `<div data-switchboard-form="${form.slug}"></div>\n<script src="${base}/embed.js" data-switchboard-consent="granted" defer></script>`;
const parsed = rules ? validateRuleSet(rules) : null;
return (
<section key={form.id} className={styles.section} aria-labelledby={`form-${form.slug}`}>
Expand Down
5 changes: 4 additions & 1 deletion docs/decisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,10 @@ decisions. Each item notes what it supersedes.
current page's UTMs stores nothing on the device. Keeping first touch in
localStorage and reading `_ga`/`_fbp`/`_fbc`/`_gcl_aw`/`hubspotutk` does,
so it waits for `data-switchboard-consent="granted"` or
`Switchboard.setConsent(true)`. The default is the privacy-safe one.
`Switchboard.setConsent(true)`. The loader's own default is the
privacy-safe one, but the documented snippet (and the one the Setup page
copies) includes the attribute: most B2B sites want full attribution, and
sites that need a consent banner remove it and call `setConsent` instead.
- **Last touch flat, first touch nested.** Rules mostly care about the visit
that converted (`attribution.utm_medium`); first touch is there for
reporting and ABM rules (`attribution.first.utm_source`).
Expand Down
32 changes: 21 additions & 11 deletions docs/embed.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,24 @@ host and the form's slug:

```html
<div data-switchboard-form="book-a-demo"></div>
<script src="https://switchboard.yourcompany.com/embed.js" defer></script>
<script src="https://switchboard.yourcompany.com/embed.js" data-switchboard-consent="granted" defer></script>
```

The loader (about 4 KB, no dependencies) turns every
`data-switchboard-form` placeholder into the form. Several placeholders on one
page each get their own form.

`data-switchboard-consent="granted"` turns on full attribution: the loader
remembers where a visitor first came from across pages and visits, and reads
your analytics and ad cookie IDs. If your site has to ask visitors before
storing that (for example under GDPR), remove the attribute and let your
consent banner turn it on instead; see
[Tracking and attribution](#tracking-and-attribution).

To capture campaigns from your landing pages, not just the page with the
form, add the script tag (without a placeholder) to every page, for example
in your site's shared layout or through your tag manager.

## Single-page apps, modals, and tag managers

- Placeholders added after the page loads (client-side routing, a modal that
Expand All @@ -26,7 +37,7 @@ page each get their own form.
`<script>` tag so the loader can find its own origin:

```html
<script src="https://switchboard.yourcompany.com/embed.js" data-switchboard-embed defer></script>
<script src="https://switchboard.yourcompany.com/embed.js" data-switchboard-embed data-switchboard-consent="granted" defer></script>
```

- Set an accessible name for the frame with
Expand Down Expand Up @@ -61,18 +72,17 @@ loads, it asks the loader for that data and sends it with the submission.
| First touch, kept across pages and visits for 90 days | localStorage on your site | Yes |
| Cookie IDs: `_ga`, `_fbp`, `_fbc`, `_gcl_aw`, `hubspotutk` | Your site's cookies | Yes |

Without consent, the loader reads only the current page's URL and referrer
and stores nothing. So if a visitor lands on `/pricing?utm_source=google` and
then clicks to `/demo`, the campaign is lost unless you've granted consent.
Grant it in one of two ways:
The snippets in this guide include `data-switchboard-consent="granted"`, so
everything in the table is captured. Without the attribute, the loader reads
only the current page's URL and referrer and stores nothing; a visitor who
lands on `/pricing?utm_source=google` and then clicks to `/demo` would arrive
with no campaign.

```html
<!-- Your site doesn't need a consent banner (or consent is implied): -->
<script src="https://switchboard.yourcompany.com/embed.js" data-switchboard-consent="granted" defer></script>
```
If your site needs consent before storing data or reading cookies, leave the
attribute off and call this from your consent banner once the visitor
accepts analytics or marketing cookies:

```js
// Your consent banner calls this once the visitor accepts analytics or marketing cookies:
window.Switchboard.setConsent(true);
```

Expand Down
2 changes: 1 addition & 1 deletion examples/embed-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ <h1>Your product</h1>
<hr />
<!-- Replace the host and slug with your own; see docs/embed.md -->
<div data-switchboard-form="book-a-demo"></div>
<script src="http://localhost:3000/embed.js" defer></script>
<script src="http://localhost:3000/embed.js" data-switchboard-consent="granted" defer></script>
</main>
</body>
</html>
Loading