Browsers, JSON, and FormData
Jeremy wrote about what a boon the new view transitions API could be for the web:
Allow me to try and explain.
What do I mean by this?
In this way, browsers communicate and render GUIs at their most basic level in HTML via HTTP.
<a>element clicked? That’s an HTTP GET for another resource whose response, if HTML, will render something new in the browser.
<form>element submitted? That’s an HTTP GET or POST with user-supplied data for another resource whose response, if HTML, will render something new in the browser.
application/json, but as
To put it bluntly: there’s no progressive enhancement if all your APIs only accept JSON payloads directly from the browser.
A Simple Example
Imagine I have a simple static site with a call to action to sign up for my newsletter. I drop a static HTML file on a web server with some
<form> markup which the browser will use to render a GUI where the user can enter their information.
<form> <label for="email"> Sign Up For My Newsletter </label> <input type="email" id="email" /> <button type="submit"> Sign Up </button> </form>
Now I need a server somewhere to collect this information and store it.
So many third-party services have APIs you can integrate with and guess what? They probably speak JSON exclusively. But browsers don’t send user-entered data as JSON by default, so what’s one to do? You can:
- Create a URL that accepts the structure of a default browser POST request (
<form method="post" action="/my-url">).
<script>tag on the page somewhere that handles the logic to submit a JSON payload to whatever service will store this information for you.
Once you need to collect one simple piece of data from a user on a “static” web page — like
<input type="email" /> — you either 1) now need to control a server that accepts
Quick plug: this is where a framework like Remix which supports progressive enhancement really shines. Remix makes it incredibly easy to support
<form> submissions as the browser default
application/json type. Read the docs for more info.
Try to implement that using Next.js…and I can't think…how. You can post to "api endpoint", but that'll return JSON…I'm sure there's a work around, but the point is that it has to be worked around, intentionally.
- To their credit, the folks at Netlify support
e.preventDefault()on the form submission and the sending of a JSON payload instead. Third-party JSON APIs are so often the recipients of user data entered directly in the browser. If anybody out there is using Netlify’s
<form netlify>feature to support progressive enhancement, hit me up with the details on how you’re doing it! ↩
- AFAIK, there’s no way (currently) to declaratively describe a form in HTML that makes a request with JSON (though there appears to have been an effort to do so at one point). ↩