When should there be a declarative version of a JavaScript API?
Tags: html, markup, declarative, webshare
Published: 2022-03-14 08:27:48

---
title: When should there be a declarative version of a JavaScript API?
published: true
date: 2022-03-09 17:42:33 UTC
tags: html,markup,declarative,webshare
canonical_url: https://adactio.com/journal/18903
---

I feel like it’s high time I revived some interest in my proposal for [`button type="share"`](https://github.com/adactio/share-button-type/blob/gh-pages/explainer.md). Last I left it, I was [gathering use cases](https://github.com/adactio/share-button-type/blob/gh-pages/explainer.md) and they seem to suggest that the most common use case for the [Web Share API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_API) is sharing the URL of the current page.

If you want to catch up on the history of this proposal, here’s what I’ve previously written:

- [A declarative Web Share API](https://adactio.com/journal/17398)
- [A polyfill for button type=”share”](https://adactio.com/journal/17405)
- [The reason for a share button type](https://adactio.com/journal/17493)

Remember, my proposal isn’t to _replace_ the JavaScript API, it’s to _complement_ it with a declarative option. The declarative option doesn’t need to be as fully featured as the JavaScript API, but it should be able to cover the majority use case. I think this should hold true of most APIs.

A good example is the [Constraint Validation API](https://developer.mozilla.org/en-US/docs/Web/API/Constraint_validation). For the most common use cases, the `required` attribute and `input type`s like “email”, “url”, and “number” have you covered. If you need more power, reach for the JavaScript API.

A bad example is the [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API). The most common use case is getting the user’s current location. But there’s no `input type="geolocation"` (or `button type="geolocation"`). Your only choice is to use JavaScript. It feels heavy-handed.

I recently got an email from [Taylor Hunt](https://dev.to/tigt) who has come up with a good litmus test for JavaScript APIs that should have a complementary declarative option:

> I’ve been thinking about how a lot of recently-proposed APIs end up having to deal with what Chrome devrel’s been calling the “user gesture/activation budget”, and wondering if that’s a good indicator of when something should have been HTML in the first place.

I think he’s onto something here!

Think about any API that requires a user gesture. Often the documentation or demo literally shows you how to generate a button in JavaScript in order to add an event handler to it in order to use the API. Surely that’s an indication that a new `button type` could be minted?

The Web Share API is a classic example. You can’t invoke the API after an event like the page loading. You have to invoke the API after a user-initiated event like, oh, I don’t know …clicking on a button!

The [Fullscreen API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API) has the same restriction. You can’t make the browser go fullscreen unless you’re responding to user gesture, like a click. So why not have `button type="fullscreen"` in HTML to encapsulate that? And again, the fallback in non-supporting browsers is predictable—it behaves like a regular button—so this is trivial to polyfill. I should probably whip up a polyfill to demonstrate this.

I can’t find a list of all the JavaScript APIs that require a user gesture, but I know there’s more that I’m just not thinking of. I’d love to see if they’d all fit this pattern of being candidates for a new `button type` value.

The only potential flaw in this thinking is that some APIs that require a user gesture might also require a [secure context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts) (either being served over HTTPS or `localhost`). But as far as I know, HTML has never had the concept of features being restricted by context. An element is either supported or it isn’t.

That said, there is some prior art here. If you use `input type="password"` in a non-secure context—like a page being served over HTTP—the browser updates the interface to provide scary warnings. Perhaps browsers could do something similar for any new `button type`s that complement [secure-context JavaScript APIs](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts/features_restricted_to_secure_contexts).