OptOut
Build the CCPA Do Not Sell dialog with your own markup.
What it does
OptOut.* gives you the Do Not Sell dialog in pieces: when it opens, the checkbox and its label, the Save and Cancel buttons, and the confirmation shown after saving. You supply the elements and the classes. Focus handling, Escape to close and the dialog roles come with OptOut.Root.
Use it only when CookieOptOut cannot produce the markup your design needs, and only if your site serves CCPA visitors. It is one checkbox, not a list of categories; for GDPR, build with Preferences.
Build a dialog
Render this in place of <CookieOptOut />. OptOut.Root renders nothing while the dialog is closed, so keep it as the outer element.
import { OptOut } from "@cookieyes/react";
export function ConsentOptOut() {
return (
<OptOut.Root className="overlay">
<div className="dialog">
<OptOut.Title className="dialog-title" />
<OptOut.Close className="dialog-close" />
<OptOut.Description className="dialog-text" />
<div className="opt-out-row">
<OptOut.Checkbox id="do-not-sell" />
<OptOut.CheckboxLabel htmlFor="do-not-sell" />
</div>
<OptOut.Buttons className="dialog-actions">
<OptOut.Cancel className="btn" />
<OptOut.Save className="btn btn-primary" />
</OptOut.Buttons>
<OptOut.Success className="dialog-success" />
</div>
</OptOut.Root>
);
}Give the checkbox an id and the label the matching htmlFor, so clicking the label ticks the box. Render both Buttons and Success: after an opt-out, the buttons disappear and the confirmation takes their place. Saving without an opt-out closes the dialog at once.
The pieces
| Piece | Renders | What it does |
|---|---|---|
OptOut.Root | <div> | The overlay. Opens and closes the dialog, traps focus, closes on Escape. Keep it as the wrapper |
OptOut.Title | <h2> | The dialog heading |
OptOut.Description | <p> | The dialog text |
OptOut.Close | <button> | Closes without saving |
OptOut.Checkbox | <input type="checkbox"> | The Do Not Sell checkbox. Ticked already if the visitor has opted out |
OptOut.CheckboxLabel | <label> | The checkbox text |
OptOut.Cancel | <button> | Closes without saving |
OptOut.Save | <button> | Saves and shows the confirmation |
OptOut.Buttons | <div> | Holds Cancel and Save. Hidden while the confirmation shows |
OptOut.Success | <div> | The confirmation after an opt-out, with a ten-second countdown, then the dialog closes. It receives focus so screen readers announce it |
OptOut.Branding | <a> | The "Powered by" link |
Every piece takes className, style and the other props of the element it renders, and renders the translated text for the active language; pass children to replace it. Close, Cancel and Save accept asChild for your own button component, the same way as on Banner.
What Save actually writes
Save with the box ticked rejects every optional category. Save with the box unticked accepts every category. Cancel and Close record nothing.
Common mistakes
Error: OptOut.* sub-components must be rendered inside <OptOut.Root>.
Checkbox, Save, Buttons or Success sits outside OptOut.Root. Move it inside.
Nothing shows after Save.
If the box was not ticked, the dialog simply closes; that is expected. If it was ticked, OptOut.Success is not rendered.
Clicking the label does not tick the box.
The checkbox id and the label htmlFor do not match.
The dialog never opens.
The visitor is not under CCPA, or nothing opens it. Render Banner.DoNotSell, RecallButton, or your own button calling useConsentActions().showOptOut().
Next steps
- CookieOptOut: the ready-made version of this dialog
- Preferences: the GDPR dialog, built the same way
- Translations: the
optOut.*text in every language