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