Shopify / shopify-app-bridge

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

Page refreshes when clicking on navigation menu after using app.dispatch(Redirect.toApp #271

Closed faridmovsumov closed 9 months ago

faridmovsumov commented 9 months ago

Video explanation of the problem: https://www.loom.com/share/799eb63d75a64e9da14ed5239359e509?sid=e24f3e44-a7ae-41eb-a992-fe64c1068418

I have the following primary action.

const primaryActions = {
        content: 'Create New Upload', onAction() {
            app.dispatch(Redirect.toApp({
                path: '/create-upload'
            }));
        }
    };

After redirecting to the correct page, if I click on the navigation item link, then the page refresh happens.

import {Provider, NavigationMenu} from "@shopify/app-bridge-react";
import {AppProvider} from "@shopify/polaris";
import {useState, useMemo, useEffect} from "react";
import enTranslations from "@shopify/polaris/locales/en.json";
import Support from "./components/Support.jsx";
import {useNavigate, Routes, Route} from 'react-router-dom';
import Dashboard from "./components/Dashboard.jsx";
import Settings from "./components/Settings.jsx";
import CreateUpload from "./components/CreateUpload.jsx";
import {getSessionToken} from "@shopify/app-bridge/utilities";
import createApp from "@shopify/app-bridge";
import axios from "axios";
import MatchingResults from "./components/MatchingResults.jsx";
import MyRouter from "./elements/MyRouter.jsx";
import UploadJob from "./components/UploadJob.jsx";
import * as Sentry from "@sentry/react";
import Plans from "./components/Plans.jsx";

const App = () => {

    const [appBridgeConfig] = useState(() => {
        let host = new URLSearchParams(location.search).get("host") || window.__SHOPIFY_HOST;
        window.__SHOPIFY_HOST = host;
        return {
            host,
            apiKey: import.meta.env.VITE_SHOPIFY_API_KEY,
            forceRedirect: true,
        };
    });

    const app = createApp(appBridgeConfig);

    const navigate = useNavigate();
    const history = useMemo(
        () => ({replace: (path) => navigate(path, {replace: true})}),
        [navigate],
    );

    return (

        <AppProvider i18n={enTranslations}>
            <Provider config={appBridgeConfig}>
                <Routes>
                    <Route path="/" element={<Dashboard app={app} axios={axios}/>}/>
                    <Route path="/create-upload" element={<CreateUpload app={app} axios={axios}/>}/>
                    <Route path="/support" element={<Support app={app}/>}/>
                    <Route path="/plans" element={<Plans app={app} axios={axios}/>}/>
                    <Route path="/settings" element={<Settings app={app} axios={axios}/>}/>
                    <Route path="/upload-job/:id" element={<UploadJob app={app} axios={axios}/>}/>
                    <Route path="/matching-results" element={<MatchingResults app={app} axios={axios}/>}/>
                </Routes>
                <MyRouter history={history}/>
                <NavigationMenu
                    navigationLinks={[
                        {
                            label: 'Dashboard',
                            destination: '/',
                        },
                        {
                            label: 'Create New Upload',
                            destination: '/create-upload',
                        },
                        {
                            label: 'Settings',
                            destination: '/settings',
                        },
                        {
                            label: 'Support',
                            destination: '/support',
                        },
                        {
                            label: 'Plans',
                            destination: '/plans',
                        }
                    ]}
                    matcher={(link, location) => {
                        let pathname = location.pathname;
                        if (pathname === "/matching-results") {
                            pathname = "/create-upload";
                        }
                        return link.destination === pathname;
                    }}
                />
            </Provider>
        </AppProvider>

    );
};

export default App;

App ID: 4222617

Versions

"@shopify/app-bridge": "^3.7.9",
"@shopify/app-bridge-react": "^3.7.9",
faridmovsumov commented 9 months ago

I found the solution to the problem. Instead of using

const primaryActions = {
        content: 'Create New Upload', onAction() {
            app.dispatch(Redirect.toApp({
                path: '/create-upload'
            }));
        }
    };

I should use

import {useNavigate} from "react-router-dom";

const navigate = useNavigate();

    const primaryActions = {
        content: 'Create New Upload', onAction() {
            navigate('/create-upload');
        }
    };