I’m trying to find the correct way to reload a Shopify embedded app by code, for example from a button click.
I want to show a simple “Reload app” button in some cases, but the normal reload methods I’ve tried don’t seem to work reliably inside the Shopify Admin embedded app.
Is there a recommended way to do this with App Bridge or another Shopify-supported approach?
I did some digging here. The ID token App Bridge uses to authenticate only lives for ~60 seconds, and it’s meant to be fetched fresh per request rather than reused. When Shopify first loads your app, it hands you a fresh token in the URL (the id_token query parameter). location.reload() just re-requests that same URL, so it may be that the stale token is riding along in the original URL because App Bridge can’t rewrite a top-level reload (location.reload()) the way it can refresh a fetch(), so your backend rejects it. In other words the reload itself isn’t really the problem; it’s that the document request lands carrying a token that has already expired.
A couple of things worth trying, depending on what you actually need the reload to do:
If you just want to refresh what’s on the screen, try doing it without a full reload. For example, re-run your fetch() calls and update your app’s state. App Bridge intercepts fetch() to your app’s domain and automatically attaches a fresh Authorization: Bearer token, so this stays authenticated and sidesteps the expired-token issue entirely. Something like:
async function reload() {
const res = await fetch('/api/data'); // App Bridge adds a fresh token for you
setData(await res.json());
}
This is the path Shopify steers toward, since session-token auth is really designed around apps behaving like single-page apps. Reference: Resource Fetching API
If you genuinely need a hard reload of the whole app, then the thing to look at is how your backend authenticates the initial document request. The robust pattern here is Shopify managed installation + token exchange (e.g. unstable_newEmbeddedAuthStrategy if you’re on the Remix template): you serve the document without requiring a still-valid token up front, let App Bridge boot, grab a fresh token via shopify.idToken(), and authenticate from there. Once auth isn’t tied to a token that has to survive the reload, location.reload() stops throwing access-denied. Refs: About session tokens and Exchange a session token for an access token
Out of curiosity — are you on the token-exchange flow already, or validating a token on the document request directly? That’ll narrow down which of the two is the better fit.