# Footer exposes a "Do Not Sell or Share" / "Your Privacy Choices" opt-out link

- **Pattern:** `ab-002619` (`project-snapshot.legal.do-not-sell-or-opt-out-link`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-23
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002619
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002619)

## Why it matters

CCPA §1798.135(a)(1), as strengthened by the 2023 CPRA amendment, requires a literal-text "Do Not Sell or Share My Personal Information" link (or the state-approved alternate "Your Privacy Choices" link with the official blue-white icon) in the footer of any site that "sells or shares" personal data — and under CPRA, routing any identifier (IP, device ID, cookie ID) to ads, analytics, or retargeting counts as "sharing." Sephora paid $1.2M to the California AG in 2022 for missing exactly this link, and the Connecticut, Colorado, Virginia, and Utah parallel statutes each layer additional $7,500-per-violation exposure on top. AI coding tools reliably bolt Google Analytics, PostHog, Meta Pixel, or TikTok Pixel into a Next.js layout — because "add analytics" is a two-line copy-paste — but almost never scaffold the matching opt-out link, because the obligation only triggers once the pixel is present. The quiet failure mode is a site that successfully tracks California visitors while silently accruing per-visitor violations.

## Severity rationale

High because California AG enforcement has shown a clear willingness to settle for seven figures on the missing-link vector alone, the exposure scales linearly with California visitor volume, and parallel CPA / CTDPA / CDPA regimes compound it.

## Remediation

Add a `/privacy/opt-out` (or `/do-not-sell`) route that handles opt-out requests (cookie drop + downstream pixel disabling), then link to it from the site footer with the exact California-approved text:

```tsx
// components/Footer.tsx
<Link href="/privacy/opt-out">Do Not Sell or Share My Personal Information</Link>
```

The alternate compliant text is `"Your Privacy Choices"` paired with the California blue-white opt-out icon (see `oag.ca.gov/privacy/ccpa/icons-download`). Deeper coverage of the full CPRA opt-out flow (global privacy control signals, sensitive PI limits, authorized agent handling) lives in the `ccpa-readiness` Pro audit.

## Detection

- **ID:** `do-not-sell-or-opt-out-link`
- **Severity:** `high`
- **What to look for:** First determine whether the site "sells or shares" personal data under CPRA — practically, whether any analytics / advertising / retargeting / session-replay library is loaded. Scan `package.json` for: `posthog-js`, `@vercel/analytics`, `@vercel/speed-insights`, `react-ga`, `react-ga4`, `@segment/analytics-next`, `mixpanel-browser`, `@hotjar/browser`, `@amplitude/*`, `@microsoft/clarity`, `next-plausible`, `@intercom/messenger-js-sdk`, `react-facebook-pixel`, `react-tiktok-pixel`, `react-linkedin-insight-tag`. Also grep `<script>`, `<Script>`, and string literals for `googletagmanager.com`, `google-analytics.com`, `gtag(`, `fbevents.js`, `fbq(`, `tiktok.com/i18n/pixel`, `snap.licdn.com`, `analytics.tiktok.com`. If any match, the site is in-scope. Then look for the opt-out link: grep the codebase for text matching `/Do Not Sell( or Share)?( My Personal Information)?/i` OR `/Your Privacy Choices/i`. Evidence locations: `app/layout.tsx`, `app/_layout.tsx`, any component file whose name matches `/footer/i`, or `components/Footer.tsx` / `components/site-footer.tsx`. The match must be inside a rendered link / button, not just a comment.
- **Pass criteria:** Either no tracking/analytics/ad libraries are detected (site out of scope), OR tracking is detected AND a visible footer link containing the exact text "Do Not Sell or Share My Personal Information" or "Your Privacy Choices" is present.
- **Fail criteria:** Tracking / analytics / ad / retargeting is detected AND no matching opt-out link text is found in the footer or any persistent navigation surface.
- **Skip (N/A) when:** No analytics, ad, retargeting, or tracking pixel is detected anywhere in the codebase. Quote: `"No analytics or ad pixel detected — CPRA §1798.135 does not apply."`
- **Do NOT pass when:** A privacy policy page exists and mentions opt-out rights in prose, but no literal-text link appears in the footer or persistent navigation. CPRA §1798.135 requires a *link*, not just prose.
- **Before evaluating, quote:** Quote the tracking evidence (dependency name or script URL) AND the matching footer link text with its surrounding JSX / HTML, or state `"No match for Do-Not-Sell / Privacy-Choices text in any footer or layout file."`
- **Report even on pass:** `"Tracking detected: <libraries>; opt-out link text '<exact text>' at <file>:<line>."`
- **Detail on fail:** `"Google Analytics 4 loaded via app/layout.tsx (@vercel/analytics in package.json; gtag call in app/_components/Analytics.tsx) but no 'Do Not Sell' or 'Your Privacy Choices' link found in components/Footer.tsx or app/layout.tsx."`
- **Remediation:** Add a `/privacy/opt-out` (or `/do-not-sell`) route that handles opt-out requests, then link to it from the site footer with the exact California-approved text (see `remediation_prose` above). Deeper coverage lives in the `ccpa-readiness` Pro audit.

## External references

- ccpa §1798.135

Taxons: project-snapshot, regulatory-conformance

HTML version: https://auditbuffet.com/patterns/ab-002619
