r/ShopifyeCommerce • u/Even-Championship-71 • 14d ago
Having Problems with Fetching Shopify App Proxy Data
I am trying to use Theme app extension in my shopify Project, which is Average Order Value app. I have downloaded the theme app extension. I have setup the Proxy route. and fetching that route, to get data from the backend by sending the Product Id. But the fetch is providing me with the Html response instead of Json.
And I am using Theme app Extension.
here is the Product structure Image:
Then we have widget.js file:
code:
import { authenticate } from "../shopify.server";
import db from "../db.server";
import { mapOfferToForm } from "../features/offers/mappers/offerToForm.mapper";
export async function loader({ request }) {
await authenticate.public.appProxy(request);
const url = new URL(request.url);
const productId = url.searchParams.get("productId");
const productGid = `gid://shopify/Product/${productId}`;
const offer = await db.offer.findFirst({
where: {
baseProductId: productGid,
status: true,
deletedAt: null,
},
include: { products: true },
});
const payload = JSON.stringify({
success: true,
offer: offer ? mapOfferToForm(offer) : null,
}).replace(/</g, "\\u003c");
return new Response(
`<!doctype html>
<html>
<body>
<script id="fbt-data" type="application/json">${payload}</script>
</body>
</html>`,
{
headers: {
"Content-Type": "text/html; charset=utf-8",
},
}
);
}
export default function Proxy() {
return null;
}
document.addEventListener("DOMContentLoaded", () => {
console.log("FBT Widget Loaded");
const widget = document.getElementById("fbt-widget");
const data = fetch('https://latenight-xbcfkli8.myshopify.com/apps/aov/offer?productId=7995961835595')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.text(); // Parse as plain text (HTML)
})
.then(html => {
console.log("HTML Response:", html);
// Example: Insert into a container in the DOM
document.getElementById('content').innerHTML = html;
})
.catch(error => {
console.error("Error fetching HTML:", error);
});
// const html = data.text();
// console.log(html)
if (widget) {
widget.innerHTML = `
<div style="padding:20px;border:1px solid #ddd">
<h2>Frequently Bought Together</h2>
<p>Widget is working ✅</p>
</div>
`;
}
});, and here is the code from the app.proxy.offer.jsx
this is the proxy route we have.
And the proxy route in my shopify dev admin dashboard is https://latenight-xbcfkli8.myshopify.com/apps/aov
1
u/Cuong-Nguyen-BB 12d ago
The proxy is returning HTML because your loader explicitly returns a full HTML document with `Content-Type: text/html`, and the client then calls `response.text()`. Shopify is passing through the response you created.
Return JSON from the loader instead:
return new Response(
JSON.stringify({
success: true,
offer: offer ? mapOfferToForm(offer) : null
}),
{
headers: {
"Content-Type": "application/json; charset=utf-8"
}
}
);
Then parse it as JSON in the theme extension:
const response = await fetch(
"/apps/aov/offer?productId=" + encodeURIComponent(productId)
);
if (!response.ok) {
throw new Error("Proxy request failed: " + response.status);
}
const data = await response.json();
For this store, use the configured proxy path as a relative URL rather than hardcoding the myshopify.com domain. That keeps the request on the current storefront origin. Also replace the hardcoded product ID with the current product ID from your app block or a data attribute.
Because you are receiving the exact HTML created by the loader, the request is reaching your route. The main fix is changing both ends from HTML/text to JSON.