How to customize the native navigator.share() function?

581 Views Asked by At

I'm trying to modify the url parameter of the navigator.share() function so when some share the page using the mobile browser's share option, I'm able to customize the URL.

Why I need this? I have WordPress website www.abcwebsite.com that has a dynamic cloning system with subdomain with a single backend site (not multisite network, we use a plugin to manage identify the subdomain and modify certain texts). Ex: clonea.abcwebsite.com is an exact copy of the main site except for some text elements. For SEO purposes, we want to disable the clone sites from being indexed but want to capitalize on the traffic that the clone sites get.

The initial step I did was change the canonical meta tag to point to the root domain. Later I identified that navigator.share() by default uses the canonical link and if not found then falls back to location.href. When someone shared the clone page using browser's share option, it shares the main site link instead of the cloned link. Not a feasible solution.

Next step was to completely remove the meta tag for canonical and move it to http headers. It solved our problems with Google. But recently I have noticed that the canonical in the header doesn't work in Bing and so all the thousands of our clone sites are now appearing in Bing results.

I believe the only way to go about it add the canonical meta tag and point it to main website, and when navigator.share() is initiated by browser's share option, pass the clone site url into the share.

This is what I have tried and I get Maximum call stack size exceeded error--

var defaultNavigator = navigator;
function shareThis($args){ return defaultNavigator.share($args); }
navigator.share = function($args){ return shareThis($args); };
navigator.share({ url: "https://www.abcwebsite.com", text: "Test", title: document.title });

and with this I get Failed to execute 'share' on 'Navigator': Illegal invocation

var defaultShare = navigator.share;
function shareThis($args){ return defaultShare($args); }
navigator.share = function($args){ return shareThis($args); };
navigator.share({ url: "https://www.abcwebsite.com", text: "Test", title: document.title });
2

There are 2 best solutions below

1
LickingFilth On

I think navigator.share method is a native browser API and expects to be called with the navigator object as its context. When we wrap it in another fn the context (the this) changes and it leads to the error: "Illegal invocation".

I would override navigator.share like this:

// Storing original share method
const originalShare = navigator.share;

// Overriding navigator.share method
navigator.share = function(data) {
  // Modify the data object
  data.url = "https://www.cat-bounce.com";

  // Calling original share method with the modified data
  return originalShare.call(navigator, data);
};

// Use navigator.share as normal but with modifications
navigator.share({
  title: 'My Title',
  text: 'My Text',
  url: 'https://www.clonesite.com'  // This is replaced by override
}).then(() => {
  console.log('Successful share');
}).catch((error) => {
  console.log('Error sharing:', error);
});
1
EvrCopy On

The previous answer should work for you, but you can also try to explicitly bind the function.

const originalShare = navigator.share.bind(navigator);

navigator.share = (data) => {
    /* your code here */
    originalShare(data);
};

Two more ideas:

  1. Make note that the Web Share API is not supported in all browsers, so that might explain why it didn't work for you on mobile.
  2. When are you overriding this function? It might be that it gets overriden too late (after the mobile client invokes the share).