Building a Real Cookie Consent Settings Flow in Next.js

June 30, 2026Web101 by HanWeb Development

Build log on implementing a real cookie consent settings flow in a Next.js site by connecting Privacy Policy links to a ConsentBanner component, showing a first-visit consent panel, saving user choices, supporting Accept all / Reject all / Save choices, and verifying the route and build.

Building a Real Cookie Consent Settings Flow in Next.js

Problem

The Problem

Implementation

Implementation 1: Connect Privacy Policy Links to the Consent Panel

Result

Fix Direction

Introduction

I found a small but important compliance UI problem on a Next.js site: the Privacy Policy page told users they could open Cookie/Consent settings, but clicking the link did not show anything.

That is not just a small UI issue. If a site says users can manage consent choices, the control needs to actually work. Otherwise the Privacy Policy looks incomplete, and the consent experience feels fake.

This note documents how I fixed the flow by connecting the Privacy Policy link to a real consent settings panel, then changing the cookie consent behavior so first-time visitors see a normal bottom-right consent panel instead of needing to find the setting inside the Privacy Policy page.

The Problem

The Privacy Policy page had text like this:

To update cookie/consent choices, open Cookie/Consent settings.

But clicking the Cookie/Consent settings link did not open anything.

The visible issue was:

Privacy Policy mentions cookie settings

User clicks Cookie/Consent settings

Nothing appears

No panel opens

No choices are shown

That made the page look broken because the policy promised a control that the interface did not actually provide.

The Wrong Assumption

The first wrong assumption was thinking that a Privacy Policy link alone was enough.

It is not.

A Privacy Policy link can be useful for letting users revisit their choices later, but it should not be the only way users see cookie consent options.

A more normal consent flow is:

First visit → show cookie consent panel

User chooses Accept / Reject / Save choices

Later visit → show a small Cookie settings button

Privacy Policy link → reopens the same settings panel

The Privacy Policy should support consent management, not hide the only consent control.

Source Inspection

After inspecting the implementation, the issue became clear.

The Privacy Policy page had a trigger-style attribute:

data-open-consent

But the consent component did not have a matching event listener that opened the settings panel when that trigger was clicked.

So the page had a visible entry point, but no connected behavior.

The simplified bug looked like this:

Privacy page: has data-open-consent

ConsentBanner: does not listen for data-open-consent clicks

Result: clicking the link does nothing

This was an implementation gap, not expected cookie consent behavior.

Fix Direction

The fix needed to solve two separate problems:

1. The Privacy Policy link should reopen consent settings.

2. First-time visitors should see a visible consent panel automatically.

Only fixing the Privacy Policy link would still be weak UX because most users will not go to the Privacy Policy page first.

The better direction was to build a reusable consent settings flow:

Bottom-right consent panel on first visit

Accept all / Reject all / Save choices actions

Persistent cookie storing the user choice

Small Cookie settings button after choice is saved

Privacy Policy link opens the same panel

Consent state updates Google Consent Mode

That turns the consent UI from a dead link into a real site-level control.

Implementation 1: Connect Privacy Policy Links to the Consent Panel

The first implementation step was to make the Privacy Policy link actually do something.

Instead of treating the Privacy Policy link as a normal navigation link, I used it as a trigger that opens the existing consent settings UI.

The behavior is:

User clicks element with data-open-consent

ConsentBanner receives the event

Consent settings panel opens

User can update choices

This makes the Privacy Policy page useful as a place where users can revisit their choices later.

Implementation 2: Show a Consent Panel on First Visit

The next fix was changing the first-visit behavior.

The consent panel should not only appear after someone finds the Privacy Policy. It should appear automatically when the user has not made a consent choice yet.

The rule became:

If consent_choice cookie does not exist:

show the bottom-right consent panel

If consent_choice cookie exists:

hide the panel

show a small Cookie settings button

This matches the normal consent banner pattern better than hiding the control inside a policy page.

Implementation 3: Add Clear Consent Actions

The settings panel needs real choices, not only informational text.

The panel includes:

Essential cookies: always on

Analytics storage: optional

Advertising storage: optional

Ad personalization: optional

Reject all

Save choices

Accept all

