Your Cookie Banner Is Making Your Google Ads More Expensive
Slow cookie banners don't just hurt your Core Web Vitals. They're quietly making your Google ads more expensive.
Here's the chain reaction almost no one talks about.
The Chain Nobody Sees Coming
It starts innocently enough: you add a cookie banner to handle GDPR compliance. Standard stuff. Everyone does it.
But here's what's actually happening inside that script tag:
- Your banner loads slowly, adding layout shifts and blocking main thread time
- Your Core Web Vitals scores dip below Google's "Good" threshold
- Google sees your poor performance and lowers your ad quality score
- Lower quality scores mean higher cost-per-clicks in Google Ads
You've optimized your landing pages, your ad copy, your targeting. But your cookie banner is working against all of that.
A customer who recently moved to Inth's consent infrastructure put it plainly: they were paying a mid-5-figure annual fee to a provider that was "driving the quality score down and increasing cost of your entire ad budget."
That's not a compliance problem. That's a performance problem that masquerades as compliance.
Why This Keeps Happening
The standard consent management vendors built their products for legal teams, not engineers.
The result: dashboards, toggle switches, and a script that loads hundreds of kilobytes from their servers before your banner ever appears.
When you load a third-party script that:
- Fetches configuration from a remote server
- Downloads banner code after initial page render
- Injects DOM elements that trigger layout shifts
- Blocks the main thread while initializing
...you're not just adding a cookie banner. You're adding a performance liability that Google measures and penalizes.
The math is simple: every 100ms of additional load time can impact your CLS score. A poor CLS score drops your ad quality. A lower quality score means you're paying more for the same placement.
What Good Looks Like
A fast cookie banner, defined in code, bundled into your application, and loaded from your own infrastructure, doesn't create this problem.
c15t's cookie banner loads in under 90ms. It's defined in your codebase, styles alongside your components, and runs on your servers. No external configuration fetch. No layout shifts. No main thread blocking.
When your Core Web Vitals stay in the "Good" range, Google rewards you with better quality scores. That means lower costs for the same ad performance.
The difference isn't just compliance. It's money.
The Real Question
If you're running Google Ads and your cookie banner is slow, you're paying a hidden tax on every campaign.
Not because Google is being unfair. Because you're giving them measurable signals that your site performs poorly, and they're pricing that risk into your CPCs.
Most teams don't connect these dots because the cookie banner sits in a different part of the stack. Legal owns the vendor. Marketing runs the ads. Nobody's looking at the intersection.
But if you are running ads, and your cookie banner is tanking your Core Web Vitals, you're essentially paying double: once for the banner, and again in inflated ad costs.
The Fix Takes Less Time Than You Think
Getting c15t live with Inth's consent infrastructure takes less time than you probably think, no matter your scale. It's npm install, a configuration file, and a component. No external scripts. No bloat.
If you're running Google Ads and your cookie banner is slow, you should probably talk to someone who can measure the actual impact on your quality scores.
Inth can help with that.
Want to hand this to your agent to deploy? Sign up to Inth, copy your hosted backend URL, paste the prompt below, and let the agent wire c15t into your repo against the matching docs. Then review the diff and ship.
# Add c15t Consent Management
Set up c15t consent management for this project using the installed package docs when available.
## Step 1: Inspect the project
Read:
- `AGENTS.md` files that apply
- `package.json`
- the lockfile
- framework entry files and routing/layout structure
- existing env, middleware, provider, and global CSS patterns
Detect:
- package manager: npm, pnpm, yarn, or bun
- framework: Next.js, React, or custom JavaScript
- whether `@c15t/*` or `c15t` is already installed
- whether this is a new setup or an existing setup that needs repair
## Step 2: Detect the supported integration
c15t currently publishes these setup targets:
| Project shape | Package | Bundled docs |
| --- | --- | --- |
| Next.js app using `next` | `@c15t/nextjs` | `node_modules/@c15t/nextjs/docs/README.md` |
| React app using `react` without Next.js | `@c15t/react` | `node_modules/@c15t/react/docs/README.md` |
| Headless or custom JavaScript integration | `c15t` | `node_modules/c15t/docs/README.md` |
Do not look for framework-specific c15t packages for Remix, Astro, Nuxt, Vue, Svelte, Express, or similar unless the project already depends on one.
## Step 3: Choose the documentation source
Prefer docs in this order:
1. Framework-specific bundled docs for the installed package version:
- Next.js: `node_modules/@c15t/nextjs/docs/README.md`
- React: `node_modules/@c15t/react/docs/README.md`
- Headless/core: `node_modules/c15t/docs/README.md`
2. Bundled core docs:
- `node_modules/c15t/docs/README.md`
- relevant pages under `node_modules/c15t/docs/`
3. Project-local markdown docs, if this repo contains c15t-specific setup docs.
4. Hosted docs only if bundled docs are unavailable or the package is not installed.
If bundled docs are missing, search for nested installs:
```bash
find node_modules -path "*/c15t/docs/README.md" -not -path "*/node_modules/*/node_modules/*/node_modules/*" | head -1
Do not guess component names, provider names, config shape, or file paths. Follow the docs that match the detected package and framework.
Step 4: Install or update packages
If c15t is not installed, install only the relevant c15t package for the detected project shape using the repo's package manager:
Next.js: @c15t/nextjs
React: @c15t/react
Headless/custom JavaScript: c15t
If c15t is already installed, keep the existing version unless the docs or code clearly require an update.
Only use c15t version >=2.0. If the project is on an older version, stop and report that a v2 migration decision is needed.
Step 5: Configure c15t
Follow the relevant bundled quickstart exactly.
Usually this means:
adding the c15t provider at the correct app root
adding the consent banner or consent manager component
adding required CSS imports
adding middleware, route handlers, or API endpoints only if required by the docs
configuring environment variables only where required
preserving existing providers, layouts, middleware, and app structure
If the project needs hosted mode, use the user's own hosted backend URL from their Inth account after they sign up.
If the repo already contains an Inth hosted backend URL, use that.
If it does not, stop and ask for it.
Do not hardcode or invent a hosted backend URL.
For manual setup, choose the documented mode only if it is clear from the project. Otherwise report the available modes:
hosted with Inth
hosted with self-hosted backend
offline
Do not silently choose offline for production-looking apps.
Step 6: Integrations
Before manually adding third-party script blocking or consent behavior:
Check file node_modules/@c15t/scripts/README.md if it exists.
Check node_modules/c15t/docs/integrations/.
Use a prebuilt c15t script helper if one exists.
Only create manual script config if no helper exists.
Step 7: Styling and copy
Use the lowest-power customization that solves the task:
provider/component props
i18n for text changes
documented layout/action options
theme tokens
slots
CSS overrides only when documented APIs are insufficient
headless mode only when fully custom markup is required
Step 8: Verify
Run the repo's relevant checks:
typecheck
lint
tests if available
build if reasonable
Start the dev server if needed and verify:
the app loads
the consent UI appears
accepting/rejecting preferences works
no server/client import errors
no secret keys are exposed to client code
Critical rules
Prefer bundled docs over web docs when packages are installed.
Preserve existing app conventions.
Do not invent c15t APIs.
Do not expose server secrets in client code.
Do not overwrite unrelated user changes.
Report files changed and checks run.