@zonos/elements
v1.3.142
Published
Zonos component UI for Stripe elements
Downloads
13,712
Readme
Zonos Component UI Introduction
This project offers web components designed primarily for Zonos Checkout, Zonos Hello, and other Zonos products, with a focus on React and Next.js integration. Although not yet tested with other JavaScript libraries and frameworks, the implementation principles for React and Next.js can be adapted for use with other frameworks. For more information about Zonos products, please visit the official Zonos website.
Table of contents
Prerequisites
- Node.js (v18 or higher)
- An API key for Zonos Checkout/Hello (please contact our support team for more information)
Installation
There are two ways to initialize Zonos: via custom integration using a CDN or through npm installation.
Note: All methods below are only using the base configuration to have the Checkout and Hello up and running. For a more secure way to build your cart, please check out our docs for more information.
Brief Zonos.init
base configuration explanation:
checkoutSettings.buildCartDetail
: This callback function retrieves cart item information from your web platform. It should return an array of cart item objects. For the expected type definition, please refer to thebuildCartDetail
and the cart item files.checkoutSettings.placeOrderButtonSelector
: This is used to find all matching selectors and attach an event to trigger the Checkout process. While you can configure this in our Zonos dashboard, it's recommended to set it here so that Zonos can disable your Checkout place order button while loading.zonosApiKey
: An API key for Zonos Checkout/Hello (please contact our support team for more information).storeId
: Store id that your checkout would associate with (please contact our support team for more information).
CDN
CDN when to use:
This is suitable for you if you:
- Use any non-JavaScript frameworks (e.g., PHP, Java, C#).
- Have a static site with pure HTML, CSS, and JavaScript.
- Do not need type references in the project.
- Prefer to use a CDN even if you are using a JavaScript framework (e.g., React, Vue, Next.js).
- Want to quickly test how Zonos functions on your site (e.g., easily drop the script snippet into the Console tab in your browser's developer tools).
CDN usage:
For non-JavaScript frameworks:
Put the
<script>
tag below into the<head>
tag of your HTML:<script> (async function () { const zonosElementsUrl = 'https://js.zonos.com'; const timestamp = new Date().getTime(); const zonosScript = document.querySelector( `script[src*="${zonosElementsUrl}/dist/scripts/loadZonos.js"]`, ); if (!zonosScript) { const script = document.createElement('script'); script.src = `${zonosElementsUrl}/dist/scripts/loadZonos.js?timestamp=${timestamp}`; script.addEventListener( 'load', () => { const getCartItems = async () => { const yourServerUrl = "https://your-server.com/api/get-cart-items"; const response = await fetch(yourServerUrl); const json = await response.json(); return json; }; // Initialize Zonos with your store's settings. // Replace '<%= placeOrderButtonSelector %>', '<%= storeId %>', and '<%= credentialToken %>' // with your actual values. void window.Zonos.init({ checkoutSettings: { buildCartDetail: async () => { const allItems = getCartItems(); return allItems; }, placeOrderButtonSelector: '<%= placeOrderButtonSelector %>', }, storeId: Number('<%= storeId %>'), // Contact support for this information. zonosApiKey: '<%= credentialToken %>', // Contact support for this information }); }, false, ); document.head.appendChild(script); } })(); </script>
For React, Next.js:
Create a typescript file and import
@zonos/elements
to define types definition forwindow
interfaceimport "@zonos/elements";
Create a
ContextProvider
'use client'; import { type ReactNode, createContext, useMemo, useState } from 'react'; import Script from 'next/script'; type ZonosScriptProps = { scriptLoaded: boolean; }; export const ZonosScriptContext = createContext<ZonosScriptProps>({ scriptLoaded: false, }); export const ZonosScriptContextProvider = ({ children, }: { children: ReactNode; }) => { const [scriptLoaded, setScriptLoaded] = useState(false); const context: ZonosScriptProps = { scriptLoaded, }; const timestamp = useMemo(() => Date.now(), []); return ( <ZonosScriptContext.Provider value={context}> <Script onLoad={() => setScriptLoaded(true)} src={`https://js.zonos.com/dist/scripts/loadZonos.js?timestamp=${timestamp}`} /> {children} </ZonosScriptContext.Provider> ); };
Wrap
ZonosScriptContextProvider
into root of yourlayout.tsx
export default function Layout({ children }:{ children: ReactNode}) { return ( <ZonosScriptContextProvider> <main> {children} </main> </ZonosScriptContextProvider> ) }
Create a hook named
useZonosScript.ts
to use the context easierimport { useContext } from 'react'; import { ZonosScriptContext } from 'src/components/ZonosScriptContext'; export const useZonosScript = () => useContext(ZonosScriptContext);
Create component called
ZonosLayoutSetup.tsx
to initializeZonos
.'use client'; import { type ReactNode, useEffect } from 'react'; import { useZonosScript } from 'src/utils/hooks/useZonosScript'; export const ZonosLayoutSetup = ({ children }: { children: ReactNode }) => { const { scriptLoaded } = useZonosScript(); useEffect(() => { // Only initialize Zonos when zonos script is fully loaded. if (!scriptLoaded) { return; } const getCartItems = async () => { const yourServerUrl = "https://your-server.com/api/get-cart-items"; const response = await fetch(yourServerUrl); const json = await response.json(); return json; }; // Initialize Zonos with your store's settings. // Replace '<%= placeOrderButtonSelector %>', '<%= storeId %>', and '<%= credentialToken %>' // with your actual values. void window.Zonos.init({ checkoutSettings: { buildCartDetail: async () => { const allItems = getCartItems(); return allItems; }, placeOrderButtonSelector: '<%= placeOrderButtonSelector %>', }, storeId: Number('<%= storeId %>'), // Contact support for this information. zonosApiKey: '<%= credentialToken %>', // Contact support for this information }); }, [scriptLoaded]); return children; };
Put component
ZonosLayoutSetup.tsx
right underZonosScriptContextProvider
export default function Layout({ children }:{ children: ReactNode}) { return ( <ZonosScriptContextProvider> <ZonosLayoutSetup> <main> {children} </main> </ZonosLayoutSetup> </ZonosScriptContextProvider> ) }
For javascript framework that's not React, Next.js:
Create a typescript file and import
@zonos/elements
to define types definition forwindow
interface. You will have access towindow.Zonos
through out of your project if you are using typescript.import "@zonos/elements";
Npm
Npm when to use:
This method is ideal if you are using TypeScript with modern JavaScript frameworks, particularly React and Next.js. It provides strong typing for the window.Zonos.init function, making setup easier and enabling auto-completion in TypeScript-enabled environments.
Npm usage:
Install @zonos/elements
:
| Package Manager | Command |
|-----------------|-------------------------------|
| pnpm | pnpm add @zonos/elements
|
| npm | npm install @zonos/elements
|
| yarn | yarn add @zonos/elements
|
React, Next.js:
Create a component called
ZonosLayoutSetup.tsx
'use client'; import { type ReactNode, useEffect } from 'react'; import { Zonos } from '@zonos/elements'; import { useZonosScript } from 'src/utils/hooks/useZonosScript'; export const ZonosLayoutSetup = ({ children }: { children: ReactNode }) => { useEffect(() => { // Initialize Zonos into `window` API. window.Zonos = Zonos; const getCartItems = async () => { const yourServerUrl = "https://your-server.com/api/get-cart-items"; const response = await fetch(yourServerUrl); const json = await response.json(); return json; }; // Initialize Zonos void window.Zonos.init({ checkoutSettings: { buildCartDetail: async () => { const allItems = getCartItems(); return allItems; }, placeOrderButtonSelector: '<%= placeOrderButtonSelector %>', }, storeId: Number('<%= storeId %>'), // Contact support for this information. zonosApiKey: '<%= credentialToken %>', // Contact support for this information }); }, [scriptLoaded]); return children; };
Put component
ZonosLayoutSetup.tsx
at top level of yourlayout.tsx
export default function Layout({ children }:{ children: ReactNode}) { return ( <ZonosLayoutSetup> <main> {children} </main> </ZonosLayoutSetup> ) }