<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>solidjs on SpartanAuth Blog</title>
    <link>https://blog.spartanauth.com/tags/solidjs/</link>
    <description>SpartanAuth Blog (solidjs)</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Thu, 26 May 2022 23:24:13 -0600</lastBuildDate>
    
    <atom:link href="https://blog.spartanauth.com/tags/solidjs/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Login Widget</title>
      <link>https://blog.spartanauth.com/posts/login-widget/</link>
      <pubDate>Thu, 26 May 2022 23:24:13 -0600</pubDate>
      
      <guid>https://blog.spartanauth.com/posts/login-widget/</guid>
      <description>&lt;p&gt;When I started SpartanAuth, I had a simple obsession: authentication should be easy to do &lt;em&gt;correctly&lt;/em&gt;. Complexity is where security bugs and abandoned sign-ins both hide. Today I want to talk about the login widget.&lt;/p&gt;
&lt;h2 id=&#34;why-build-a-widget&#34; &gt;Why build a widget?
&lt;span&gt;
    &lt;a href=&#34;#why-build-a-widget&#34;&gt;
        &lt;svg viewBox=&#34;0 0 28 23&#34; height=&#34;100%&#34; width=&#34;19&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34; fill=&#34;none&#34; stroke-linecap=&#34;round&#34; stroke-miterlimit=&#34;10&#34; stroke-width=&#34;2&#34;/&gt;&lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34; fill=&#34;none&#34; stroke-linecap=&#34;round&#34; stroke-miterlimit=&#34;10&#34; stroke-width=&#34;2&#34;/&gt;&lt;/svg&gt;
    &lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;TLDR: usability, branding, and making the secure path the easy path.&lt;/p&gt;
