Shopify Storefront API on Google Cloud Run SSR

To start, everything works locally. I’m using Astro + React with the Shopify Storefront API, and when I build the site, everything works ok.

I get a [ssr] TypeError: fetch failed error when loading the store

I’m using Google Cloud Run.

I have a feeling it has to do with headers, so here’s my request headers

GET /shop HTTP/3
Host: iklectik-image-5mudepf7wa-nw.a.run.app
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/114.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,/;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate, br
Alt-Used: iklectik-image-5mudepf7wa-nw.a.run.app
Connection: keep-alive
Referer: https://iklectik-image-5mudepf7wa-nw.a.run.app/
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
TE: trailers

And my response headers

Status 500 Internal Server Error

Version HTTP/3
Transferred256 B (0 B size) Referrer Policy strict-origin-when-cross-origin
Request Priority Highest

this is the function making the request (typescript isn’t supported here)

const makeShopifyRequest = async (
query: string,
variables: Record<string, unknown> = {},
buyerIP: string = “”
) => {
const isSSR = import.meta.env.SSR;
const apiUrl = https://${config.shopifyShop}/api/${config.apiVersion}/graphql.json;

function getOptions() {
// If the request is made from the server, we need to pass the private access token and the buyer IP
isSSR &&
!buyerIP &&
console.error(
:red_circle: No buyer IP provided => make sure to pass the buyer IP when making a server side Shopify request.
);

const { privateShopifyAccessToken, publicShopifyAccessToken } = config;
const options = {
method: “POST”,
headers: {},
body: JSON.stringify({ query, variables }),
};
// Check if the Shopify request is made from the server or the client
if (isSSR) {
options.headers = {
“Content-Type”: “application/json”,
“Shopify-Storefront-Private-Token”: privateShopifyAccessToken,
“Shopify-Storefront-Buyer-IP”: buyerIP,
};
return options;
}
options.headers = {
“Content-Type”: “application/json”,
“X-Shopify-Storefront-Access-Token”: publicShopifyAccessToken,
};

return options;
}

const response = await fetch(apiUrl, getOptions());

if (!response.ok) {
const body = await response.text();
throw new Error(${response.status} ${body});
}

const json = await response.json();
if (json.errors) {
throw new Error(json.errors.map((e: Error) => e.message).join(“\n”));
}

return json.data;
};

I fixed it. I switched from “import.meta” to “process” with the dotenv package