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. Another use case for this advanced installation option is to allow for better compability with applicatons that don't have changing URLs.
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.