Questions and discussions about using the Shopify CLI and Shopify-built libraries.
Hello, I tried to use redirect
But it does not work, neither Action.APP nor remote
my package json
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@shopify/app-bridge": "^1.6.8",
"@shopify/app-bridge-react": "^1.6.8",
"@shopify/polaris": "^4.2.1",
"@shopify/react-shopify-app-route-propagator": "^3.0.2",
"@zeit/next-css": "^1.0.1",
"babel-loader": "^8.0.6",
"babel-plugin-transform-class-properties": "^6.24.1",
"fetch": "^1.1.0",
"immutability-helper": "^3.0.1",
"next": "^9.0.6",
"prop-types": "^15.7.2",
"react": "^16.10.2",
"react-addons-update": "^15.6.2",
"react-dom": "^16.10.2",
"react-router-dom": "^5.0.1"
}
Here are a few examples that I have tried already:
I dont see any errors, and console.log('Redirect') is working, so dispatch method does not work
class IndexPage extends React.Component
{
render() {
const primaryAction = {content: 'save', url: '/save'};
const handleRedirect = () => {
console.log('redirect')
const redirect = Redirect.create(app);
redirect.dispatch(Redirect.Action.APP, '/tasks');
};
return (
<Provider config={config} >
<TitleBar title={"MyApp"} primaryAction={primaryAction} />
<AppProvider i18n={{}}>
<div>
<Button onClick={handleRedirect}>Redirect me please</Button>
</div>
</AppProvider>
</Provider>
);
}
}
ReactDOM.render(<IndexPage router={AppRouter}/>, document.getElementById('my-site'));
const app = createApp({
apiKey: 'key',
shopOrigin: 'myshop.myshopify.com',
});
const redirect = Redirect.create(app);
redirect.dispatch(Redirect.Action.APP, '/tasks');
This does not work
Solved! Go to the solution
This is an accepted solution.
Sorry, just tried again and it's working, sorry
this is strange 😕
Hi Neok,
Can you show the code where you're importing `Redirect`? Also, can you try out the development build of App Bridge and see if there are any errors?
It might also be useful to set up Redux DevTools to see if the action is successfully dispatched.
Trish | Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit the Shopify Help Center or the Shopify Blog
`
import {Redirect, History} from '@shopify/app-bridge/actions';
and i tried development build and no errors
Full code of my index.jsx file
import React from 'react';
import ReactDOM from 'react-dom';
import '@shopify/polaris/styles.css';
import {Provider, TitleBar} from '@shopify/app-bridge-react';
import createApp from '@shopify/app-bridge/development';
import {Redirect} from '@shopify/app-bridge/actions';
import {AppProvider, Button} from '@shopify/polaris';
const config = {
apiKey: "SECRET",
shopOrigin: ORIGIN
};
const app = createApp(config);
class IndexPage extends React.Component
{
render() {
const primaryAction = {content: 'save', url: '/save'};
const redirectToProduct = () => {
const redirect = Redirect.create(app);
redirect.dispatch(Redirect.Action.APP, '/tasks');
};
return (
<Provider config={config} >
<TitleBar title={"App"} primaryAction={primaryAction} />
<AppProvider i18n={{}}>
<Button onClick={redirectToProduct}>Redirect me please</Button>
</AppProvider>
</Provider>
);
}
}
ReactDOM.render(<IndexPage />, document.getElementById('my-site'));
And I create a navigation routes in my embedded app so I have `/tasks` route
Hi Neok,
I'm glad it's working for you now! Just a note that when you're using app-bridge-react, you should try to use the same app instance from the `<Provider>` instead of calling `createApp` to create another instance of the app. Creating 2 instances of the app might result in strange behaviours.
You should be able to modify your code as follows:
import React from 'react'; import ReactDOM from 'react-dom'; import '@shopify/polaris/styles.css'; import {Context, Provider, TitleBar} from '@shopify/app-bridge-react'; import {Redirect} from '@shopify/app-bridge/actions'; import {AppProvider, Button} from '@shopify/polaris'; const config = { apiKey: "SECRET", shopOrigin: ORIGIN };
class IndexPage extends React.Component { static contextType = Context; render() {
// Access the same app instance from <Provider/> const app = this.context; const primaryAction = {content: 'save', url: '/save'}; const redirectToProduct = () => { const redirect = Redirect.create(app); redirect.dispatch(Redirect.Action.APP, '/tasks'); }; return ( <AppProvider i18n={{}}> <TitleBar title={"App"} primaryAction={primaryAction} /> <Button onClick={redirectToProduct}>Redirect me please</Button> </AppProvider> ); } } function MyApp() { return ( <Provider config={config}> <IndexPage /> </Provider> ); } ReactDOM.render(<MyApp />, document.getElementById('my-site'));
Cheers,
Trish
Trish | Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit the Shopify Help Center or the Shopify Blog
Hi @Trish_Ta, could you please help me out on getting redirects working?
I followed the documentation here: https://help.shopify.com/en/api/embedded-apps/app-bridge/actions/navigation/redirect
But the redirect isn't working for me.
Here's what I have:
import React from "react";
import createApp from "@shopify/app-bridge"; import { Redirect } from "@shopify/app-bridge/actions"; const app = createApp({ apiKey: "api_key", shopOrigin: "myshopify_url", forceRedirect: true // not sure if needed but I tried with and without }); const redirect = Redirect.create(app); class Page extends React.Component { handleButtonClick = () => { redirect.dispatch(Redirect.Action.APP, "/help"); console.log(app); console.log(redirect); console.log(Redirect); } render() { ... } }
export default Page;
The 3 console.log statements all produce objects with data in them, but the redirect doesn't work.
This component is in a parent like this:
import React from "react"; import { BrowserRouter as Router, Route } from "react-router-dom"; import { AppProvider } from "@shopify/polaris"; class App extends React.Component { render() { return ( <AppProvider> <Router> <Route path="/page" component={Page} /> ...
I'm using <Router> from react-router-dom, I'm wondering if that is causing interference of some sort?
Navigation works fine otherwise, I just can't get a Redirect to happen.
I can change views in my app, but the URL doesn't change and the wrong navigation link is highlighted, so I'm trying to change the URL.
I've also setup Redux Dev Tools and read this: https://help.shopify.com/en/api/embedded-apps/app-bridge/debugging.
No action is taken when the dispatch statement is being called. It seems like it's just not executing.
Any advice on what's wrong or how I can further debug to find why that redirect is not dispatching?
Thanks
Hi Joe,
Your code looks correct to me but there might be something else going on. Could you try using the development version of App Bridge and see if there are any errors? You can import it like this:
import createApp from '@shopify/app-bridge/development';
Trish | Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit the Shopify Help Center or the Shopify Blog
Thanks Trish, I tried this but got the same results. No errors, and all 3 console.log statements are populating.
I'm just not sure what I should be looking for to try and debug this. I followed Shopify documentation exactly, but it's not working and not reporting an error.
I did some more experimentation and can't see why it's not firing the navigation change. There are no other errors in the app, navigation works fine I just can't get the url / nav highlight to change.
Joe, can you clarify this comment?
There are no other errors in the app, navigation works fine I just can't get the url / nav highlight to change.
Does this mean that your app navigates to the requested url but the browser url is not updating? Also, can you confirm that you're testing the app by opening it in a development Shopify store?
Trish | Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit the Shopify Help Center or the Shopify Blog
If I use the Polaris <Link> element, it navigates to the correct location, but the nav highlight and url don't change, so it looks weird. This is how I found about the Redirect feature, from what I understand it's necessary to change the top level nav / url.
Yes I've been testing in a development store. I've built a few embedded Shopify apps, launched public, etc and using the same process. The app is error free ready to submit to the store, otherwise working except the Redirect isn't firing (or the dispatch action, I'm not sure).
It's the final piece 🙂
I was saying there aren't any other errors, just so we can rule out that conflicting javascript error could be causing it. I just can't find any information that will help me debug this... I followed the docs exactly but it's just not working, not giving error message, and not giving any information to help debug.
Joe, I noticed you're calling createApp in your page component. Have you tried passing the apiKey/shopUrl/redirect config to AppProvider or Provider (app-bridge-react)? You might be creating two instances of the app or redirect may not be working since its not associated with one of those providers. Once you initialize the app via a Provider you'll need to import Context from app-bridge/actions and use it via React useContext to access the app. Then you can call Redirect.create(app). Apologies if I missed something.
<Provider config={getAppConfig(props)}> <AppProvider> <Component {...props} /> </AppProvider> </Provider>
import { ContextualSaveBar } from '@shopify/app-bridge/actions' const app = useContext(ShopifyContext); // Redirect.create(app).dispatch(...)
Cheers,
Chris
Thanks for the try Chris but I got the same results.
I used <Provider> inside <AppProvider> according to https://help.shopify.com/en/api/embedded-apps/app-bridge/react-components.
Then I imported context according to https://help.shopify.com/en/api/embedded-apps/app-bridge/react-components/provider#accessing-the-app...
Logging to the console shows I'm getting the app instance in my component successfully.
Same deal though, it just will not fire the dispatch / redirect action.
When I create the redirect and try to dispatch:
const app = this.context;
const redirect = Redirect.create(app); console.log(redirect);
redirect.dispatch(Redirect.Action.APP, "/help");
react.dispatch doesn't do anything. Here's what logs to the console (the redirect😞
I haven't seen what a successful redirect object looks like so I don't know what to look for here, any ideas?
Crazy how much time I'm having to burn just trying to navigate to another page... haha this is insane 😂
Hi Joe,
This is frustrating for sure. I'm trying to think of what else could be preventing it from working. Two ideas come to mind:
1. Are you subscribing to the Redirect action? If you subscribe to app redirects Shopify assumes that your app will handle the redirect and will not change the iframe url: https://help.shopify.com/en/api/embedded-apps/app-bridge/actions/navigation#using-client-side-routin....
2. Can you try dispatching a History push action instead? Since you were able to navigate inside your app using the <Link> component from Polaris, the only thing that was missing is updating the top level url, which could be achieved through the History action. See the docs for more info: https://help.shopify.com/en/api/embedded-apps/app-bridge/actions/navigation/history#push-a-new-histo...
Trish | Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit the Shopify Help Center or the Shopify Blog
@Trish_Ta I appreciate your ideas here... they didn't work but ideas usually get us closer to a solution.
To answer your questions:
1) I've never used subscriptions before so I don't believe I'm subscribing to any existing Redirects.
2) I tried that and have same result: The object populates (console log below), but nothing happens. It's like the dispatch action isn't firing for some reason... or getting blocked somehow.
Yes, in-app navigation works fine it's just I can't get the top level URL and nav link underline to sync up with the view.
I just wish I could get some logs / info to help debug, that would really help debug and take out some guesswork.
P.S. Sorry for hijacking this thread, I couldn't find any good examples or documentation from searching so hopefully this could help the next person pulling their hair out trying to redirect.
@JoesIdeas , did you get to solve this? I have been spending all day today with the same issue. Despite following same steps as in the React Node tutorial, can't get the Redirect to work.
Finally found the issue, it was pretty trivial in my case. I had accidentally given a http URL in Shopify Partners > App Setup > App URL. Changed to https and the redirect is working now.
@JoesIdeas - not sure if it's a similar issue in your case, but do give it a check!
@cyberabis that's a different scenario, my app is already live but the Redirect component is not working even though I've followed Shopify docs exactly. In this case it seems to be a Shopify bug or incorrect documentation but I can't get any help so I just am not using the component.
Good luck on your app dev journey. 👍
👋Hi @JoesIdeas, Hanna here following up with @Trish_Ta's suggestions. I have an idea that's a bit of a shot in the dark. I've heard of cases where the redirect action might need to be chained after creation, like so:
Redirect.create(app).dispatch(Redirect.Action.APP, "/help");
Have you already tried something similar?
Hanna | Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit the Shopify Help Center or the Shopify Blog
Hi @Trish_Ta & @hannachen
I'm having the exact same problem and I think I have a theory as to why it is not working in my case.
The front-end of my app (Single page application) is hosted under a different domain than my backend.
In the Shopify Partner Dashboard, I entered the backend url for my app e.g myshopifyappbackend.com.
After user auth, in the backend, i redirect user to my front-end app myshopifyappfrontend.com where I have App-Bridge instantiated.
On the front-end app, none of the App-Bridge actions work and I believe it is because it is using a different domain.
I see in the console a bunch of postMessage going to shopify but it looks like Shopify ignores them because they come from a different domain.
Is that theory accurate?
Can App-bridge be used in an app with a different domain than the one defined in Partner dashboard?
My goal is to have the following flow:
-User install the app and is redirected to a pricing page with different plans (in my front end app)
-When user picks a plan, user is redirected to the Shopify Charges page with the right subscription options.
Do you have any recommendations/best practices to architect this flow with having 2 domains as I do?
Thanks a lot.
Hi @benei55 it sounds like you might have encountered a security restriction. The app domain shown through the embedded frame cannot be different from the app URL defined in the partner dashboard. However, you can define multiple whitelisted callback domains. In this case, you might want to set your front-end app domain to be the app URL, and add your back-end callback URL as the callback URL (basically flip the two). Does this work?
Hanna | Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit the Shopify Help Center or the Shopify Blog
Wow it took me 6 hours to find this post and figure out why the app bridge just wasn't working and failed silently. You'd think that if you white listed the urls you are using for your app and each one had the api key that would be enough. So now it's impossible to develop with ngrok locally because ngrok does not handle different ports from the same machine. This is a nightmare of a development experience. At least some sort of error would have been nice. On top of the confusion between polaris resource picker being deprecated and the different ways to initiate the provider this is just one of the most impossible bugs to figure out.
Many people like myself have an api server that is a different sub-domain from their UI elements. I'm using firebase. I did figure out how to get it all on the same subdomain for production, but that still means that in order to work with app bridge I'm going to have to write everything and upload to the server every time because I can't run my whole firebase project through 1 ngrok. Thanks.
same.
Hi guys,
In my case it was due to using authenticatedFetch from @Shopify/app-bridge-utils. I manually added the Authorization header with getSessionToken.
// Client provider is a custom provider I wrote which I am using with Urql GraphQL library
export default function ClientProvider({ children }) {
const appBridge = useAppBridge();
const [sessionToken, setSessionToken] = useState<string>();
useEffect(() => {
getSessionToken(appBridge as any).then((token) => {
client.fetchOptions = () => ({
headers: token ? { authorization: `Bearer ${token}` } : {},
method: "POST",
});
setSessionToken(token);
});
}, [appBridge]);
if (!sessionToken) {
return null;
}
return <Provider value={client}>{children}</Provider>;
}
Just wrote to let you know - you are totally on-point with your different-domains diagnosis.
this is exactly the issue, I'm, currently experiencing the same problem, I'm trying to get the app state or even just the defined location..
i had a chat with a Shopify staff member and he told me that this is the problem, I'm pasting his suggestion here:
"If you have two different domains, the way it could work is use alias.
For example: Set application domain in your app on Shopify https://www.yourapp.io/
The front end is hosted at https://www.yourapp.io/app
All other requests from https://www.yourapp.io/* will be alias to the backend https://yourapp.azurewebsites.net/*"
imho? i think this is not a good solution at all, and i will probably try anything and everything else prior to renaming my infrastructure and jumping through the CDN hoops
This is an accepted solution.
Sorry, just tried again and it's working, sorry
this is strange 😕