Share Controls Web Component

I built a Web Component that adds native copy to clipboard and sharing controls to a web page. The original idea was based on this excellent blog post by the folks at Set Studio. In this post I don't really want to go into the technical details of how it's built, but more of the conceptual approach and potential alternative ways to think about building progressively-enhanced Web Components.

Initial implementation and design

I've built the first version of this out and am currently using it on my recipe site, recipes.levimcg.com. It works pretty well for my purposes, but I'm thinking about how it might be re-written or improved for more general-purpose use. It currently works like this:

<share-controls url="https://levimcg.com" share-text="Share this!">
    <p>Place fallback content here. For example a simple URL.<p>
</share-controls>

Once the page is loaded and JavaScript is available, the <share-controls> element will replace the fallback content with JS-capable buttons that use the native clipboard and share APIs where browser support is available.1

This is what it looks like if JS is not available.

The share section of a recipe with a URL visible

This is after JS is available.

A "copy" and a "share" button at the end of an article

The HTML looks like this once it's rendered.

<share-controls url="https://levimcg.com" share-text="Share this!">
    <div class="sc-wrapper">
        <button class="sc-copy-button">Copy</button>
        <button class="sc-share-button">Share this!</button>
    </div>
</share-controls>

Attributes

This is how it's in its most simple form, but there are also a handful of attributes that can be used to customize the rendered button controls output. All of these attributes have default fallbacks.

Attribute Description
url A string that is coppied to the clipboard and/or used by the native share API. Defaults to the current page's URL
copy-button A string that is used for the copy button text. Defaults to "Copy"
share-text A string that is use as the message by the native web share API. Defaults to the current page title
share-button A string that is used for the share button text. Defaults to "Share"

Design Alternatives

I do wonder if there might be better ways to handle this kind of component than fully rendering the button controls on page load with JavaScript. I've started to ask myself, "what would HTML do?" in this case. For example, could my component just accept button elements as children and progressively enhance those with share and copy/paste functionality?

<share-controls url="mywebsite.com" copy="copy-button" share="share-button">
    <button id="copy-button" hidden>Copy</button>
    <button id="share-button" hidden>Share</button>
</share-controls>

Pros of this approach

  • This would eliminate the need for three of the four attributes that are currently need to offer customization.
  • The actual controls markup can be customized however needed and server-rendered.
  • This would make it more extensible if more sharing capabilities or APIs are added (or never fully implemented ) in browsers. Or maybe even implementing share via email with mailto links.

Cons of this approach

  • In order to get the fully progressive enhancement benefits, the author would have to remember to add hidden attributes to the buttons so that if JS was not available, the controls would not be available to use.
  • Associating the share and copy functionality with the child button elements becomes problematic without re-introducing additional attributes that author would need to know and understand. For example, using id on the buttons to associate those with custom copy and share attributes on the <share-controls> element

Wrapping up

I guess for now I'll leave things as is and maybe come back to it later with a fresh perspective. If you want to have a look I put the source and some demos up on GitHub. I may or may not publish it to npm if it seems like it could become something useful.

I love that this concept of HTML Web Components is having a moment right now. I've built a couple of Web Components in this model in the past, but never really knew what to call them. I think HTML Web Components is a great term and has already done so much to improve the general awareness of Web Components. As Chris mentioned in their post, this approach is quickly becoming my preferred way of writing encapsulated JavaScript functionality with progressive enhancement.


  1. Currently, only Safari and Edge support the native share API