With global privacy regulations like GDPR and ePrivacy Directive, businesses must seek user consent before storing cookies—especially for marketing and analytics purposes.
While Salesforce Experience Cloud provides great flexibility, it doesn’t come with a built-in cookie consent manager for your portals.
In this guide, we’ll create a Cookie Consent Popup that:
- Appears only on first login (or until the user saves their preferences).
- Lets users toggle cookie categories (Preferences, Marketing, Statistics).
- Saves choices both in Salesforce and in the browser.
Solution Overview
The consent popup will be powered by:
- Apex Controllers – Handle database checks and updates.
- Parent LWC – Checks if the popup is needed and manages modal visibility.
- Child LWC – Displays consent toggles and saves preferences.
- Custom User Fields – Store the consent status.


Apex Classes
CookieConsentLoginController
Purpose: This Apex class controls the first-login behavior. It checks whether the popup should appear and saves preferences along with a timestamp.
Key Methods:
@AuraEnabled(cacheable=true)
public static Boolean needsConsentPopup()
- Checks if the current user’s Cookies_Save_Preference_Time__c is null.
- If null, this means the user hasn’t saved preferences yet → popup should show.
@AuraEnabled
public static void updateConsentAndTime(Boolean preferences, Boolean marketing, Boolean statistics)
- Updates cookie preference fields (Cookie_Preferences__c, Marketing_Allowed__c, Statistics_Allowed__c)
- Also sets the timestamp field to current time.
- Prevents popup from appearing again in future logins.
CookieConsentLoginController
Checks if popup is needed and updates preferences with a timestamp.
public with sharing class CookieConsentLoginController {
@AuraEnabled(cacheable=true)
public static Boolean needsConsentPopup() {
User u = [
SELECT Cookies_Save_Preference_Time__c
FROM User
WHERE Id = :UserInfo.getUserId()
];
return u.Cookies_Save_Preference_Time__c == null;
}
@AuraEnabled
public static void updateConsentAndTime(Boolean preferences, Boolean marketing, Boolean statistics) {
User u = [
SELECT Id, Cookie_Preferences__c, Marketing_Allowed__c, Statistics_Allowed__c, Cookies_Save_Preference_Time__c
FROM User
WHERE Id = :UserInfo.getUserId()
];
u.Cookie_Preferences__c = preferences;
u.Marketing_Allowed__c = marketing;
u.Statistics_Allowed__c = statistics;
u.Cookies_Save_Preference_Time__c = System.now();
update u;
}
}
CookieConsentController
Purpose: Allows updating cookie preferences without modifying the timestamp. This is useful when the user is editing preferences later from a settings page.
Key Method:
@AuraEnabled
public static void updateConsent(Boolean preferences, Boolean marketing, Boolean statistics)
- Updates cookie preferences in the database.
- Does not update the Cookies_Save_Preference_Time__c, ensuring the original consent timestamp remains intact.
- Updates preferences without modifying the timestamp (useful for settings page edits).
public with sharing class CookieConsentController {
@AuraEnabled
public static void updateConsent(Boolean preferences, Boolean marketing, Boolean statistics) {
User u = [
SELECT Id, Cookie_Preferences__c, Marketing_Allowed__c, Statistics_Allowed__c
FROM User
WHERE Id = :UserInfo.getUserId()
];
u.Cookie_Preferences__c = preferences;
u.Marketing_Allowed__c = marketing;
u.Statistics_Allowed__c = statistics;
update u;
}
}
Lightning Web Components
Parent LWC – cookieMain
Purpose: Controls whether the cookie consent popup should appear by calling Apex. Also hosts the child component in a modal dialog.
What It Does:
- Calls needsConsentPopup() in connectedCallback() to determine if the popup should appear.
- If the Apex method returns true, it shows the modal containing the child LWC.
- Includes a “Cookie Preferences” link to manually open the popup again.
- Listens for a closechild event from the child component to close the modal.
Acts as the controller and modal wrapper.
Responsible for checking if the popup should be shown and for rendering the child component.
HTML
Cookie Preferences
JS
import { LightningElement, track } from ‘lwc’;
import needsConsentPopup from ‘@salesforce/apex/CookieConsentLoginController.needsConsentPopup’;
export default class CookiePreferencesParent extends LightningElement {
@track initialized = false;
@track showChild = false;
connectedCallback() {
needsConsentPopup()
.then(result => {
this.showChild = result;
})
.catch(error => {
console.error(‘Error checking consent popup:’, error);
})
.finally(() => {
this.initialized = true;
});
}
handleClick() {
this.showChild = true;
}
handleClose() {
this.showChild = false;
}
}
CSS
.centered-link {
text-align: center;
margin-top: 20px;
}
.slds-modal__container {
max-width: 40rem;
width: 100%;
}
Child LWC – cookiesForPortal
Purpose: Displays the actual cookie settings UI and handles saving the user’s preferences to both the Salesforce backend and the browser.
What It Does:
- Displays toggle switches for Preferences, Marketing, and Statistics cookies.
- Updates internal consent object when toggles change.
- On clicking “Save Preferences”:
- Saves consent to the browser via setCookieConsent().
- Calls updateConsentAndTime() Apex method to save in Salesforce.
- Displays success/error message using ShowToastEvent.
- Fires a closechild event to tell the parent to close the modal.
Handles all user interaction and data saving logic.
Handles displaying and saving the cookie consent options.
HTML
We use cookies to personalize content and ads. Please adjust your preferences below:
Check our cookie preferences
here.
JS
import { LightningElement, track } from ‘lwc’;
import { setCookieConsent, isCategoryAllowedForCurrentConsent } from ‘lightning/userConsentCookie’;
import { ShowToastEvent } from ‘lightning/platformShowToastEvent’;
import updateConsentAndTime from ‘@salesforce/apex/CookieConsentLoginController.updateConsentAndTime’;
export default class CookieConsentToggle extends LightningElement {
@track checkedPreferences = isCategoryAllowedForCurrentConsent(“Preferences”);
@track checkedMarketing = isCategoryAllowedForCurrentConsent(“Marketing”);
@track checkedStatistics = isCategoryAllowedForCurrentConsent(“Statistics”);
consent = {
Preferences: this.checkedPreferences,
Marketing: this.checkedMarketing,
Statistics: this.checkedStatistics
};
changeTogglePreferences(event) {
this.checkedPreferences = event.target.checked;
this.consent.Preferences = this.checkedPreferences;
}
changeToggleMarketing(event) {
this.checkedMarketing = event.target.checked;
this.consent.Marketing = this.checkedMarketing;
}
changeToggleStatistics(event) {
this.checkedStatistics = event.target.checked;
this.consent.Statistics = this.checkedStatistics;
}
handleClickSetConsent() {
setCookieConsent(this.consent);
updateConsentAndTime({
preferences: this.checkedPreferences,
marketing: this.checkedMarketing,
statistics: this.checkedStatistics
})
.then(() => {
this.dispatchEvent(
new ShowToastEvent({
title: ‘Preferences Saved’,
message: ‘Your cookie settings have been updated.’,
variant: ‘success’
})
);
this.dispatchEvent(new CustomEvent(‘closechild’));
})
.catch(error => {
this.dispatchEvent(
new ShowToastEvent({
title: ‘Error’,
message: error.body.message,
variant: ‘error’
})
);
});
}
}
CSS
.custom-container {
color: black;
}
Key Points
- The decision point for showing the popup is:
- return u.Cookies_Save_Preference_Time__c == null;
- Preferences are stored in two places: Salesforce (server-side) and browser consent cookie (client-side).
- Users can reopen the popup anytime via the “Cookie Preferences” link.
- Future logins skip the popup unless the timestamp is cleared.
Conclusion
This approach delivers a compliant and user-friendly cookie consent manager within Salesforce.
It’s flexible enough to:
- Integrate with Experience Cloud sites.
- Allow users to change preferences anytime.
- Store consent history securely.