Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Cookie Consent Login Block for React

A bakery subscription's cookie choices shown open over a drawn sign-in page: Essential locked on, Analytics and Marketing switches that start off, and three equal buttons, Reject all, Accept all and Save choices.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Ask for cookie choices without taking over the page, with this cookie consent login block for React with Base UI. It's the consent card of Kneadful, a bakery subscription, shown over its sign-in page. The host header says "Cookie choices" and holds the real trigger, an outline "Review choices" Button, and the page itself is drawn in greys under a soft scrim inside a hairline frame with a plus mark on each corner. The card holds three categories: "Essential" is on and locked, "Analytics" and "Marketing" are Switches that start off, each with one line on what it does, and three equal buttons follow, Reject all, Accept all and Save choices, which is the Shine Button and the only coloured control. Any of them closes the card and a polite line under the page says what was chosen; the drawn page shows three dots for the choices once there is one. Nothing is stored. For preview the card is drawn open in place when the page loads; the trigger opens the real Popover, which is not modal, with the same switches and the same state. For any sign-in or landing page that sets non-essential cookies.

FAQ

Why is the card already open, and what do I keep?

So you can see it without a click. On load the card is a copy drawn in place on the stage: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Review choices button opens the real Popover, with the same CookieFields and the block's state, so a switch turned in place is on in the real one, and the copy stays closed until a reload. In your app keep the Popover (or a bottom sheet) and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.

What does Save choices store, and how do I wire it for real?

Nothing leaves the page and no cookie is written: the choices live in the block's state, so a reload starts again. A polite line says what was chosen ("Saved: essential on, analytics on, marketing off. No cookie was written."). For real, write one first-party cookie, or a record on the account, with the choices, the date and the version of your policy, only after the visitor chooses; load analytics and marketing scripts only when their switch is on, and read the cookie before loading anything so the card doesn't come back for a returning visitor.

Why are Reject all and Accept all equal?

Because a choice that is easier one way isn't free. Both are outline buttons of the same size and weight, side by side, and Save choices, the coloured one, saves exactly what the switches show. Nothing is pre-switched: analytics and marketing start off, and essential cookies are described as always on because the page can't work without them, not because you agreed.

Why a popover and not a modal dialog?

A consent card shouldn't trap anyone: the page behind it stays usable, and Escape closes it without a choice, which means the same as rejecting. The real card is a Popover opened from the trigger, anchored under it, not modal, with focus returning to the trigger when it closes. If you want a decision before anything else, make it a bottom sheet instead and keep the same fields. The popover is non-modal by default.

Is it usable with a keyboard and a screen reader?

Yes. In the real popover focus starts inside it and Escape closes it and puts focus back on Review choices. Each switch is named ("Analytics cookies") and described by its line, the locked one is read as on and unavailable, and the three buttons are ordinary buttons in the order Reject all, Accept all, Save choices. The copy shown on load moves no focus; Escape inside it closes it and puts focus on the trigger. One polite status line reports each choice.

How does it look on a phone?

The copy shown on load docks to the foot of the page as a bottom card, with the three categories scrolling above the buttons if the screen is short and the buttons stacked below them. The real popover opens under the trigger at the width of the screen, with the same stacked buttons.

  • Pro

    Privacy Notice Login

    Split with a panel

    A split sign-in page for a patient portal: a Why we ask button under each field opens one sentence on why it is needed, a data list says what the portal keeps, and a required privacy box names itself when it is left unticked.

  • Pro

    Terms Consent Login

    Sign-up and consent

    A full-height agreements screen for a tenant app: a select-all checkbox that turns mixed over the two required agreements, an optional product-updates box that is never pre-ticked, and a Continue button that names what is missing instead of being disabled.

  • Pro

    Cookie Consent Dialog

    Drawers and popovers

    A recipe blog's first-visit cookie card shown open over its page: two sentences, then Reject all and Accept all as two equal outline buttons side by side, with no primary. It isn't modal, so the page stays readable, and the choice is written on the page's foot.

  • Pro

    A full-height sign-in page for a team chat app: the product's mark, Google and GitHub rows with lettermark tiles, an or rule, email and password checked on submit, and one Sign in button with a simulated wait and its result.

  • Pro

    Invite Members Dialog

    Share and invite

    A household calendar's Members page with its invite dialog shown open: one email field that knows the household's domain, so an outside address joins as a guest, the people who already have access, and a Send invite button that adds a pending row.

  • Pro

    Remember Device Login

    Sessions and devices

    A full-height sign-in page for an email client where trusting the browser is a choice with a consequence: a switch opens a 7, 30 or 90 day choice and a live line works out the date from a typed today.