Get a compliant banner live in about a minute. First, choose the tag setup that
matches your site in [Choose your setup](/install/choose-setup/) or use the
[Lightning configurator](https://demo.lightning-consent.io/). The final
`lightning("init", …)` line depends on that choice.

> **Warning — Using Google Tag Manager?**
> Do not copy the generic init line below and then add a separate GTM snippet.
> Use the [Google bridge](/integrations/bridges/#google-gtag--gtm) with your
> `GTM-…` container ID. It owns the loader ordering; individual tags remain
> managed in GTM. The setup is shown in the first tab below.

## Before you start

You need three things — see [Prerequisites](/install/prerequisites/) for detail:

- A **license key** (`k=8f3c…`). It's baked into the script URL and carries your
  `siteId`, so you usually don't set `siteId` in `init()`.
- Your **domains registered** against the site. The SDK only runs on authorised
  hosts; everywhere else it's a harmless no-op (`localhost` is allowed for
  testing).
- **Access to `<head>`** — ideally as the *first* thing in it.

## Install

The head block depends on who owns Google Consent Mode. When you use a Google
bridge, the bridge supplies the default and the snippet stays smaller. Choose
the setup before you paste it:

#### Google Tag Manager

Use this when your tags are managed in GTM. Replace `GTM-XXXXXXX` with your
container ID, then configure each tag's Consent Settings in GTM.

```html
<!-- 1. Warm up the first backend round-trip. -->
<link rel="preconnect" href="https://cmp.lightning-consent.io" />

<!-- 2. Async queue stub. The configured Google bridge owns Consent Mode. -->
<script>
  !(function (c) {
    c.lightning =
      c.lightning ||
      function () {
        (c.lightning.q = c.lightning.q || []).push(arguments);
      };
  })(window);
</script>

<!-- 3. Load the CMP async (never render-blocking). -->
<script
  async
  src="https://cmp.lightning-consent.io/v1/cmp.js?k=YOUR_LICENSE_KEY"
></script>
<script>
  lightning("init", { bridges: { google: { tagId: "GTM-XXXXXXX" } } });
</script>
```

#### GA4 or Ads (no GTM)

Use this when the CMP should load a Google tag directly. Replace the ID with
your `G-…` or `AW-…` value.

```html
<!-- 1. Warm up the first backend round-trip. -->
<link rel="preconnect" href="https://cmp.lightning-consent.io" />

<!-- 2. Async queue stub. The configured Google bridge owns Consent Mode. -->
<script>
  !(function (c) {
    c.lightning =
      c.lightning ||
      function () {
        (c.lightning.q = c.lightning.q || []).push(arguments);
      };
  })(window);
</script>

<!-- 3. Load the CMP async (never render-blocking). -->
<script
  async
  src="https://cmp.lightning-consent.io/v1/cmp.js?k=YOUR_LICENSE_KEY"
></script>
<script>
  lightning("init", { bridges: { google: { tagId: "G-XXXXXXX" } } });
</script>
```

#### No Google tag

Use the generic init when another system already owns your Google setup or
your site has no Google tags. Add supported vendor bridges separately.

```html
<!-- 1. Warm up the first backend round-trip. -->
<link rel="preconnect" href="https://cmp.lightning-consent.io" />

<!-- 2. Consent Mode v2 default + async queue stub. MUST be first. -->
<script>
  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,
  });
  !(function (c) {
    c.lightning =
      c.lightning ||
      function () {
        (c.lightning.q = c.lightning.q || []).push(arguments);
      };
  })(window);
</script>

<!-- 3. Load the CMP async (never render-blocking). -->
<script
  async
  src="https://cmp.lightning-consent.io/v1/cmp.js?k=YOUR_LICENSE_KEY"
></script>
<script>
  lightning("init", { theme: "light" });
</script>
```

1. **Paste your selected snippet** at the very top of `<head>`, before any
   site-hosted Google tag or other tracker. Replace `YOUR_LICENSE_KEY` and the
   example tag ID with your values. Bridge tabs omit the inline default because
   the bridge owns it.

2. **Load the page** and open its console. Run:

   ```js
   LightningCMP.debug();
   ```

   You'll see the resolved regulation, the Consent Mode signals, and a table of
   any scripts the CMP is gating. If that prints, you're installed.

That's a complete, compliant install for the path you selected. The banner shows
(or doesn't) according to the visitor's region, resolved at the edge.

## What each part does

A one-line tour — the [line-by-line explainer](/install/snippet-explained/) goes
deeper.

| Part                             | Why it's there                                                                                                                                          |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `preconnect`                     | Warms the TLS connection to the edge so the first config round-trip is fast. Pure performance.                                                          |
| `gtag('consent','default', …)`   | The **Consent Mode default** for site-hosted Google tags. Bridge installs omit it because the Google bridge pushes the default before it loads its tag. |
| The `lightning()` **queue stub** | Lets you load `cmp.js` `async` and still call `lightning('init', …)` immediately — calls are queued and replayed on load.                               |
| `cmp.js?k=…`                     | The SDK (\~12 KB gzipped), `async`, never render-blocking. The `?k=` key authorises backend calls and carries your `siteId`.                            |
| `lightning('init', { … })`       | Boots the banner with your [config](/api/config-reference/).                                                                                            |

> **Warning — Using Cloudflare Rocket Loader or a “defer all JS” optimiser?**
> Rocket Loader (and WP Rocket, LiteSpeed, NitroPack…) rewrite and re-order your
> scripts, which can make the Consent Mode default land *after* your Google tags —
> GTM Preview then reports *“a tag read consent state before a default was set.”*
> Add `data-cfasync="false"` to every Lightning `<script>`. See
> [Troubleshooting](/guides/troubleshooting/).

## `lightning(...)` vs `LightningCMP.*`

Two ways to call the CMP, for two moments:

- **`lightning('method', args)`** — the queue-safe dispatcher. Use it in the
  initial page markup (like `lightning('init', …)` above), before the SDK has
  finished loading.
- **`window.LightningCMP.*`** — the real API, available once loaded. Call it from
  event handlers and app code, e.g. a footer "Cookie settings" link:

  ```html
  <button onclick="LightningCMP.openPreferences()">Cookie settings</button>
  ```

## Next steps

- [Choose your setup](/install/choose-setup/) — revisit the decision if your tag
  stack changes.
- [Configurator](https://demo.lightning-consent.io/) — generate a setup for your
  site and vendor mix.
- [How it works](/how-it-works/) — the model behind the snippet.
- [Framework recipes](/install/frameworks/) — the same snippet for WordPress,
  React, Next.js, Shopify and more.
- [Built-in bridges](/integrations/bridges/) — wire Google, HubSpot, Adobe and
  Pardot to consent.
- [Appearance & theming](/configure/appearance/) — make the banner yours.
