Shopify Headless
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 ContentSecurityPolicyAdicione 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',
]
});
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
| undefined;
customer?: Promise
; }; 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 as any)?.email ?? (resolvedCustomer as any)?.emailAddress?.emailAddress ?? null; 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
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 (!name && email) { name = email; } 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; }
Você precisa trocar o CODIGO_BONIFIQ pelo identificador fornecido pelo time da BonifiQ. Cada loja virtual/marca possui seu próprio código.
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
{(customer) => (
)}
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 (
); }
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