I’m building an embedded app using the App Bridge v4 CDN script (app-bridge.js) with a custom backend (Cloudflare Workers + Hono). I’m NOT using the Remix/React Router template.
Setup:
-
<meta name="shopify-api-key" content="..." />in<head> -
<script src="https://cdn.shopify.com/shopifycloud/app-bridge.js"></script>in<head> -
Backend verifies session token JWT via HMAC-SHA256 (standard approach per docs)
-
401 responses include
X-Shopify-Retry-Invalid-Session-Request: 1header
Issue: I see intermittent 401 Unauthorized errors, especially after:
-
Navigating between pages in the app
-
Switching away from the browser and returning after >60 seconds
Looking at the server logs, the Authorization header either contains an expired token or is missing entirely. I see two consecutive 401s for the same endpoint - indicating App Bridge attempted the retry (per the X-Shopify-Retry-Invalid-Session-Request header) but the retry also failed with an expired/missing token.
Workaround: I now manually call shopify.idToken() before each fetch request and set the Authorization header ourselves. This resolves the issue completely - every request gets a fresh token.
if (window.shopify) {
const token = await window.shopify.idToken();
headers["Authorization"] = `Bearer ${token}`;
}
Questions:
-
Is the auto-injection mechanism expected to always provide fresh tokens, or does it cache them?
-
Is manually calling
idToken()the recommended approach for non-Remix apps, or should auto-injection be sufficient? -
The thread at Requests constantly missing JWT describes the same root cause (no validation in the token-setting code). Has this been addressed?
Environment: Shopify API version 2026-01, App Bridge CDN (latest)