Custom routing
By default, Product Fruits uses window.location.href
to read and set URLs. This works for traditional multi-page applications, but can disrupt single-page applications (SPAs) by causing full-page reloads instead of leveraging client-side routing.
To resolve this, Product Fruits provides a custom routing system that integrates with your application's existing navigation logic.
Custom routing options
To implement custom routing, provide a customNavigation
object when initializing Product Fruits. This can be done either through:
- the
init
function (for the npm package), or - the
config
prop (for the React component).
The customNavigation
object must also implement the following two methods:
navigate(url, openInNewTab)
- This method handles all navigation requests from Product Fruits.
- Parameters:
url
(string): The target URL.- optional -
openInNewTab
(boolean): Indicates whether to open the URL in a new browser tab(true)
or not(false)
.
onGet()
- Returns the current URL whenever Product Fruits needs it.
- Requirements:
- Must return a fully qualified URL (starting with
https://
). In most SPAs, returningwindow.location.href
is sufficient.
- Must return a fully qualified URL (starting with
Code example for the npm package
import { productFruits } from 'product-fruits';
productFruits.init(
'<<workspacecode>>',
'<<languagecode>>',
{ username: '<<replace>>' },
{
customNavigation: {
use: true, // Enables custom routing
navigate: (url) => {
// Handle navigation using your custom router
if (/^https?:\/\//.test(url)) {
window.location.href;
} else {
// Use your app's router for internal URLs
yourCustomRouter.navigate(url);
}
},
onGet() {
// Return the current URL (must start with https://)
return window.location.href;
// Example: 'https://example.com/current-route'
},
}
}
);
Code example for the React component
<ProductFruits
language='<<languagecode>>'
workspaceCode='<<workspacecode>>'
user={{ username: '<<replace>>' }}
config={{
customNavigation: {
use: true, // Enables custom routing
navigate: (url) => {
if (/^https?:\/\//.test(url)) {
// Optionally, open external URLs in a new tab
window.open(url, "_blank", "noopener,noreferrer");
} else {
yourRouter.navigate(url);
}
},
onGet() {
return window.location.href;
// Example: 'https://example.com/current-route'
},
}
}}
/>
Additional implementation considerations
Depending on your application's routing setup, you might need a bit more tailored approach.
For example, if you're using useNavigate
from react-router-dom
, you will need to ensure that your implementation also distinguishes between:
- Internal URLs β Handled by the appβs routing system.
- External URLs β Opened via
window.location.href
orwindow.open()
as appropriate. - New tab behavior β Ensuring that external links or specific URLs open in a new tab when required.
For example, a more complete implementation may look like this:
(location, openInNewTab) => {
if (/^https?:\/\//.test(location)) {
openInNewTab
? window.open(location, "_blank", "noopener,noreferrer")
: (window.location.href = location);
} else {
openInNewTab
? window.open(location, "_blank")
: navigate(location);
}
}
or
(url, openInNewTab) => {
if (openInNewTab) {
window.open(url, "_blank", "noopener,noreferrer");
} else {
window.location.href = url;
}
}
Special use cases
For Shopify apps or embedded iframes that manage navigation internally (without updating the browser's URL), you can also use a custom string identifier instead of a real URL with the custom routing approach.
For instance, you might define a string as an identifier in the URL template of tour cards. In your onGet
callback, simply return this identifier - making sure to also include the https://
prefix.
Please remember, the exact implementation may vary based on your application's requirements, but these examples should provide a solid starting point.
Before deploying, please thoroughly test your custom routing in both development and production environments to ensure functional navigation across your application.