Insights
A minimal "Last used" login option indicator with Alpine.js
When you come back to Flare's login page, the sign-in option you used last time has a small "Last used" pill above it. Nothing dramatic, just a quiet nudge toward the option you've used before. I added it recently and was surprised how little code it took: around 25 lines of HTML and AlpineJS, most of which already existed to render the login page. No custom code for managing localstorage or cookies.
The whole thing is held together by Alpine's $persist plugin. It wraps a reactive variable so its value survives page reloads by mirroring it into localStorage. You declare it inside an x-data block and then forget about it. Reading and writing to it look identical to any other Alpine state variable.
<div x-data="{ count: $persist(0) }">
<button x-on:click="count++">count: <span x-text="count"></span></button>
</div>
My first pass at the indicator pill was the direct version. One persisted variable, bound to both the TailwindCSS ring class and the pill's visibility. Click a button, variable updates, everything re-renders.
<div x-data="{ last: $persist('').as('last-method') }">
<button
x-on:click="last = 'google'"
x-bind:class="{ 'ring': last === 'google' }"
>
Sign in with Google
<span x-show="last === 'google'">Last used</span>
</button>
</div>
You might've already caught the most glaring issue here: the moment you click Google, the pill immediately activates on the Google button. That's not wrong exactly, it's just not what you want, especially for an external login flow that hasn't been completed yet. The pill is supposed to say "here's what you used last time".
The fix is to split the variable in two. Keep $persist as the write target, but take a one-time copy into a plain Alpine variable on x-init. The bindings read from the copied variable, which was frozen the moment the page loaded.
<div x-data="{
recent: $persist('').as('last-method'),
displayed: '',
}"
x-init="displayed = recent">
<button
x-on:click="recent = 'google'"
x-bind:class="{ 'ring': displayed === 'google' }"
>
Sign in with Google
<span x-show="displayed === 'google'">Last used</span>
</button>
</div>
Now clicking "Sign in with Google" immediately updates localStorage (so it's the value you'll see next time) but it doesn't touch the displayed variable, so the pill stays where it was. On the next visit, x-init runs again, displayed gets the updated value, and the pill has moved.
The login page also has an email/password form below the social buttons, and I deliberately don't track it with a pill, because it feels like the defautl. But if they used to sign in with Google and then switched back to the email and password login flow, I don't want a stale pill on Google forever either. Thats why a single x-on:submit on the form clears the stored value.
<form x-on:submit="recent = ''" method="POST">
...
</form>
I like when a touch like this doesn't need a session, an endpoint, or a new column on users. The browser already has localStorage, Alpine already has $persist, and the whole thing just feels elegant like this.
Continue reading
Create richer issues from your errors
When Flare creates an issue on GitHub, GitLab or Linear, you can now pick the assignee and labels right away.
Ruben
One core, many clients: the new Flare JavaScript client architecture
We recently reshaped the Flare JavaScript client from a single browser library and a few thin framework specific packages into a small family of packages built on a shared, platform-agnostic core. This post explains why we did it, what the core package exposes, how the browser and Node SDKs are built on top of it, why the React, Vue, and Svelte packages sit one level higher, and how anyone can use the same core to write a Flare JS client for a platform we do not ship ourselves.
Dries
Subscribe to Backtrace, our quarterly Flare newsletter
No spam, just news & product updates