Shopify / Shopify/shopify-app-template-node

Issue with host parameter persistence with App Bridge React v4 updates

Open
#1,332 3 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
1k
Forks
434
PR merge metrics
No merged PRs in 30d

Description

We currently use this template to run an application handling multiple stores. In an attempt to upgrade our @shopify/app-bridge-react module to v4 we have encountered a series of changes that have broken the app in multiple places. I've fixed all bar the "host parameter is missing" issue. This occurs when the store auth callback is run, the initial page is loaded correctly, but then upon navigation, the host parameter is no longer persisted across pages, and as such the page fails to load app bridge.

I am using the default functions built in to handle auth and callback (shopify.auth.begin() and shopify.auth.callback()) and it seems to work but it's just the frontend app with React and Vite that seems to be causing trouble. I have attempted to use createApp() from @shopify/app-bridge to rectify the change from useAppBridge() -> ClientApplication to useAppBridge() -> ShopifyGlobal where we now define const shopifyApp = createApp(config) in the index.jsx file but this seems to be re-rendered on every page, so I can't see how I'm supposed to persist the host value if it's passed through once to the frontend as a parameter.

index.jsx
Below are the files of relevance, if someone could point me in the right direction, I'd be very appreciative:

import { createRoot } from "react-dom/client";
import { createApp } from "@shopify/app-bridge";
import { initI18n } from "./utils/i18nUtils";
const config = {
    apiKey: process.env.SHOPIFY_API_KEY,
    host: new URLSearchParams(location.search).get("host") || window.__SHOPIFY_DEV_HOST,
    forceRedirect: true,
};
console.log(config);
const shopifyApp = createApp(config);
import App from "./App";
const container = document.getElementById("app");
const root = createRoot(container);
root.render(<App app={shopifyApp} />);

server.js

// Just the auth flow
app.get(shopify.config.auth.path, shopify.auth.begin());
app.get(
  shopify.config.auth.callbackPath,
  shopify.auth.callback(),
  // flareInit ends with a call to next() and just does some processing on our end (a few GQL queries and DB calls)
  flareInit,
  shopify.redirectToShopifyOrAppRoot()
);

app.post(
  shopify.config.webhooks.path,
  shopify.processWebhooks({ webhookHandlers: WebhookHandlers })
);

ExitIframe.jsx

import { Redirect } from "@shopify/app-bridge/actions";
import { useAppBridge } from "@shopify/app-bridge-react";
import { useEffect, useState } from "react";
import { useLocation } from "react-router-dom";
import { Banner, Layout, Page, Text } from "@shopify/polaris";

export default function ExitIframe({ app }) {
  const { search } = useLocation();
  const [showWarning, setShowWarning] = useState(false);

  useEffect(() => {
    if (!!app && !!search) {
      const params = new URLSearchParams(search);
      const redirectUri = params.get("redirectUri");
      const url = new URL(decodeURIComponent(redirectUri));

      if (
        [location.hostname, "admin.shopify.com"].includes(url.hostname) ||
        url.hostname.endsWith(".myshopify.com")
      ) {
        const redirect = Redirect.create(app);
        redirect.dispatch(
          Redirect.Action.REMOTE,
          decodeURIComponent(redirectUri)
        );
      } else {
        setShowWarning(true);
      }
    }
  }, [app, search, setShowWarning]);

  return showWarning ? (
    <Page narrowWidth>
      <Layout>
        <Layout.Section>
          <div style={{ marginTop: "100px" }}>
            <Banner title="Redirecting outside of Shopify" status="warning">
              Apps can only use /exitiframe to reach Shopify or the app itself.
            </Banner>
          </div>
        </Layout.Section>
      </Layout>
    </Page>
  ) : <Text>Loading...</Text>
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the host value from index.jsx through the React navigation flow and compare it with the auth and redirect handlers in server.js. Review ExitIframe.jsx and the App Bridge v4 migration behavior; done means the host remains available after navigation and App Bridge loads successfully on subsequent pages.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js, react, vite
Domain
authentication, backend, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.