Embed Yotpo Reviews Widgets in Headless Stores

I am a developer from North Carolina. I have always been fascinated by the internet, and scince high school I have been trying to understand the magic behind it all. ECU Computer Science Graduate
Search for a command to run...

I am a developer from North Carolina. I have always been fascinated by the internet, and scince high school I have been trying to understand the magic behind it all. ECU Computer Science Graduate
No comments yet. Be the first to comment.
As a technical person, it’s always been easy for me to focus on hard skills, numbers, and statistics. This worked well through school, personal projects and smaller teams; environments where I could accomplish a ton on my own. But now I’m working in ...

Currently, I am working on turning a Liquid-based Shopify store into a headless Hydrogen-based store. Part of this was transferring Yotpo embedded forms to the new headless site. As for the loyalty and referrals portion of Yotpo, you can embed these ...

Within Shopify, store owners are restricted from having full control of their store’s checkout page. This is a safety feature on Shopify’s end, protectecting store owners and customers from accidentally (or purposely) exposing private information. Th...

HSTS is HTTPS Strict-Transport-Security. It enforces that only HTTPS is used across your web application, preventing unencrypted traffic being monitored and collected by unwanted entities. HSTS in Hydrogen It can be enabled in your Hydrogen app via r...

I recently wrote an article detailing how to embed Yotpo’s loyalty widgets on a headless site. As I was writing it, I thought “there is no way that the reviews widget will be this troublesome”. I was wrong, it was just as troublesome. For 2 primary reasons.
There’s not a ton of documentation on installing these widgets on a headless source. They have this guide (linked below), but it does not show any of the code examples.
If your Yotpo account is already connected to your Shopify store, the Yotpo reviews dashboard will only generate the embed codes needed for the Shopify store.
Now, on with the tutorial
CSP stands for content security policy. This allows you to import scripts and media from URLs from outside of your site. If you are using Hydrogen, your CSP is located in entry.server.jsx .
If you are using another framework or vanilla JS, you will likely not have a CSP unless you have configured one manually. You can go to the next step if so.
Here are the CSP links you need to allow to use Yotpo in your Hydrogen app.
const {nonce, header, NonceProvider} = createContentSecurityPolicy({
connectSrc: [
'https://cdn-widgetsrepository.yotpo.com',
'https://loyalty.yotpo.com',
],
scriptSrc: [
'https://cdn-widgetsrepository.yotpo.com', // Loader script
'https://loyalty.yotpo.com', // Potential dynamic script loading
],
styleSrc: [
'https://cdn-widgetsrepository.yotpo.com',
'https://loyalty.yotpo.com',
],
imgSrc: [
'https://cdn-widgetsrepository.yotpo.com', // Yotpo-hosted images
'https://loyalty.yotpo.com',
],
mediaSrc: [
'https://cdn-widgetsrepository.yotpo.com',
],
defaultSrc: [
'https://cdn-widgetsrepository.yotpo.com',
'https://loyalty.yotpo.com',
],
});
This could be overkill haha, but I added it in most sources just in case. You likely will only need it in default and script sources.
Copy this script tag into your root component. For Hydrogen, your root component is in the file root.jsx.
<script src="https://cdn-widgetsrepository.yotpo.com/v1/loader/<app_key>" async></script>
Notice that it is asking for your app_key, not your guid (like for the loyalty widgets). This means, if you want to use both Yotpo loyalty widgets and Yotpo reviews widgets, you will need 2 imports.
Go into your Yotpo Reviews dashboard. Select Display On-Site. Select the reviews widget (or any other you want to add) and click the </> button in the top right. Select get the code and copy the code.
Since you are not using Liquid, you will need to alter this a bit like so:
{/* Yotpo Reviews Widget */}
<div
className="yotpo-widget-instance"
data-yotpo-instance-id="<your_instance_id>"
data-yotpo-product-id={product.id.split('/').pop()}
data-yotpo-name={product.title}
data-yotpo-url={`${store_url}/products/${product.handle}`}
data-yotpo-image-url={product.selectedVariant.image.url}
data-yotpo-price={parseFloat(product.selectedVariant.price.amount).toFixed(2)}
data-yotpo-currency={product.selectedVariant.price.currencyCode}
data-yotpo-description={escapeHtml(product.description)}
></div>
For some reason, this is not done automatically. You will need to manually initialize the widgets once the DOM has loaded. This is how I accomplished this within a useEffect hook.
// initialize yotpo widgets
useEffect(() => {
const initializeWidgets = () => {
if (
window.yotpoWidgetsContainer &&
typeof window.yotpoWidgetsContainer.initWidgets === "function"
) {
yotpoWidgetsContainer.initWidgets();
}
};
if (document.readyState === "complete") {
initializeWidgets();
} else {
const handleLoad = () => {
initializeWidgets();
};
window.addEventListener("load", handleLoad);
return () => window.removeEventListener("load", handleLoad);
}
}, []);
This should be it! If not, carefully go back and look over all of your code and read the text I have included. If you are still having issues, you can reach out to me or view the Yotpo documentation. Yotpo also has a very good support chat, but keep in mind that some of the Yotpo support team is not aware of issues surrounding headless stores and integration.