🤗 What is the Web Share API? #
In this post, we see how you can add Svelte share buttons to your Svelte-based app. We will follow a roll-your-own approach here, using inbuilt browser APIs, rather than adding extra packages or dependencies. We will work in SvelteKit though our Svelte components can just as easily be used in Slinkity or Astro Svelte apps.
We add buttons, to a blog starter, which let site visitors share blog posts with their friends and followers on WhatsApp, Telegram and Twitter as well as Facebook. That functionality works in any browser, relying on just JavaScript. As well as that, we make use of the relatively new Web Share API. On the visitor’s mobile; this will bring up a menu, making it easy to share your site on any suitable apps they have installed. We are going for a progressive enhancement approach. This means mobile (and Safari on desktop) will show the Web Share API button, while browsers yet to support it will show our share buttons instead.
🧱 What we’re Building #
I mentioned we are working in SvelteKit using the MDsveX blog starter. If Astro is your preferred tool for building Svelte sites, start with the Astro Svelte Markdown starter instead. Of course, if you have an existing Svelte app, you can create a feature branch and add this functionality there. Anyway, to start, let’s clone a repo:
With that done, we will start by adding the fallback share button functionality. We will run through adding Twitter in detail, then sketch over adding other networks. If you want to add a popular network not mentioned, drop a comment below, and I will see what I can do. Equally, feel free to submit a pull request to the repo if you code up support for a well-known network, not already implemented.
🧩 Initial Share Button Component #
To get the ball rolling, let’s create a src/lib/components/ShareButtons
folder and inside it add an index.svelte
file. This file will ultimately
contain the logic for the Web Share progressive enhancement, as well as the fallbacks. Progressive enhancement expresses a similar sentiment to graceful degradation. The idea is, we want to support
a new feature which does not currently enjoy wide support. We have a baseline which supports all
(or most) devices, then the progressive enhancement offers the new feature, but only where the
user device supports it.
To get going, paste this code into the new file:
Here is some optional styling which you can paste at the end of the file:
src/lib/components/ShareButtons/index.svelte
— click to expand code.
This will not work yet — we need to create the Twitter share button component. Nonetheless,
let’s add the ShareButton
component to our blog post template
now:
With that basic wiring up done, we will next create the Twitter share button component. The other components work similarly, though the Twitter API supports the most customization, so it provides a good starting point.
🐦 Twitter Share Button Component #
This button will be part of the fallback; as such, we will not show it on devices which support the Web Share API. Currently, on MacOS, Safari does support the API, so test this part in Firefox and Chrome. The Twitter code, together with the other share button components, are based off the nygardk/react-share GitHub repo by Klaus Nygård.
In line 2
we import an Iconify Twitter icon already used in the project.
It is fairly easy to add icons from dozens of libraries using Iconify. In fact, this post is a follow-up
to an earlier post which tells you exactly how to gain access to over 100,000 SVG icons using a
single package. So jump back there when you want to see how to add icons to your own project.
The Twitter API has most bells and whistles: you can include hashtags, quotes and related accounts as well as a via Twitter account. I have added
some comments in the code to explain how to use these. Here, we’ll just focus on adding the text
(title
prop) and URL.
Twitter Customizations #
Lines 14
– 21
(above)
build up the query parameters for the URL which we need to send to Twitter to share the post. Because
this is a URL, some characters are not allowed, and we have to encode them. In line 25
, we make use of encodeURIComponent
to URL encode the keys and parameters for us.
The handleClick
code in lines 30
– 51
brings up a new window on Twitter’s
site which lets the visitor log in (if they are not already logged in) and share. The sizes are sensible
defaults which work on different sized devices, so you will probably not need to adjust these.
The other components will be similar, though with differing baseUrl
(see line 13
). For improved accessibility, include some screen
reader text on all buttons (as in line 55
). This will not be
visible, though screen readers will announce it, helping screen reader users know what the button
does.
🔘 Other Network Buttons #
We will skim over the other networks now, in fact, we will only point out details which are different. Then in the following section we will add them into the principal component and also wire up the Web Share API.
Facebook #
src/lib/components/ShareButtons/Facebook.svelte
— click to expand code.
Telegram #
src/lib/components/ShareButtons/Telegram.svelte
— click to expand code.
WhatsApp #
src/lib/components/ShareButtons/Whatsapp.svelte
— click to expand code.
There is not already a WhatsApp icon in the starter. Add this code, or create your own using your preferred icon set:
src/lib/components/Icons/Whatsapp.svelte
— click to expand code.
Also for WhatsApp, there are different API URLs depending on whether the visitor is using a mobile device or not. We make use of a utility function to check the type of device the user has. Create this file if you added the WhatsApp share button code above to your app:
🔨 Pulling it all Together #
We are going back to src/lib/components/ShareButtons/index.svelte
now
to tie the new buttons in. Feel free to omit any networks you will not need on your app here.
I think it will be clear what we are doing here, but let me know if I have forgotten to explain something!
🕸 Web Share API #
The final missing piece is the Web Share button. We will add a webShareAPISupported
boolean variable with a reactive declaration . This requires access to the browser navigator
object, so will not
work when the code is running server-side. SvelteKit provides the browser
variable defined in $app/env
which we make use of here. If you are
working in Astro, check for ssr
using this snippet:
Remember when browser
in the SvelteKit code is true
, ssr
will be false (and vice verse).
Anyway, let’s update the file:
In line 17
we declare the handleWebShare
function as reactive, using the dollar syntax. This will let the interface update if, in line 26
, the function sets webShareAPISuported
to false
.
What have we got here? #
In lines 35
– 41
, we have a guard so if webShareAPISupported
is false
, the user will see the share buttons we previously defined. On the other hand, if it is true
, the user sees the share button, which we will add in a moment.
When the use clicks or taps the share button, the handleWebShare
function
is invoked. This is asynchronous, so it is best practice to include try
/catch
blocks. If for some reason, the share fails, there is no issue!
Remember, we have our fallback, so just show the share buttons for the networks we added initially.
Lines 20
– 24
have
the core Web Share code.
Sharing via the API #
The Web Share API lets users share links, text, and files . We focus on sharing text and links here. To share a file, just add an extra files
field to the share object. We share both a link and some related text. You can opt to share either
one of these on its own and drop the other (some browsers do not yet support text, though). You see
that the API is fairly simple and there is not much more left to explain… the browsers do all
the heavy lifting! The final thing worth a mention is the check for support in line 15
. To check the latest browser support, see MDN Web Share API docs .
Share Icon #
Before we can test, we need to put the missing share icon into the project (feel free to swap this out, using your preferred collection):
🗳 Poll #
💯 Svelte Share Buttons: Test #
You should now be able to see the share buttons if you open any of the blog posts in a browser. To test on desktop, at the time of writing the WebShare API was not supported on Firefox and Chrome, so these are good for testing the fallback buttons. Safari on desktop does support the Web Share API, so is fantastic for testing that button. Also, try deploying your app to a staging environment to test a few mobile browsers.
🙌🏽 Svelte Share Buttons: Wrapup #
In this post we looked at:
- how to add share buttons to a Svelte app with progressive enhancement,
- using the Web Share API to share from a Svelte app,
- adding fallback share icons with Iconify.
I do hope there is at least one thing in this article which you can use in your work or a side project. Also, let me know if you feel more explanation of the config is needed.
This post came from a request in a comment on another post, so do drop a comment below if there is something else you would like to see a video or post on.
You can see the full SvelteKit code for this project on the Rodney Lab Git Hub repo . If you run into any issues, you can drop a comment below as well as reach out for a chat on Element . Also, Twitter @mention if you have suggestions for improvements or questions.
🏁 Svelte Share Buttons: Summary #
What is the Web Share API? #
- The Web Share API offers a convenient way for web developers to allow site visitors to share text, URLs, and files. The API needs to be invoked via a user action, such a tapping a button. Once invoked, supporting browsers show a native dialogue allowing users to share using apps installed on their device. The developer needs no prior knowledge of which apps are available on the user device. The user experience is ideal, allowing them to share content with friends, family, and followers using their favourite apps and social networks.
Which browsers currently support the Web Share API? #
- The Web Share API is supported on some, but not all browsers. Mobile browsers tend to have more favourable support. Safari on iOS and Chrome, Firefox and Opera on Android all support it. On top, Safari and Opera offer full desktop support, while Chrome and Edge have partial support. That’s for sharing URLs. Firefox for Android does not support file sharing via the Web Share API at the time of writing, and only Safari offers full desktop support.
How can you add the Web Share API with Progressive Enhancement? #
- To provide the best overall experience for all users, it is worth adding JavaScript based share buttons (without use of the Web Share API) as a base case. These buttons need to make use of the social networks’ own APIs. To offer an enhanced experience to users with devices which support the API, add a check for support and only show the corresponding share button where it is supported. While a single share button may suffice when the Web Share API is supported, buttons for multiple popular networks invoking that network’s own API are needed in the fallback.
🙏🏽 Feedback #
If you have found this video useful, see links below for further related content on this site. I do hope you learned one new thing from the video. Let me know if there are any ways I can improve on it. I hope you will use the code or starter in your own projects. Be sure to share your work on Twitter, giving me a mention, so I can see what you did. Finally, be sure to let me know ideas for other short videos you would like to see. Read on to find ways to get in touch, further below. If you have found this post useful, even though you can only afford even a tiny contribution, please consider supporting me through Buy me a Coffee.
Just dropped a new post taking you through how to roll-your-own sharing in your ❤️ Svelte app with Web Share API support as a progressive enhancement.
— Rodney (@askRodney) April 8, 2022
Includes fallbacks for the Facebook, Telegram, Twitter & WhatsApp share APIs.
Hope you find it useful!
https://t.co/5eZGjznGoB
Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via @askRodney on Twitter and also askRodney on Telegram . Also, see further ways to get in touch with Rodney Lab. I post regularly on SvelteKit as well as Search Engine Optimization among other topics. Also, subscribe to the newsletter to keep up-to-date with our latest projects.