5

Below code works well on devices where web share API is supported and shows the native share dialog but throughs "Uncaught (in promise) DOMException: Share canceled" error where web share API is not supported and do not goes to the URL defined in href of the anchor tag.

<a href="https://example.com?utm_source=btn_share" class="btn-share" target="_blank">
    Share on Facebook
</a>


<script type="text/javascript">
    $(".btn-share").click(function(e){
        // Web Share API
        if (navigator.share){
            e.preventDefault();
            navigator.share({
                title: 'This is example website',
                url: 'https://example.com'
            });
        }
    });
</script>

Remove the error so that it should go to the URL defined in href of the anchor tag if web share API is not supported on the device.

DMP
  • 523
  • 4
  • 19

2 Answers2

3
  1. You need to catch the error as navigator.share() is a Promise,

  2. Promise returns "AbortError" If the user chose to cancel the share operation(mostly on mobile devices) or if there are no share targets available (it occurs mostly on desktop devices). So differentiating the "AbortError" on mobile devices and on desktop computer needs some extra mechanism. Reference: https://www.w3.org/TR/web-share/

The best solution to your problem at the moment is:

https://jsfiddle.net/g19but5o/2/

<a href="https://example.com" class="btn-share" target="_blank">
    Share on Facebook
</a>

$(".btn-share").click(function(clickEvent){
    var self = $(this);
    // Web Share API
    if (navigator.share){
        clickEvent.preventDefault();
        navigator.share({
                title: 'This is example website',
                url: 'https://example.com'
            })
            .then(function() {
                console.log('Successful share');
            })
            .catch(function(error) {
              console.log('Error sharing:', error);
              window.open($(self).attr('href'), '_blank');
            });
    }
});
Syed
  • 891
  • 2
  • 8
  • 29
1

Since navigator.share is a promise, I would just catch the error, set a prop on the link letting you know it errors, and then simulate another click.

https://jsfiddle.net/n672g4kr/

(Stackoverflow won't open a new window from a fiddle apperently)

$(".btn-share").click(function(e){
    // Web Share API
    if (navigator.share && !$(this).prop('error')){
        e.preventDefault();
        navigator.share({
            title: 'This is example website',
            url: 'https://example.com'
        }).catch(() => {
            $(this).prop('error', true);
            $(this).click();
        });
    } else {
        $(this).prop('error', false);
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href="https://example.com?utm_source=btn_share" class="btn-share" target="_blank">
    Share on Facebook
</a>
dave
  • 62,300
  • 5
  • 72
  • 93
  • Thank you dave for your time, there is an issue with it, it works fine on mobile devices on 1st click only on 2nd click it doesn't open native share dialog rather opens the page in new browser tab. – DMP Jun 30 '21 at 02:28
  • I noticed that above issue occurs if user cancels the native share dialog on mobile devices. – DMP Jun 30 '21 at 14:10
  • 1
    In that case just add `$(this).prop('error', false);` to the very end in an else block (updated example). This will make it so when they click, if it errors, it will open in a new window, but if they click again, it will still try to use `navigator.share` (and if it errors again will still open in a new window). Before once it errored it assumed it always would. – dave Jun 30 '21 at 17:07
  • @Syed - I'm assuming you mean the `navigator.share` API? That part *is* called in response to a user action, only if it errors do we "reclick" with the error prop set to true, which makes it bypass the `navigator.share` API call entirely and open it as a normal link. – dave Jul 02 '21 at 05:11
  • 1
    What ever the reason is but `$(this).click();` in your code is not working on desktop browses. – Syed Jul 02 '21 at 10:04
  • I'm on a desktop browser and it works just fine, but ok – dave Jul 02 '21 at 20:37