Para incluir a BonifiQ via Shopify Headless é necessário que você inclua no template do Hydrogen alguns componentes e faça alguns ajustes para que o script da BonifiQ rode corretamente.
Libere o ContentSecurityPolicy
Adicione os seguintes itens ao ContentSecurityPolicy do seu entry.server.tsx
const { nonce, header, NonceProvider } = createContentSecurityPolicy({ shop: { checkoutDomain: context.env.PUBLIC_CHECKOUT_DOMAIN, storeDomain: context.env.PUBLIC_STORE_DOMAIN, }, scriptSrc: [ "'self'", 'https://cdn.shopify.com', 'https://bq-scripts.s3.amazonaws.com', 'https://widget.bonifiq.com.br', ], frameSrc: [ 'https://widget.bonifiq.com.br', 'https://landingpage.bonifiq.com.br', ], imgSrc: [ 'https://bq-public-images.s3.amazonaws.com', ] });
Criar um novo componente para o script da BonifiQ
Esse componente adiciona o script da BonifiQ em todo o site. Crie um novo arquivo em /app/components/BqScript.tsx. Inclua o conteúdo abaixo:
import {CartReturn} from '@shopify/hydrogen'; import {useEffect} from 'react'; type Customer = { id?: string; email?: string | null; firstName?: string | null; lastName?: string | null; }; type BqScriptProps = { bonifiqId: string; nonce?: string; cart?: Promise<CartReturn | null> | undefined; customer?: Promise<Customer | null>; }; export function BqScript({ bonifiqId, nonce, cart, customer, }: BqScriptProps) { useEffect(() => { if (!bonifiqId) return; const src = `https://bq-scripts.s3.amazonaws.com/scripts/${bonifiqId}/bqloader.js`; let script: HTMLScriptElement | null = null; let cancelled = false; (async () => { const resolvedCustomer = customer ? await customer : null; // Prefer explicit props; fall back to cart.buyerIdentity let email: string | null | undefined = resolvedCustomer?.email; let id: string | undefined = resolvedCustomer?.id ? resolvedCustomer.id.split('/').pop() : undefined; const customerFullName = resolvedCustomer?.firstName || resolvedCustomer?.lastName ? `${resolvedCustomer.firstName ?? ''} ${ resolvedCustomer.lastName ?? '' }`.trim() : undefined; let name: string | null | undefined = customerFullName; if ((!email || !id || !name) && cart) { try { const resolved = await cart; // <-- resolve the Promise<CartReturn | null> const bi: any = resolved?.buyerIdentity as any | undefined; // In Hydrogen, buyerIdentity has `email` and optional `customer` if (bi) { email = email ?? bi.email ?? bi.customer?.email ?? null; const c = bi.customer as | { id?: string; firstName?: string | null; lastName?: string | null; } | undefined; if (c) { id = id ?? (c.id ? c.id.split('/').pop() : undefined); const firstName = c.firstName ?? null; const lastName = c.lastName ?? null; const fullName = `${firstName ?? ''} ${lastName ?? ''}`.trim(); if (fullName) { name = name ?? fullName; } } } } catch (ex) { console.log('[BonifiQ] Error on customer resolution - ' + ex) } } if (cancelled) return; if (email) sessionStorage.setItem('bqemail', String(email)); if (id) sessionStorage.setItem('bqid', String(id)); if (name) sessionStorage.setItem('bqname', name); script = document.createElement('script'); script.src = src; script.type = 'text/javascript'; script.async = true; if (nonce) script.nonce = nonce; document.head.appendChild(script); })(); return () => { cancelled = true; if (script && document.head.contains(script)) { document.head.removeChild(script); } }; // Re-run if inputs change }, [bonifiqId, nonce, cart, customer]); return null; }
Adicione o componente ao root.tsx
Você precisa trocar o CODIGO_BONIFIQ pelo identificador fornecido pelo time da BonifiQ. Cada loja virtual/marca possui seu próprio código.
<BqScript bonifiqId="CODIGO_BONIFIQ" nonce={nonce} cart={data?.cart}/>
Habilite o Single Sign On
Além de receber o cart, o componente da BonifiQ pode receber também um customer (com id, nome e e-mail). Esse customer deve representar o usuário logado na loja e permite que ele esteja automaticamente logado no Widget da BonifiQ.
Uma sugestão para isso, segue os seguintes passos:
- Adicione um novo arquivo "CustomerBasicQuery.ts" em /app/graphql/customer-account
export const CUSTOMER_QUERY = `#graphql query CustomerBasic { customer { id emailAddress { emailAddress } firstName lastName } } `;
- Leia o customer no root.tsx
const customerPromise = isLoggedInPromise .then(async (logged) => { if (!logged) return null; const res = await customerAccount.query(CUSTOMER_QUERY); const c = res?.data?.customer; if (!c) return null; return { id: c.id, email: c.emailAddress?.emailAddress ?? null, firstName: c.firstName ?? null, lastName: c.lastName ?? null, }; }) .catch((err) => { console.error('Failed to load customer', err); return null; }); return { cart: cart.get(), isLoggedIn: isLoggedInPromise, customer: customerPromise, // Promise footer, }; }
- Informe o customer no BqScript
<Suspense> <Await resolve={data?.customer}> {(customer) => ( <BqScript bonifiqId="493b22a9-aaa4-44ec-9760-29ad95326e54" nonce={nonce} cart={data?.cart} customer={customer} /> )} </Await> </Suspense>
Adicione a Landing Page
Para isso, basta criar um novo arquivo em app/routes chamado ($locale).bq-landingpage.tsx (utilize o nome que desejar)
export default function BQLandingPage() { return ( <div className="bq-landing-page"> <div id="bq-landingpage"></div> </div> ); }
Para que a Landing Page funcione corretamente é necessário instalar o script (via componente) acima
Se precisar de referências/exemplos, verifique o nosso repositório:
https://github.com/bonifiq/bonifiq-shopify-headless/tree/main
Este artigo foi útil?
Que bom!
Obrigado pelo seu feedback
Desculpe! Não conseguimos ajudar você
Obrigado pelo seu feedback
Feedback enviado
Agradecemos seu esforço e tentaremos corrigir o artigo