Essential cookies stay enabled because they are needed for basic site behavior. Optional categories can be accepted, rejected, or saved according to the user's choice.

This gives the panel real functionality instead of making it a decorative compliance element.

Implementation 4: Keep a Persistent Cookie Settings Button

After the user makes a choice, the large first-visit panel should not keep blocking the page.

But the user still needs a way to reopen settings later.

So the flow uses a smaller persistent button:

User has already made a choice

Large consent panel is hidden

Small Cookie settings button remains in the bottom-right corner

Clicking it reopens the same settings panel

This keeps the page clean while still giving users access to consent controls.

Implementation 5: Sync Choices with Google Consent Mode

Saving a consent choice should update more than local UI state.

The selected choice also needs to update Google Consent Mode so analytics and advertising behavior follows the stored preference.

The simplified model is:

Reject all → deny optional storage

Accept all → grant optional storage

Save choices → apply selected category values

The important point is that UI state, saved cookie state, and consent mode state should not drift apart.

Verification

After implementing the consent flow, I verified the site at several levels.

The checks were:

npm run build passed

/privacy returned 200 locally

/contact returned 200 locally

Privacy Policy HTML did not output noindex

Privacy Policy link still existed as a consent settings trigger

ConsentBanner contained logic for the consent settings panel

First-visit behavior depends on the consent_choice cookie

This matters because cookie consent is not only a visual component. It touches layout, client-side state, cookies, policy pages, and sometimes analytics behavior.

Before and After

Before the fix, the consent experience looked like this:

Privacy Policy mentions Cookie/Consent settings

Clicking the link does nothing

No first-visit panel appears in normal local testing

No obvious way to change choices later

The control feels broken

After the fix, the behavior became:

First-time visitors see a bottom-right consent panel

Users can Reject all, Save choices, or Accept all

Choices are stored in a consent_choice cookie

A small Cookie settings button remains available later

Privacy Policy link reopens the same settings panel

Consent state can be synced with Google Consent Mode

That is a real consent settings flow instead of a dead policy link.

The Main Gotcha

The main gotcha is that a Privacy Policy link is not the same thing as a consent system.

A Privacy Policy can explain what cookies are used and provide a way to reopen settings. But the actual consent flow should usually be visible during normal browsing, especially before the user has made a choice.

The practical lesson is:

Privacy Policy link = later access to settings

Cookie banner or panel = first-time consent interaction

Consent storage = remembered user choice

Consent mode update = technical enforcement

All four parts need to work together.

Why This Is Stronger Than a Generic Cookie Consent Article

A generic article about cookie consent would probably explain what cookies are, why consent matters, and what a banner usually does.

That would be weak because many sites already say the same thing.

This implementation note is stronger because it includes:

A specific broken behavior

The exact failed assumption

The source-level cause

The UI behavior change

The consent state model

The Privacy Policy connection

The verification steps

The final before/after behavior

That makes the article a real build record instead of a generic overview.

Practical Checklist

For a real cookie consent settings flow, I would check:

1. Does the site show a consent panel before the user has made a choice?

2. Can the user reject optional cookies?

3. Can the user accept all optional cookies?

4. Can the user save partial choices?

5. Is the choice stored persistently?

6. Is there a way to reopen settings later?

7. Does the Privacy Policy link open the same settings panel?

8. Does the UI state match the saved cookie state?

9. Does Consent Mode receive the updated choice?

10. Does the site still build and return 200 on key routes?

This checklist is more useful than only asking whether the site has a cookie banner.

Final Takeaway

The final takeaway is simple:

A cookie settings link should not be decorative.

It should open a real settings panel.

For this fix, the important change was turning a dead Privacy Policy link into a working consent settings flow. The final implementation supports a first-visit consent panel, saved choices, a persistent Cookie settings button, Privacy Policy re-entry, and build-level verification.

That makes the Privacy Policy and cookie consent UI feel like part of the same system instead of two disconnected pieces.

Last updated: June 30, 2026

Related category: Web Development

POSTED IN
Next.jsCookie ConsentPrivacy PolicyFrontend DebuggingConsent BannerGoogle Consent ModeTechnical Notes

Related stories

Curated reads to continue the thread.