Hello everyone,
We are developing an application in React/Preact.
We have noticed that when the connection is slow and the user navigates from one page to another via the app menu, the merchant may think that nothing is happening.
We would like to display a loader or loading indicator on the current page (the one the user is on at the time of clicking) to show that an action is in progress.
If we use navigate() from react-router-dom, which works very well when the page is dismantled, but on the app menu, we cannot use navigate() because the button triggers direct navigation.
Our question: what is the best way to display a loader on the current page for all buttons in the app menu, without using navigate()?
We would like the merchant to have immediate visual feedback, even if the navigation takes a few seconds.
Thank you in advance for your advice or implementation examples.
One technique you can use is to check the navigation state in your app and display a loader when the state is not idle.
We use this pattern in a few places, thanks to the useNavigation hook.
Here’s a very basic example:
import { useNavigation } from 'react-router';
export default function App() {
const navigation = useNavigation();
// Display the loader if the page is submitting or loading
if (['submitting', 'loading'].includes(navigation.state)) {
return <s-spinner />;
}
return (
<s-page>
<s-heading>My App</s-heading>
</s-page>
);
}
@Celine_Lamotte you might also want to leverage App Bridge’s loading state to indicate progress. Here’s an update to the earlier example, in React:
import { useEffect } from 'react';
import { useNavigation } from 'react-router';
export default function App() {
const navigation = useNavigation();
const isTransitioning = ['submitting', 'loading'].includes(navigation.state);
// Trigger the Shopify loading state when the page is transitioning
useEffect(() => {
shopify.loading(isTransitioning);
}, [isTransitioning]);
// Display the loader if the page is submitting or loading
if (isTransitioning) {
return <s-spinner />;
}
return (
<s-page>
<s-heading>My App</s-heading>
</s-page>
);
}
Thank you very much for your help, I managed to do what I wanted to do.
1 Like