Extending Cookie Consent Across Subdomains

Learn how to extend cookie consent functionality to work across all subdomains for consistent user experience.

To ensure cookie consent settings are consistent across all subdomains, we extended our CookieConsentProvider to set and remove cookies with the domain attribute. This also ensures that Google Analytics (gtag) settings are updated accordingly.

How to Implement Cookie Consent Across Subdomains

1. Setting the Cookie

First up, let's set the cookie with the domain attribute:

const COOKIE_DOMAIN = '.bulletninja.com'; // Ensure this is the correct domain

const setConsentCookie = (value: string) => {
  document.cookie = `${COOKIE_NAME}=${value}; domain=${COOKIE_DOMAIN}; path=/;`;
};

2. Removing the Cookie

Next, here's how you can remove the cookie from the specified domain:

const removeConsentCookie = () => {
  document.cookie = `${COOKIE_NAME}=; domain=${COOKIE_DOMAIN}; path=/; expires=${new Date(0).toUTCString()};`;
};

3. Getting the Cookie

To retrieve the cookie, use this function:

const getConsentCookie = () => {
  const match = document.cookie.match(new RegExp('(^| )' + COOKIE_NAME + '=([^;]+)'));
  return match ? JSON.parse(match[2]) : null;
};

4. Updating Cookie Consent

When denying all cookie consents, update the state and remove the cookie like this:

const denyAllCookieConsent = useCallback(() => {
  const deniedConsent = {
    ad_storage: 'denied',
    ad_user_data: 'denied',
    ad_personalization: 'denied',
    analytics_storage: 'denied',
  };
  updateConsent(deniedConsent);
  if (typeof window !== 'undefined' && window.gtag) {
    window.gtag('consent', 'update', deniedConsent);
  }
  removeConsentCookie();
}, [updateConsent]);

Integrating with CookieConsentProvider

In your CookieConsentProvider, manage the cookie consent effortlessly with these functions:

useEffect(() => {
  const consent = getConsentCookie();
  if (consent) updateConsent(consent);
  setIsClient(true);
}, [updateConsent]);

const setCookieConsent = useCallback((updates: Partial<CookieConsent>) => {
  const newConsent = { ...cookieConsent, ...updates };
  updateConsent(newConsent);
  if (typeof window !== 'undefined' && window.gtag) window.gtag('consent', 'update', newConsent);
  setConsentCookie(JSON.stringify(newConsent));
}, [cookieConsent, updateConsent]);

Wrap your application with the CookieConsentContext.Provider like this:

return (
  <CookieConsentContext.Provider value={value}>
    {children}
  </CookieConsentContext.Provider>
);

Creating the Cookie Consent Banner

The CookieConsentBanner component displays a banner to manage user consent. Here's how it looks:

const { cookieConsent, setCookieConsent, denyAllCookieConsent } = useCookieConsent();
const allDenied = Object.values(cookieConsent).every(value => value === 'denied');
if (!allDenied) return null; // Skip rendering if consents are not all denied

return (
  <>
    <div style={{ ...overlayStyles }}></div>
    <div style={{ ...bannerStyles }}>
      <p>We use cookies to improve your experience and analyze our traffic. By using our site, you consent to our use of cookies. You can manage your preferences below:</p>
      <div style={{ ...buttonContainerStyles }}>
        <button style={{ ...acceptButtonStyles }} onClick={() => setCookieConsent({ ...grantedConsent })}>Accept All</button>
        <button style={{ ...declineButtonStyles }} onClick={denyAllCookieConsent}>Decline All</button>
      </div>
    </div>
  </>
);

Integrating Everything in Your Layout

Now, integrate CookieConsentProvider and CookieConsentBanner in your layout:

<CookieConsentProvider>
  <CookieConsentBanner />
</CookieConsentProvider>

Context and Types

Ensure you have the context and its type defined:

type CookieConsentContextType = {
  cookieConsent: CookieConsent;
  setCookieConsent: (updates: Partial<CookieConsent>) => void;
  denyAllCookieConsent: () => void;
};

const CookieConsentContext = createContext<CookieConsentContextType | undefined>(undefined);

Wrapping Up

By ensuring that cookies are set and removed with the domain attribute, your cookie consent preferences will be consistent across all subdomains, resulting in a smoother, more unified user experience. Happy coding!

← Back to posts

We use cookies to improve your experience and analyze our traffic. By using our site, you consent to our use of cookies. You can manage your preferences below: