Shopify / shopify-app-bridge

https://shopify.dev/docs/api/app-bridge
88 stars 9 forks source link

App is incorrectly reported as outdated if it takes too long to load #160

Closed matthewhilton closed 5 months ago

matthewhilton commented 1 year ago

Describe the bug

If an app takes too long to load, it will be incorrectly reported as being outdated when using an admin.shopify.com domain (aka unified admin)

I have checked my app configuration (app bridge, frame ancestors headers, etc...) and all is following the guidelines.

The error originally showed occasionally when the app loaded for the first time in a new browser, which makes sense as the load time will be slightly longer due to caching js, css, etc. This would happen about 1 in 10 loads.

If I introduce an artificial sleep of for e.g. 5 seconds in my app loading route, the error shows up 100% the time.

image

To Reproduce

Steps to reproduce the behaviour:

Prerequisites:

  1. Be on the new unified admin domain e.g. admin.shopify.com/stores/xyz
  2. Introduce an artificial sleep of 5 seconds in the app load script to simulate a slow network connection / fresh load of app

Reproduce:

  1. Launch app
  2. Error is shown

Expected behaviour

I am guessing it is checking for the existence of the AppBridgeProvider, albeit slightly too early. However since App bridge is closed source this is just a guess.

I would expect that the Admin UI waits until the app is completely loaded before checking for its existence.

Contextual information

Packages and versions

Platform

meltinbit commented 1 year ago

same for me, my app approval was rejected cause of this issue As reported here in the screenshot the problem happens on new installations. After few hours the App is no longer opening in a new tab, even if it is uninstalled and installed again. If I try on a new store where it has never been installed the problem happens again.

Screenshot 2023-02-15 at 12 00 42

mkmk89 commented 1 year ago

same for me

OleksiiShevchenko commented 1 year ago

@kragotte Hi, we are trying to get our app approved, and currently we are stuck because of the banner issue. On 2 of our development stores the app works fine without banner showing up, but on all other stores including the new ones we create the banner appears while testing the same application. We have CSP correctly configured, App bridge is the latest version.

blazeorion commented 1 year ago

@kragotte this is still a problem for me

huynq2007 commented 1 year ago

@kragotte Same issues here. We have been submitting our app but it got rejected due to the banner issue. We have confirmed that the App bridge version and CSP are correctly configured already. After trying to resubmit our app, we have not received any feedback from the review team yet. I guess we need to wait for a more few days

qq99 commented 1 year ago

Still an issue for me as well, I reviewed to ensure I have the proper CSP headers too, as well as "@shopify/app-bridge": "^3.1.0",

mohan-mensabrands commented 1 year ago

Hi all - apologies for the delayed response, we have identified a bug related to showing the banner on new installs of recently updated apps. We are actively working on a solution. Please note that while all partner dev stores are on the new domain URL, the vast majority of merchants are not.

While we work on the bug fix, we do have a manual process in place to opt out apps that have shown a successful load in the new admin domain. If you retry your apps this morning, if they have successful loaded successfully in the new admin domain, they should no longer be showing the banner or redirect on existing installs or new installs. If you are still experiencing issues please @ me.

Hi @kragotte I am stuck with this. I have submitted the app for review and reviewer is not passing my app from last week. The problem is still persisting with new stores. Please help.

qq99 commented 1 year ago

image Seeing this for the first time today when going to re-submit app for review

image

I started wondering if perhaps it's due to the ordering of the hosts in the CSP directive? They're not exactly as banner desires

rosantoz commented 1 year ago

For everyone stuck at the review process because of this:

The way I solved was by sending a support request via the partner portal asking them to opt out the app from this feature.

Here's the response from the Partner Support:

I just wanted to update you that our current work around for this issue is to add beta feature to remove this banner. I would like to share with you that I have added this feature and this issue should be resolved for now.

Unfortunately we are forced to use App Bridge for embedded apps, but when things go wrong on Shopify's side there not communication or support. Partners are left to figure out things by themselves.

This issue as reported 106 days ago and there's still no resolution. I'm sure a company with a $58b market cap can afford a developer or a small team to take care of things like this. It's really disappointing how this has been handled so far.

I hope this helps whoever is stuck in the review process because of this.

webrexRavi commented 1 year ago

@kragotte still happening in my app, need your help on this

Is anyone else found the solution ?

webrexRavi commented 1 year ago

Now it is working for me(Resolved automatically), day before yesterday it wasn't.

I think it may take some time to get resolved from shopify's end (their data pipeline can take upto 3 hours to update) - https://github.com/Shopify/shopify-app-bridge/issues/160#issuecomment-1430527337

PaulvdDool commented 1 year ago

My app is still opening in a new app as soon as I click the link to open it. The new tab is already triggered before a my app is properly loaded (checked by adding a console.log to the pages/_app.tsx file in my NextJS project).

I no longer get the banner that says the app loads too slow, but the opening in new tab is still there.

The correct Content-Security-Policy is added to all my requests. I'm using App Bridge through the @shopify/app-bridge package that is on version 3.7.4. So in that sense I meet all conditions.

Since this issue has been mostly dormant for the last month I'm wondering if I'm alone on this issue.

tomfarm commented 1 year ago

@PaulvdDool I'm having the same issue right now. @shopify/app-bridge package version 3.7.4. The app opens a new tab every! time. I'm testing this with a dev app on a dev shop, but the production version is behaving the same.

I've stripped the app to the complete minimum, only calling createApp with the shopify supplied parameters. It does not matter if forceRedirect is true or false, originHost is set or not …

After a click on the app in the sidebar, the app loads 'fine' on the admin.myshopify.com (I'm not getting a banner), but opens a new tab anyways using the old shopname.myshopify.com domain and an added force_legacy_domain=1

and then theres this JS error in the logs like "Unable to post message to https://<shopname>.myshopify.com. Recipient has origin https://admin.shopify.com.

🤷‍♂️

PhiloNL commented 1 year ago

@kragotte I'm still having this issue. I also don't quite understand why this occurs for only some of my apps (while they use the same base framework). Any update on how to resolve this?

kj commented 1 year ago

I'm also experiencing this as of about a week ago, even though I am pretty sure I have the CSP's frame-ancestors set up properly and am on the newest version of App Bridge. It also only occurs on my dev app, not my production app, although my dev app is undergoing a major rewrite.

immakdas commented 1 year ago

latest app bridge 3.7.7 and policy set to Content-Security-Policy: frame-ancestors https://' . $_REQUEST['shop'] . ' https://admin.shopify.com; keep redirecting the app to the old https://*.myshopify.com and blocking it

kj commented 1 year ago

Strangely it's suddenly working for me today, with no legacy domain popup. I didn't change anything (today specifically), and I have had the popup consistently for the last month, so I'm not sure if Shopify fixed something on their end, or marked my app in some way (as I've been in contact with support). They haven't said anything at least, but I'll update if it starts happening again. I was on 3.7.6 when I noticed the popup was gone, so I just updated to 3.7.7 and still okay.

felixmpaulus commented 1 year ago

Still happening for me.

Two tabs open (one with force_legacy_domain=1), the app loads in both.

This bug is also occurring when cloning https://github.com/Shopify/shopify-app-template-node and running yarn dev

prashant-chai commented 1 year ago

It is happening with our app too.

Two tabs open and one of the tabs with force_legacy_domain=1, the app loads in both. Received an email from the Shopify team about sending Content-Security-Policy: frame-ancestors in response headers but the app already does it

app.use((req, res, next) => {
    const shop = req.query.shop;
    if (Shopify.Context.IS_EMBEDDED_APP && shop) {
      res.setHeader(
        "Content-Security-Policy",
        `frame-ancestors https://${shop} https://admin.shopify.com;`
      );
    } else {
      res.setHeader("Content-Security-Policy", `frame-ancestors 'none';`);
    }
    next();
  });

https://github.com/Shopify/shopify-app-bridge/assets/88648714/912164a5-fd36-4ec7-b742-651691bec1e6

phongdh-lftv commented 1 year ago

For embedded apps to work correctly on the new admin domain, ensure: I. The content security policy includes admin.shopify.com. II. The app is on App Bridge 2.0 or higher. We recommend upgrading to App Bridge 3.0. III. The app has correctly implemented the host parameter.

I) Set The Content Security Policy

const shop = req.query.shop;
res.setHeader(
      "Content-Security-Policy",
      `default-src https: 'self'; script-src https: 'unsafe-inline' 'unsafe-eval' 'self' unpkg.com cdn.shopify.com cdn.shopifycloud.com; style-src https: 'unsafe-inline' cdn.shopifycloud.com; img-src 'self' https: data: cdn.shopifycloud.com blob:; upgrade-insecure-requests; frame-ancestors https://${shop} https://admin.shopify.com;`
    );

II) By way use App Bridge 3.0, in your embedded app

<script src="https://unpkg.com/@shopify/app-bridge@3"></script>
<script>
    const AppBridge = window['app-bridge'];
    const appBridge = AppBridge.createApp({
        apiKey: '<Client ID in your app>',
        host: new URLSearchParams(location.search).get("host"),
        forceRedirect: true
    });
</script>

III) Use host parameter As you see in II) host: new URLSearchParams(location.search).get("host"),. Please keep this. DO NOT CHANGE

OPTIONAL

If you want to use session token authentication so then

1. Get session token

AppBridge.utilities.getSessionToken(appBridge).then(function(sesionToken) {
    console.log(sesionToken);
});

2. Using session token

$.ajax({
    .
    .
    "headers": {
        "Authorization": `Bearer ${sessionToken}`,
    }
    .
    .
});

3. Verify session token with Client secret in your app. Use package: jsonwebtoken (https://www.npmjs.com/package/jsonwebtoken)

'use strict';
const jwt = require('jsonwebtoken');

const verifyToken = (token) => {
  return new Promise((resolve, reject) => {
    jwt.verify(token, 'Client secret in your app', (error, decoded) => {
      if (error) {
        return reject(error);
      }

      resolve(decoded);
    });
  });
};

const data = verifyToken('your session token from request.headers.authorization')

Finally

SHOPIFY manually verify if you’ve completed. It take about one working day

sondvlifull commented 1 year ago

@phongdh-lftv it is working for me. Thanks

rgopalakeans commented 10 months ago

Hi Team,

Actually, this app running with Core PHP & MySQL. Other than that, there is no "Node" or "React" kind of JavaScript libraries. So, there is no "App Bridge" kind of components. App completely build with HTML, CSS, Bootstrap Lib, PHP-MySQL, and jQuery.

Actually, our app has to load below URL,

https://admin.shopify.com/store/akeans-upload-hike/apps/akeans-upload-hike

Instead of this, it's automatically Re-directed to,

https://akeans-upload-hike.myshopify.com/admin/apps/akeans-upload-hike?force_legacy_domain=1

When we check "learn more", this is what we are getting, https://changelog.shopify.com/posts/shopify-admin-now-lives-at-admin-shopify-com

Please check this video for reference:

https://www.loom.com/share/9437301b6bdb4417b503b40e567214ae?sid=c0cfdfcf-a52d-4cb2-91cf-f42a7bc87b3a

Please let me know, if anything needs from our side.

Thanks, Gopal R

jainml151170 commented 10 months ago

Hi Team,

Actually, this app running with Laravel & MySQL. There is "React" kind of JavaScript libraries. App completely build with Laravel and React.

Actually, our app has to load below URL,

https://admin.shopify.com/store/testdcg2/apps/dcg-3

Instead of this, it's automatically Re-directed to,

https://testdcg2.myshopify.com/admin/apps/dcg-3?force_legacy_domain=1

When we check "learn more", this is what we are getting, https://changelog.shopify.com/posts/shopify-admin-now-lives-at-admin-shopify-com

Please check this video for reference:

https://www.awesomescreenshot.com/video/23647089?key=df7207707a0d52b2c70db5512309491f

Please let me know, if anything needs from our side.

thesunilyadav commented 10 months ago

For embedded apps to work correctly on the new admin domain, ensure: I. The content security policy includes admin.shopify.com. II. The app is on App Bridge 2.0 or higher. We recommend upgrading to App Bridge 3.0. III. The app has correctly implemented the host parameter.

I) Set The Content Security Policy

const shop = req.query.shop;
res.setHeader(
      "Content-Security-Policy",
      `default-src https: 'self'; script-src https: 'unsafe-inline' 'unsafe-eval' 'self' unpkg.com cdn.shopify.com cdn.shopifycloud.com; style-src https: 'unsafe-inline' cdn.shopifycloud.com; img-src 'self' https: data: cdn.shopifycloud.com blob:; upgrade-insecure-requests; frame-ancestors https://${shop} https://admin.shopify.com;`
    );

II) By way use App Bridge 3.0, in your embedded app

<script src="https://unpkg.com/@shopify/app-bridge@3"></script>
<script>
    const AppBridge = window['app-bridge'];
    const appBridge = AppBridge.createApp({
        apiKey: '<Client ID in your app>',
        host: new URLSearchParams(location.search).get("host"),
        forceRedirect: true
    });
</script>

III) Use host parameter As you see in II) host: new URLSearchParams(location.search).get("host"),. Please keep this. DO NOT CHANGE

OPTIONAL

If you want to use session token authentication so then

1. Get session token

AppBridge.utilities.getSessionToken(appBridge).then(function(sesionToken) {
    console.log(sesionToken);
});

2. Using session token

$.ajax({
    .
    .
    "headers": {
        "Authorization": `Bearer ${sessionToken}`,
    }
    .
    .
});

3. Verify session token with Client secret in your app. Use package: jsonwebtoken (https://www.npmjs.com/package/jsonwebtoken)

'use strict';
const jwt = require('jsonwebtoken');

const verifyToken = (token) => {
  return new Promise((resolve, reject) => {
    jwt.verify(token, 'Client secret in your app', (error, decoded) => {
      if (error) {
        return reject(error);
      }

      resolve(decoded);
    });
  });
};

const data = verifyToken('your session token from request.headers.authorization')

Finally

SHOPIFY manually verify if you’ve completed. It take about one working day

I've followed the same process, but I'm still encountering an issue. The app consistently opens in a new tab. Could anyone please provide additional guidance or suggestions to help resolve this matter? Your assistance is much appreciated.

prashant-chai commented 10 months ago

Hi @thesunilyadav , the key is not to add the app URL as your backend, it should hit the frontend app and then you can do your processing or forward the the request to backend

thesunilyadav commented 10 months ago

Hi @thesunilyadav , the key is not to add the app URL as your backend, it should hit the frontend app and then you can do your processing or forward the the request to backend

We have a Laravel app that combines both the front-end and backend. Therefore, the host or App URL is identical for both the front-end and backend

cdossantos15 commented 7 months ago

Hello, we are moving our app from a standalone app to an embedded app and are experiencing this as well (exactly as this previous comment) -- using the latest CDN version of AppBridge with React and Node and including the Content-Security-Policy header. App ID: 1178253.

Our app consistently opens in a new tab despite including all the requirements, from what we can tell, and optimizing load speeds to under a second. We don't usually get a banner, however. The main issue is the new tab. It seems to be triggered before or at the same time as our AppURL is called.

We've temporarily disabled app embedding because of the issue.

charlesdobson commented 7 months ago

Hi @cdossantos15,

I've enabled the flag for your app (ID: 1178253). Please try embedding again and let me know if you have any issues!

cdossantos15 commented 6 months ago

Hi @charlesdobson, thanks for looking into this for us. We're able to embed without the new tab and banner.

However, we're noticing that there's a significant delay from when someone clicks on our app and when Shopify calls our App URL. The timing that we are seeing often is: User clicks on our app, ~3 seconds later Shopify calls our App URL, our App returns in ~300ms. We are concerned about how this appears to users since from what we can control, our app takes on average 300ms. We believe the extra loading time is reflecting badly on our load speeds. It appears that this does not happen with other apps and they are loaded in in 1s or less.

Do you have any insight on this, any settings we need to toggle, or anything that can be done? Thanks!

lexcao commented 6 months ago

Hi @charlesdobson We have met the same issue, could you please try enabling the flag for our App (ID: 6155457)

charlesdobson commented 6 months ago

@lexcao Done. Please try it out again :)

lexcao commented 6 months ago

Hi @charlesdobson It works! Thank you, you are awesome!

geoffrey-syncx commented 5 months ago

Hi @charlesdobson My company (partner id:174529) app StockSync (id: 198941) just turn on the embed option, having the same issue which is open a new tab with legacy link when clicked in shopify admin. In a result that, loading 2 app in 2 tab. Can you help look into that?

The banner Stock Sync: Inventory Sync will open in a new tab also appear for new device

Another question I want to ask, is the requirement of App Bridge ver 3 is able to fulfil by using CDN version of app bridge (https://shopify.dev/docs/api/app-bridge-library)?

By the time you check the app, the embed option might be turned off due to avoid bad user experience.

Updated after few days: the open tab issue was solved automatically

agafonec commented 5 months ago

Hi @charlesdobson , i'm facing same issue after moving from standalone app to embedded app that it's opening 1 extra tab with some url parameter force_legacy_domain=1. i'm using laravel and vue for the app with latest app bridge version, and also including the Content-Security-Policy header.

this is my App ID: 22693412865 (hopefully it's correct one i took it from url in partners dashboard). if you can help me with that it would be great. thanks

huynhmaianhkiet commented 5 months ago

I have encountered an issue after transitioning from a standalone app to an embedded app. Although our app is still functioning properly, I have received a warning stating "This app is taking a while to load". Even when I tried to make my dashboard app empty (without any code), the warning continued to appear.

Screenshot 2024-05-19 at 15 30 53

However, I found that if I add the parameter "?force_legacy_domain=1" when loading the app, the warning does not appear.

I am currently using the app with the latest App Bridge version and have also included the Content-Security-Policy header.

I would greatly appreciate your assistance with this matter.

Thank you

charlesdobson commented 5 months ago

@geoffrey-syncx That flag has been turned on for Stock Sync. And that's correct, using App Bridge via the CDN satisfies version requirements.

charlesdobson commented 5 months ago

@agafonec Looks like it's already added. Let me know if the issue is not resolved for you!

charlesdobson commented 5 months ago

@huynhmaianhkiet what's your app ID?

charlesdobson commented 5 months ago

I'm closing out this issue for now as the original issue posted has been resolved.

Please continue to ask for support either here or on the Partners Slack if you're having issues with your app loading in a new tab. Thanks all!

mfyz commented 4 months ago

...we're noticing that there's a significant delay from when someone clicks on our app and when Shopify calls our App URL. The timing that we are seeing often is: User clicks on our app, ~3 seconds later Shopify calls our App URL, our App returns in ~300ms. We are concerned about how this appears to users since from what we can control, our app takes on average 300ms. We believe the extra loading time is reflecting badly on our load speeds. It appears that this does not happen with other apps and they are loaded in in 1s or less.

My app is having exact same behavior. Shopify takes about 2-3 seconds before the iframe hits my app and my app renders in 300ish ms. And the page loads and all, then in 1-2 seconds later, I get the "This app is taking a while to load." banner which is weird because the app is loaded, there is no web vitals activity (like LCP, and all is already resolved in the "performance profiler"). My app init is pretty snappy (although I just optimized it).

Screen Recording: Screenshot 2024-06-20 16 29 57

Is this a meta flag that my app got flagged when it was running on older version of app-bridge-react, and now I upgraded, will it take some time to shopify to detect the speed improvement, and reverse the flag? Is that what you were doing manually @charlesdobson ? I definitely see, doing this manually is not the way, and I'm ok to wait it out, but if it will not go away by itself, then I need to understand what's the next steps...


Update: Seems it's a crawler/data sort thing. The pop-up stayed for a day and now disappeared.

djhayman commented 2 months ago

Hi @charlesdobson,

Please continue to ask for support either here or on the Partners Slack if you're having issues with your app loading in a new tab. Thanks all!

We are having the same issue as @mfyz above where our app is using the latest AppBridge CDN, session tokens, has all the necessary CSP headers, is loading within about 300ms, and then 5 seconds after load completes is showing the "This app is taking a while to load" banner.

Is this something you can help with please? Our app ID is 4581575.

djhayman commented 2 months ago

Please disregard, someone at Shopify Partner Support was able to resolve the issue

itsmekhmtz commented 2 months ago

I am still facing the same issue

Image

This is App Bridge CDN that we are using

Below is the code that we are using

Content-Security-Policy header are also passing but still issue is persist

henrytao-me commented 2 months ago

@itsmekhmtz can you leave your appId here?

itsmekhmtz commented 2 months ago

@henrytao-me here are the appid's

6964163 4699243 4990157 4679075

itsmekhmtz commented 2 months ago

@henrytao-me I am also getting the APP::ERROR::INVALID_ORIGIN in the console when creating an app with appbridge. Application is divided into two different parts Server Side and Client App URL Added in Shopify App Level is for Server Side Application Server Side Application redirected user to Client Side Application How to handle this error

geoffrey-syncx commented 2 months ago

Hi @henrytao-me here is my app 1270200 Production App

I am try to make my production app (1270200) embed, when i test on test app (66919104513), it works ok, but when on production app (1270200), it show an error APP::ERROR::INVALID_CONFIG: host must be provided

Image

I found that this error is come from app bridge ver 2

but i am using app bridge ver cdn

geoffrey-syncx commented 1 month ago

Hi @henrytao-me ,

syncX Order Export id:1270200

It show the outdated warning banner, but i am using cdn ver app bridge

Can you help me to remove, since it confuse our users

Image

Image

huynhmaianhkiet commented 1 month ago

You might be using an outdated version of Rest API or GraphQL. Please verify and, if necessary, update to the most recent version.