&lt;p&gt;Businesses lose real money when people cannot sign in. &amp;ldquo;About a third of online purchases are abandoned at checkout because consumers cannot remember their passwords,&amp;rdquo; from a study conducted jointly by MasterCard and the University of Oxford (&lt;a href=&#34;https://phys.org/news/2017-06-customers-passwords-business.html&#34;&gt;source&lt;/a&gt;).
That is a big reason I care about helping apps &lt;a href=&#34;https://blog.spartanauth.com/posts/cost-of-passwords/&#34;&gt;move away from relying on passwords&lt;/a&gt;.&lt;/p&gt;
&lt;figure class=&#34;stat-card&#34;&gt;
  &lt;div class=&#34;stat-card-value&#34;&gt;~⅓&lt;/div&gt;
  &lt;figcaption class=&#34;stat-card-label&#34;&gt;Of online purchases abandoned at checkout over forgotten passwords&lt;/figcaption&gt;&lt;div class=&#34;stat-card-source&#34;&gt;&lt;a href=&#34;https://phys.org/news/2017-06-customers-passwords-business.html&#34; rel=&#34;noopener&#34;&gt;MasterCard / University of Oxford&lt;/a&gt;&lt;/div&gt;&lt;/figure&gt;

&lt;p&gt;Replacing passwords with stronger authentication can be expensive, complicated, error-prone, and hard to use. SpartanAuth exposes an API so you can build your own login page — but I also wanted a complete path that is kind to both end users and the developers wiring it up.&lt;/p&gt;
&lt;p&gt;User experience matters. So does branding. A login screen is often the front door of a product; it should feel like &lt;em&gt;your&lt;/em&gt; app, not a generic detour.&lt;/p&gt;
&lt;p&gt;So I built a login widget with the factors SpartanAuth supports, configurable enough to match your look and feel.&lt;/p&gt;
&lt;h2 id=&#34;choosing-a-tech&#34; &gt;Choosing a tech
&lt;span&gt;
    &lt;a href=&#34;#choosing-a-tech&#34;&gt;
        &lt;svg viewBox=&#34;0 0 28 23&#34; height=&#34;100%&#34; width=&#34;19&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34; fill=&#34;none&#34; stroke-linecap=&#34;round&#34; stroke-miterlimit=&#34;10&#34; stroke-width=&#34;2&#34;/&gt;&lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34; fill=&#34;none&#34; stroke-linecap=&#34;round&#34; stroke-miterlimit=&#34;10&#34; stroke-width=&#34;2&#34;/&gt;&lt;/svg&gt;
    &lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;Shipping third-party UI into someone&amp;rsquo;s app is a trust exercise. I wanted the widget stack to be reliable, fast, and small. Frontend framework debates aside, the last decade of competition has been great for bundle size and performance — and I wanted those gains.&lt;/p&gt;
&lt;p&gt;I set three criteria. The technology had to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;be simple to implement in any web environment&lt;/li&gt;
&lt;li&gt;have a minimal bundle size when delivered to the end user&lt;/li&gt;
&lt;li&gt;be a leader in performance&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;stat-row&#34;&gt;

&lt;figure class=&#34;stat-card stat-card--compact&#34;&gt;
  &lt;div class=&#34;stat-card-value&#34;&gt;Simple&lt;/div&gt;
  &lt;figcaption class=&#34;stat-card-label&#34;&gt;Drop into any web environment&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure class=&#34;stat-card stat-card--compact&#34;&gt;
  &lt;div class=&#34;stat-card-value&#34;&gt;Small&lt;/div&gt;
  &lt;figcaption class=&#34;stat-card-label&#34;&gt;Minimal bundle for end users&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure class=&#34;stat-card stat-card--compact&#34;&gt;
  &lt;div class=&#34;stat-card-value&#34;&gt;Fast&lt;/div&gt;
  &lt;figcaption class=&#34;stat-card-label&#34;&gt;Performance as a first-class goal&lt;/figcaption&gt;&lt;/figure&gt;


&lt;/div&gt;

&lt;p&gt;My first prototype was in &lt;a href=&#34;https://vuejs.org/&#34;&gt;Vue&lt;/a&gt;. Reactive UI is lovely, and the prototype was decent — but Vue is not ideal when you are shipping a single custom element. They even say explicitly that &lt;a href=&#34;https://vuejs.org/guide/extras/web-components.html&#34;&gt;&amp;ldquo;it is not ideal to use Vue if you are shipping a single custom element&amp;rdquo;&lt;/a&gt;. So I kept looking.&lt;/p&gt;
&lt;p&gt;At the suggestion of my friend &lt;a href=&#34;https://www.linkedin.com/in/christophergbradshaw/&#34;&gt;Christopher Bradshaw&lt;/a&gt;, I found &lt;a href=&#34;https://www.solidjs.com/&#34;&gt;SolidJS&lt;/a&gt;. This &lt;a href=&#34;https://ryansolid.medium.com/javascript-ui-compilers-comparing-svelte-and-solid-cbcba2120cea&#34;&gt;blog post&lt;/a&gt; is still one of the clearest write-ups I have seen on compilers, bundle size, and performance. Reactive programming on top was icing.&lt;/p&gt;
&lt;p&gt;Solid checked the boxes: near-vanilla JS performance, a bias toward less client JS, TypeScript support, and a tiny final bundle. And yes — it could ship as something developers drop in easily.&lt;/p&gt;
&lt;p&gt;Solid has a library aimed at custom elements: &lt;a href=&#34;https://www.npmjs.com/package/solid-element&#34;&gt;Solid Element&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;results&#34; &gt;Results
&lt;span&gt;
    &lt;a href=&#34;#results&#34;&gt;
        &lt;svg viewBox=&#34;0 0 28 23&#34; height=&#34;100%&#34; width=&#34;19&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34; fill=&#34;none&#34; stroke-linecap=&#34;round&#34; stroke-miterlimit=&#34;10&#34; stroke-width=&#34;2&#34;/&gt;&lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34; fill=&#34;none&#34; stroke-linecap=&#34;round&#34; stroke-miterlimit=&#34;10&#34; stroke-width=&#34;2&#34;/&gt;&lt;/svg&gt;
    &lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;The early Solid prototype was promising. A custom login page could look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;script&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;module&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;crossorigin&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;src&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/assets/index.2157afe0.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;spartan-login&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;start-mode&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;webAuthn&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;locale&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;en&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;redirect&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/app.html&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;spartan-login&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;stat-row&#34;&gt;

&lt;figure class=&#34;stat-card stat-card--compact&#34;&gt;
  &lt;div class=&#34;stat-card-value&#34;&gt;2 lines&lt;/div&gt;
  &lt;figcaption class=&#34;stat-card-label&#34;&gt;To embed a full login experience&lt;/figcaption&gt;&lt;/figure&gt;

&lt;figure class=&#34;stat-card stat-card--compact&#34;&gt;
  &lt;div class=&#34;stat-card-value&#34;&gt;~17 KB&lt;/div&gt;
  &lt;figcaption class=&#34;stat-card-label&#34;&gt;Gzipped bundle in the early Solid prototype&lt;/figcaption&gt;&lt;/figure&gt;


&lt;/div&gt;

&lt;p&gt;Bundle size was already reasonable, with room to improve:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;index.668c492a.js            44.63 KiB / gzip: 16.70 KiB
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That build included i18n, and the multi-locale result looked like this:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://blog.spartanauth.com/img/widget-i18n.png&#34;/&gt;&lt;figcaption&gt;
            &lt;h4&gt;Four copies of the login widget each with a different language.&lt;/h4&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Customization started simple and powerful: pass CSS through a &lt;code&gt;styles&lt;/code&gt; attribute and it applies. More knobs can come later; full CSS control is already a lot.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://blog.spartanauth.com/img/widget-styled.png&#34;/&gt;&lt;figcaption&gt;
            &lt;h4&gt;Login widget with the button stylized to match with a background of trees.&lt;/h4&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&#34;why-the-widget-is-open-source&#34; &gt;Why the widget is open source
&lt;span&gt;
    &lt;a href=&#34;#why-the-widget-is-open-source&#34;&gt;
        &lt;svg viewBox=&#34;0 0 28 23&#34; height=&#34;100%&#34; width=&#34;19&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34; fill=&#34;none&#34; stroke-linecap=&#34;round&#34; stroke-miterlimit=&#34;10&#34; stroke-width=&#34;2&#34;/&gt;&lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34; fill=&#34;none&#34; stroke-linecap=&#34;round&#34; stroke-miterlimit=&#34;10&#34; stroke-width=&#34;2&#34;/&gt;&lt;/svg&gt;
    &lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;This matters to me: the &lt;strong&gt;login widget library is open source&lt;/strong&gt;. You should be able to inspect what you embed. SpartanAuth the service is a product I am building and running for real apps — including several of my own — but I want the client piece developers drop into a page to be transparent.&lt;/p&gt;
&lt;figure class=&#34;stat-card stat-card--compact&#34;&gt;
  &lt;div class=&#34;stat-card-value&#34;&gt;Open widget&lt;/div&gt;
  &lt;figcaption class=&#34;stat-card-label&#34;&gt;Inspect what you embed — the login library is open source&lt;/figcaption&gt;&lt;/figure&gt;

&lt;h2 id=&#34;next-steps&#34; &gt;Next steps
&lt;span&gt;
    &lt;a href=&#34;#next-steps&#34;&gt;
        &lt;svg viewBox=&#34;0 0 28 23&#34; height=&#34;100%&#34; width=&#34;19&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34; fill=&#34;none&#34; stroke-linecap=&#34;round&#34; stroke-miterlimit=&#34;10&#34; stroke-width=&#34;2&#34;/&gt;&lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34; fill=&#34;none&#34; stroke-linecap=&#34;round&#34; stroke-miterlimit=&#34;10&#34; stroke-width=&#34;2&#34;/&gt;&lt;/svg&gt;
    &lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;The widget began as a focused prototype and grows as the backend gains features. If you want to follow along, use the RSS feed or the newsletter below. And if you are building something that needs auth, I would love for you to try &lt;a href=&#34;https://www.spartanauth.com&#34;&gt;SpartanAuth&lt;/a&gt;.&lt;/p&gt;
&lt;aside class=&#34;waitlist-cta&#34; aria-label=&#34;SpartanAuth updates&#34;&gt;
  &lt;p class=&#34;waitlist-cta-kicker&#34;&gt;Stay in the loop&lt;/p&gt;
  &lt;p class=&#34;waitlist-cta-text&#34;&gt;
    Get occasional notes from me on authentication and SpartanAuth — plus early access as new things ship.
  &lt;/p&gt;
  &lt;p class=&#34;waitlist-cta-action&#34;&gt;
    &lt;a class=&#34;waitlist-cta-button&#34; href=&#34;https://lc.spartanauth.com/q/waitlist-sa/start&#34; rel=&#34;noopener&#34;&gt;Get updates&lt;/a&gt;
  &lt;/p&gt;
  &lt;p class=&#34;waitlist-cta-note&#34;&gt;Low volume. No spam. Unsubscribe anytime.&lt;/p&gt;
&lt;/aside&gt;</description>
    </item>
    
  </channel>
</rss>
