This article is translated from french, namely « Le blues du Web Share », in a series describing the development of the cpu-audio.js webcomponent.
Excuse my French
as we say in… French.
Today, I talk about what lies behind the button.
Here is my player, in its last development version. You can ⇓ jump ⇓ to ⇓ the ⇓ next ⇓ chapter ⇓
Yes, I know, I’m talking in French and this show is 5 years old, but I’m not sure to be a better radio host today. Yes, the interface is in French here, because my blog usually gets contents in French. It may be started in English.
The switch
This button (on the right of the main interface) will switch it to a share one. It is possible to hide this button and so denying access to the share interface via hide="actions"
attribute. It may be useful, by example when your website already have a share system.
Once the button clicked, you get some possible actions, on the whole width of the main interface of the web component :
This panel has some different actions as direct downloading the media file (according to which codec can be read by the browser, as we still get some old guns as Safari) and also share the sound via e-mail, twitter or facebook to relatives, sending them the canonical URL of the sound’s page. Due to limitations on those social networks, only e-mail gets a working media-fragment starting the play at the exact moment you were listening.
From left to right :
- a copy of the cover, going back to the main interface,
- share on Twitter (vanilla link),
- share on Facebook (vanilla link),
- share by e-mail (
mailto:
link), - download the media (according to which codec can be read),
- cancel, going back to the main interface.
As my web component is in liquid design and mobile first, the interface is simplified on small width : cover and text labels are hidden.
Canonical URL
means that if you want to share the radio show on cpu.pm front page, as i’m only showing the last broadcasted episode, its audio tag will be removed after next one is broadcasted, so there is a better choice : providing the page of the episode. And please, don’t look like you don’t use this useful tag. Yes, even if, as I do, you don’t code a website optimized for desktops, and a .m
one for mobiles, because, you know, it’s a loss of time.
If the canonical URL is not the one where is hosted the player, the canonical=""
attribute will do the job.
The wish
We already have browsers with a share on social networks
menu on mobile platforms. I’ve explained in a 2014 post in French about why I put again share buttons on my blog. It was 5 years ago, and, even if the general interface of the browsers moved, this over useful interface is still here.
Cool. Except that your browser will take the title of the page, a title encumbered with unmeaningful elements as separation glyphs, name of the site before title of the page, in extenso description of old-school SEO with a bunch of keywords names verbs persons marks important etc… Up to the user to clean it up and rephrase it.
The witch
Here enter the good fairies of the web standards :
The W3C introduced navigator.share()
aka WebShare, a function standardizing how to do it and allowing to suggest a bit longer description.
This function has numerous wins :
- being standard (in theory, I’ll explain later) ;
- not forgetting a service used by your reader (instead of the facebook/twitter classical duo) ;
- use a native control of the host OS, really more useful on smartphones ;
- deep sending you to the share function in the native app ;
- not tracking the users as do social networks with rich buttons (this is a shared win with classical HTML links) ;
- not tracking the users by the hosting website, guessing which sharing service they use ;
- not encumbering the small screen of a smartphone with gazillions of services.
Calling it is damn simple.
I’m really delighted having a so lean and perfectly thought process, instead to construct an instance builder with parameters set by another class serving a specific object and call it via an event dispatcher.
♫ In a webpage, https://
served , on a user action (as ), cook * :
navigator.share({
'title': document.title,
'text': document.querySelector('meta[name="description"]').content,
'url': window.location.href
});
* in French, it sings as the Cake d'Amour song in the famous « Peau d'Âne » movie, directed by Jacques Demy. That’s what I call love
.
If you have a clean coded html page, your whole job is done. If it’s a piggy mess, you should start to not forget the <meta...
description tag.
By the way, you can share files with this standard’s level 2, and an API to test the share (navigator.canShare()
).
Pure genius !
The twist
Except :
- This API is not available on desktop computers (except Safari Mac) ;
- It is also not available on Chrome Desktop, even in
responsive
mode (by the way, not a real mobile emulation, and may induce you in error) ; - This API is as today only on iOS and Chrome Android ;
- On iOS, each native app should carry its own sharing list, so we had a lot of missing ones due to the lack of a system-wide registry. We have it finally with, guess what ? Experimental support of
navigator.share
! - It is still not possible of a online service accessed via a browser to be registered, as long Web Share Target API is nowhere implemented (and if it will be somewhere, we need to have it accepted by the user via a specific interface, to avoid spam attempts).
We have a very volatile scene of social networks, and the landing of decentralized hives, where inhabitants is supposed to easily migrate from an instance to another one. For 3 years Web Share is so under-esteemed and only usable on one platform is a real shame. I’m deeply convinced we have technical ability to build a WebExtension doing that job on desktop browsers.
I have some request to add, or being able to add, sharing option for a lambda website. Sure, I’d only put Facebook and Twitter, some people shamed me for forgetting Diaspora*, VKontakte, Mastodon, etc.social.random() in the action interface of my player. They are right.
Except the more you get in a limited place, smaller each button will be and all those services will be tight on the bench a wide as a smartphone. And, whatever we can do, there is no way to keep an exhaustive list of any available share services, even for specialized audience, for a real obvious point : New services appear each day.
Looking this image again, we note that a lot of those social
services that died during the last 5 years. And having so much begging puppies makes the whole page unreadable.
The tweet
Well, I can not declare those missing services in the webcomponent code, and create an API permitting the web-developer to add some ?
Ahem. No. Wrong idea.
Because a such function will induce other problems : charging the work to whom will include my webcomponent in his website, asking to have some javascript knowledge and read my API's documentation. I can hear you, noisy kids : even with a big RTFM, you won’t.
And I can bet that the web operator will forget some sharing services.
It also means giving to the integrator some parameters that may be harmful :
- describing a color, injecting it via the
style="background-color"
attribute ; - describing a monochromatic SVG logo, needed because of the color inversion on
:hover
and:focus
, and betting the image will be exactly matching my template constraints and is not having an embedded javascript ; - describing an URL canvas where to send for that sharing service, if a such URL exists.
Yes, I’m talking about you, social services with sharing systems that don’t support a simple link for that job. With the main motive to force your users using your mobile app full of tracking ads. You, nasty boys.
So what ?
I don't know what to tell.
Today, a feature detection replaces the facebook/twitter/e-mail buttons by a unique button, launching the navigator.share()
function. You can see it only on Chrome Android and Safari.
And later, yes, build a polyfill WebExtension may be a great idea (in a more generic and without jQuery way, compared to web-share-api by C. Zuber). As long as sharing services will collaborate without pollute it with analytics
and other ad-tracking.
For me, the best looking interface to add a share service in my browser is to re-use what already exists in Firefox to add a search engine. Because it's a lean interface, explicit one, standard-based and most of the work is already done there.
It’s up to you to build it, now. IMHO, this is not a over-difficult job to complete, and will be still a future-proof solution instead of any old AddThis script.
You can also support initiatives to add WebShare into :
Again, it was a long post talking about code, standard, implementations, but, for me, it worth it because this issue is not limited to my cpu-audio.js.
My next post in this series will be in French and talks about CSS, standards and implementations for some… strange colors.
May be it’s a frightening title, may be related to a horror story, so I have to say the killing sentence :
I’ll be back… soon !
une réaction
1 De Da Scritch - 27/06/2019, 11:14
Creating a polyfill in webextension is a bit complicated, as there is only obsolete ways to add methods into Navigator() https://developer.mozilla.org/en-US...