This folder contains an example implementation of the Shopify Cookie Banner based on the Customer Privacy API.
More specifically, this example demonstrates how to load an admin-customizable banner that allows merchants to accept or reject marketing tracking cookies.
This folder contains the minimal set of files needed to showcase the implementation. Files that aren’t included by default with Hydrogen and that you’ll need to create are labeled with 🆕.
File | Description |
---|---|
🆕 app/components/ShopifyCookieBanner.tsx |
A component that loads the Shopify cookie banner |
app/root.tsx |
The root layout modified to display the consent banner |
app/remix.env.d.ts |
Typescript Remix definitions |
app/entry.server.tsx |
Remix entry server component |
Important
During development, you can force the banner by passing ?preview_privacy_banner=1
h2 link
Add the PUBLIC_CHECKOUT_DOMAIN
environment to your local .env and admin.
+ PUBLIC_CHECKOUT_DOMAIN="checkout.hydrogen.shop"
Add the PUBLIC_CHECKOUT_DOMAIN
variable to the Env
interface inside remix.d.ts
interface Env {
SESSION_SECRET: string;
PUBLIC_STOREFRONT_API_TOKEN: string;
PRIVATE_STOREFRONT_API_TOKEN: string;
PUBLIC_STORE_DOMAIN: string;
PUBLIC_STOREFRONT_ID: string;
PUBLIC_CUSTOMER_ACCOUNT_API_CLIENT_ID: string;
PUBLIC_CUSTOMER_ACCOUNT_API_URL: string;
+ PUBLIC_CHECKOUT_DOMAIN: string;
}
View the complete component file to see these updates in context.
Create ShopifyCookieBanner.tsx
inside app/components/
import {Script} from '@shopify/hydrogen';
import {useEffect, useRef} from 'react';
declare global {
interface Window {
privacyBanner: {
loadBanner: (options: PrivacyConsentBannerProps) => void;
};
}
}
type PrivacyConsentBannerProps = {
checkoutRootDomain: string;
shopDomain: string;
storefrontAccessToken: string;
storefrontRootDomain: string;
};
/**
* A component that loads the Shopify privacy consent banner.
* @param props - The props to pass to the privacy consent banner.
* @returns A component that loads the Shopify privacy consent banner.
* @link https://shopify.dev/docs/api/customer-privacy#installation-on-a-custom-storefront
* @example while testing you can force the banner pass ?preview_privacy_banner=1
*/
export function ShopifyCookieBanner(props: PrivacyConsentBannerProps) {
const loaded = useRef(false);
useEffect(() => {
if (!window?.privacyBanner || loaded.current) {
return;
}
window?.privacyBanner?.loadBanner(props);
loaded.current = true;
}, [props]);
// NOTE: load the script regardless the need for consent or not
return (
<Script
id="consent-privacy-banner"
src="https://cdn.shopify.com/shopifycloud/privacy-banner/storefront-banner.js"
async={false}
/>
);
}
View the complete component file to see these updates in context.
Import the ShopifyCookieBanner
component in app/root.tsx
+ import {ShopifyCookieBanner} from '~/components/ShopifyCookieBanner';
Pass the required environment variables to the client by returning them from the loader
export async function loader({context}: LoaderFunctionArgs) {
// other code ...
return defer(
{
cart: cartPromise,
isLoggedIn: isLoggedInPromise,
+ env: {
+ publicStoreDomain: env.PUBLIC_STORE_DOMAIN,
+ checkoutRootDomain: env.PUBLIC_CHECKOUT_DOMAIN,
+ storefrontAccessToken: env.PUBLIC_STOREFRONT_API_TOKEN,
+ storefrontRootDomain: env.PUBLIC_STORE_DOMAIN,
+ },
},
{
headers: {
'Set-Cookie': await context.session.commit(),
},
},
);
}
Render the ShopifyCookieBanner
component inside the root layout
export default function App() {
const nonce = useNonce();
+ const {env} = useLoaderData<typeof loader>();
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<Meta />
<Links />
+ <ShopifyCookieBanner
+ checkoutRootDomain={env.checkoutRootDomain}
+ shopDomain={env.publicStoreDomain}
+ storefrontAccessToken={env.storefrontAccessToken}
+ storefrontRootDomain={env.storefrontRootDomain}
+ />
</head>
<body>
<Outlet />
<ScrollRestoration nonce={nonce} />
<Scripts nonce={nonce} />
<LiveReload nonce={nonce} />
</body>
</html>
);
}
If CSP is enabled, modify /app/entry.server.tsx
like so
- const {nonce, header, NonceProvider} = createContentSecurityPolicy()
+ const {nonce, header, NonceProvider} = createContentSecurityPolicy({
+ connectSrc: [
+ 'https://checkout.hydrogen.shop/api/unstable/graphql.json',
+ 'https://privacy-banner.shopifyapps.com/customization',
+ ],
+ });
View the complete component file to see these updates in context.
You can customize the look and feel of the banner via the Shopify admin by going to
Settings > Customer Privacy > Cookie Banner
In addition to the standard Shopify banner, the Customer Privacy API allows you to build a custom cookie consent banner for your storefront or guard certain activities behind consent.