Coder Social home page Coder Social logo

hydrogen-customer-privacy-api's Introduction

Hydrogen example: Shopify Cookie Consent Banner

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.

Screenshot 2024-02-12 at 5 31 47 PM

Key files

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

Instructions

1. Link your store to inject the required environment variables

h2 link

2. Environment variables

Add the PUBLIC_CHECKOUT_DOMAIN environment to your local .env and admin.

+ PUBLIC_CHECKOUT_DOMAIN="checkout.hydrogen.shop"

3. Modify remix.env.d.ts (TypeScript only)

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.

3. Create the ShopifyCookieBanner.tsx component

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.

4. Modify root.tsx to render the banner component

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>
  );
}

5. Add privacy domain to the Content Security Policy (If applicable)

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.

Customizing the default banner

You can customize the look and feel of the banner via the Shopify admin by going to Settings > Customer Privacy > Cookie Banner

Advanced

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.

hydrogen-customer-privacy-api's People

Contributors

juanpprieto avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.