Building a low-code, opinionated approach to plug & play login
It feels so long ago that Magic unveiled its first auth solution in April 2020. JAMstack was having a moment, and so were NFTs. The world had just begun to reckon with shutdowns and social distancing. A surge in remote work showed us that online identity was overdue for a refactor. Centralized infrastructures were being challenged everywhere.
Back then, all it took was one line of code to implement Magic.
We used to hear lots of positive feedback about our whole developer experience. Those docs, you know? So clean.
A year since, the world of web development is again at a threshold. We’re inundated with feedback from users that want a multitude of sign-in options. They want to feel secure, they want to own their data. They desire convenience and seamlessness. Providing an auth experience that serves every user, no matter their technical acumen or accessibility needs, is a costly undertaking for app creators. That’s because building a Magic implementation never really was just one line-of-code. You still have to create buttons, composed into forms, connected to a server. Model user accounts, measure conversion rates, but wait… did I
aria-label that button right? Hold on, we need a combobox? Now add social logins to the mix: what the heck is OAuth? Or WebAuthn? This login page is turning into infinite story points!
As we added more and more choices for sign-in, we heard feedback that Magic was harder to use, especially for no-code builders. So, what happened? And why should auth — something that every app needs — be so difficult to build and maintain? That’s a question that’s been bugging me for some time now. I lead the engineering team for developer experience at Magic, so we aimed to set a new standard to help our customers build auth more quickly, more securely, more accessibly, and more user friendly-y.
The aha moment came from the simple realization that most modern auth flows follow a discrete pattern: authorization and callback. You prompt a user to authorize themselves, traditionally with an email + password. Or, a more modern (and more secure) approach would use social logins, or Magic’s own passwordless email/SMS flows. Once a user has submitted their proof-of-identity (“authorization”), the app has to then verify this information (“callback”). In the case of social logins, this requires checking a one-time code built around some fancy, math-y cryptographic stuff. Or, using Magic’s passwordless SDKs, you just call
getRedirectResult for social logins and
loginWithCredential for email/SMS. Building auth for the web essentially boils down to two big function calls. Noticing this, however, presents an opportunity to do what we engineers love to do best: abstract!
But we weren’t going to make just any abstraction.
We want a new paradigm that speaks to the power of web development today and uses web primitives in such a way that the solution can slot into just about any tech stack.
We’re especially excited about no-code and low-code platforms like Webflow and Bubble, so we made it a priority to support those tools as natively as possible.
Today, we’re introducing a new way to implement Magic auth for the web: Magic Login Form.
We think it delivers on the promise of Magic as the easiest, most flexible, and most extensible auth solution available. That’s because we want your frontend implementation to be as simple as copy & paste.
Everything you need to start securely authenticating your users with any of Magic’s sign-in methods is two <script> tags away:
That’s all it takes to connect your app to Magic’s entire suite of auth features. You get a beautiful, accessible login screen with UI best-practices built-in — we’ll even remember which auth method users previously signed-in with. And better yet, your implementation is future-proof and automatically updates with Magic’s service. So, when Magic adds support for your favorite social login provider, you don’t need to deploy an update. Your users will see the latest changes automatically. All of this happens inside of an
<iframe> hosted on your domain, so users aren't left questioning what service they're interacting with, reducing the risk of phishing.
An example of a fully-branded Magic Login Form
At Magic, we think developer experience is user experience.
So we’re trying to remove as many barriers between you and your creativity as possible. With Login Form, you can stop worrying about auth and start focusing on what matters to your users and your business. Though it’s still not quite “one line of code” for everything auth, it’s a hell of a lot closer than we’ve seen anywhere else, and we’re excited about its potential to improve the auth experience for everyone on the web, long into the future.
At Magic, we promote a culture of creative experimentation, and we put this into practice during bi-weekly “demo days.” Everyone on the team has an opportunity to share something they’re working on — whether it’s related to a milestone project, or just a blossoming idea. Some of our best features sparked this way, usually based on pure intuition and user empathy. This takes a lot of introspection as a team. If we’re knowledgable of ourselves, it tends to manifest in great products for our users. So, demo day is also an opportunity for us to invest in each other.
When Login Form made its first appearance at demo day — unplanned and off-the-cuff — it looked like this:
The inspiration for that demo had simmered for a while. When we talked about this “big idea,” to make auth simple and clean and future-proof, it was sandwiched between phrases like “pie-in-the-sky” and “someday…” But, to produce that working proof-of-concept was a matter of hours (it helps, of course, that we already had a universe in which to bake our apple pie).
Demo day was a hit, but that’s only where the real work began.
For the developer experience team, Login Form meant so much more than a pre-packaged UI. It represented a whole new, opinionated implementation approach. Building a login page is pretty easy to “get”, even if you’re not an engineer. We’ve seen a thousand login pages before. But we still had to explain this implementation approach in a way that our product designers and marketing extraordinaries could relate to — we needed to help them tell a story. So, we went back to the drawing board.
Snapshots from the UI design process
It didn’t take long to find consensus on a UX pattern. Again, it’s a login page (a damn good login page). We started with a few design goals:
- Login Form should be adaptive to a developer’s Magic Dashboard settings, creating a seamless development experience. If you add some Google creds to your Magic account, then Login Form should instantly reflect that.
- Logging in should be quick, easy, and frictionless — users should never feel lost in sea of sign-in options. So, we want to remember what sign-in method a user has previously used for an app, then we can focus them on the right form automatically.
- Good design is inclusive design. Our entire login experience should reflect UI best practices and accessibility standards, above and beyond simple compliance.
- The design should be extensible. While we’re super proud of our initial release, we’re already thinking about ways to make Magic Login Form even better. Simplicity and flexibility help ensure we’ve got room to grow moving forward.
Magic Login Form represents a new onboarding experience for end-users, so we wanted to revamp our own onboarding experience for developers to match. Learning about auth can quickly derail any developer’s good day. Striking the balance between good UX and good security can just boggle the mind. Even building on top of a solution like Magic can quickly spiral into a thousand-thousand esoteric questions. UX tends to be the last box on the auth checklist. So, how do we show-off the “easy button”? We started by looking at our own sign-up experience on Magic Dashboard.
After you’ve completed our passwordless email flow for the first time, you see a screen like this:
When we created
npx make-magic, we sought to speed-up development of new projects using Magic. When we added this screen to our sign-up flow, however, we saw a mixed response. Some, especially those from a JAMstack background, were happy to see familiar tooling options. Others were unsure about what
npx make-magic was doing in their system, and why they were being asked to start there. One developer was confused upon seeing
npx, thinking that Magic worked exclusively for the NodeJS ecosystem—an impression we wanted to correct. The easiest decision for us was to strike this page from our sign-up flow completely.
We replaced this piece of the onboarding puzzle with a new Login Form settings page. From here, developers can access an interactive preview of their customized form. We also introduced a new featured card to Magic Dashboard’s home page, surfacing this new implementation approach with a beautiful, eye-catching design.
Getting started with Magic Login Form is super easy. Log into your Magic Dashboard account and go to Login Form. Try a demo for your very own plug & play login page. You’ll also see a link to download a working implementation using your actual API keys!
We’ve also written some documentation to help you build a plug & play login experience from the ground up. And, of course, we have added a template to our CLI scaffolding tool to generate a working implementation in under a minute. Simply run the following command in your preferred shell:
npx make-magic --template plug-and-play
We hope you enjoyed this peek behind-the-curtain of the all-new Magic Login Form (fun fact: our internal code name was “Auth-in-a-box”). By the way, it’s totally free to try. If you’re interested in getting more involved, join the Magic Discord server, where you can provide feedback or connect with a vibrant community of developers.
And one more thing: we’re hiring!