# Setup wizard: a verified installation, step by step

How the FlowConsent setup wizard verifies every install step for real — snippet check, refusal scan, weekly monitoring, plus the server-side path.

> Canonical: https://www.flowconsent.com/en/doc/setup-wizard
> Last updated: 2026-07-30
The setup wizard lives in the Builder's **Deployment** tab, once your banner is deployed. It does more than hand you a snippet: every step is **verified against your live site**. The wizard doesn't say "paste this code" — it fetches your page and confirms it's done, then proves the banner is respected with a refusal scan, and ends on continuous monitoring rather than a "you're done".

## Step 1 — Add the snippet for your platform

The integration card offers the snippet in three flavors: **HTML / No-code**, **Webflow**, and **Next.js**. All of them contain the same two parts, in this order:

1. An inline **Consent Mode stub** that registers `denied` defaults for every Google signal.
2. The **FlowConsent loader** that displays the banner and applies the visitor's choice.

```html title="index.html"
<script>
// FlowConsent Loader - PLACER AVANT tout autre script dans le <head>
window.dataLayer=window.dataLayer||[];
function gtag(){dataLayer.push(arguments);}
gtag('consent','default',{
  'ad_storage':'denied',
  'analytics_storage':'denied',
  'ad_user_data':'denied',
  'ad_personalization':'denied',
  'wait_for_update':500
});
gtag('set','url_passthrough',true);
gtag('set','ads_data_redaction',true);
</script>
<!-- FlowConsent CMP -->
<script src="https://YOUR-LICENSE-CODE.consent.flowconsent.com/cookie-manager.js?code=YOUR_LICENSE_CODE"></script>
```

> [!WARNING]
> The stub must come **before** the loader — and before any other script. The loader is asynchronous, so a Google tag injected by another channel (a site-builder setting, a plugin) could win the race. The stub executes while the HTML is parsed: the `denied` defaults are registered before any gtag, whoever loads it.

Platform specifics, as shown in the wizard:

- **Webflow** — paste the snippet in *Site settings → Custom code → Head code*, then publish. Remove any Google Analytics Measurement ID from *Site settings → Apps & Integrations*: Webflow injects it **above** your custom code, so its gtag config would run before the consent defaults and no CMP could gate it.
- **Next.js** — the wizard generates an `app/layout.tsx` version using `<Script strategy="beforeInteractive">` for both the stub and the loader. For client-side navigation, also enable SPA Mode in the Settings tab — see the [Next.js integration guide](/en/doc/nextjs-integration).

## Step 2 — Verify your installation

Enter your page URL and click **Verify**. FlowConsent fetches the page from its servers and checks, in the real HTML:

- the page is **reachable** (with the HTTP status if not);
- the **FlowConsent loader is present with your license code** — if a loader is found with a *different* license, the wizard tells you which one;
- the **Consent Mode stub is present** — if it's missing, you probably pasted only the second `<script>` block;
- if a Google tag is on the page, the **stub runs before it** — otherwise its cookies cannot be gated, and the wizard shows the offending tag URL.

> [!TIP]
> If the check reports a tag injected by your **Webflow site settings**, don't fight it with custom code: remove the Measurement ID from *Site settings → Apps & Integrations* and let the banner load Google Analytics instead.

## Step 3 — Run a refusal scan

An installed banner proves nothing by itself: what matters is what runs when a visitor **refuses**. This step loads your page in a real browser with consent refused and lists everything that still fires. It uses the fast profile — a verdict in about 30–60 seconds — and shows the same verdict badge as the Compliance page (Compliant, Warnings, or Violations) plus the number of violations.

The exhaustive audit, page suggestions and scan history live on the [Compliance page](/en/doc/compliance-verification).

## Step 4 — Turn on weekly monitoring

The last step doesn't end the installation — it makes it stay proven. Click **Monitor this page weekly**: the same refusal scan re-runs every week and alerts you on regression (a tag added by a marketing team, a site-builder setting re-enabled). Once a monitor exists for the page, the wizard shows it as active.

## Server side (optional)

Half of consent-bound processing happens server side — GA4 Measurement Protocol, CRM sync, home-grown analytics. The wizard covers this path too.

### Read the consent contract with the server SDK

The wizard generates a `readConsent()` snippet with your banner's **current `configHash` already injected**. A consent given before you changed the banner is invalid — the hash makes your server treat it as requiring re-consent:

```js title="handler.js"
import { readConsent } from '@flowconsent/server-sdk'

export async function handler(request) {
  const consent = readConsent(request, {
    // Hash of the published config: a choice made before a
    // banner change is invalid (re-consent).
    expectedConfigHash: 'YOUR_CURRENT_CONFIG_HASH',
  })
  if (consent.can('analytics')) {
    // GA4 Measurement Protocol, in-house analytics…
  }
  if (consent.can('marketing')) {
    // CRM sync, audiences…
  }
}
```

See the [server SDK guide](/en/doc/server-sdk) for the full API.

### Consent webhook, tested with a real signed event

Add an endpoint URL and the wizard creates a **consent webhook** with a signing secret in the `whsec_…` format.

> [!IMPORTANT]
> The signing secret is shown **once**, at creation. Store it immediately — you will need it to verify the signature of every delivery.

Then click **Send signed test**: FlowConsent delivers a real, signed `consent.test` event to your endpoint and reports the outcome — delivered with the HTTP status and response time, or the failure detail. Your integration is confirmed by an actual delivery, not by a green checkmark on faith.

## Next steps

- [Verify compliance continuously](/en/doc/compliance-verification)
- [Customize the banner](/en/doc/banner-customization)
- [Quick install from scratch](/en/doc/quick-install)
