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, returning window.location.href is sufficient.

 

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 or window.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.

Was this article helpful?