<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rod Vanderzee</title>
    <description>The latest articles on DEV Community by Rod Vanderzee (@rodezee).</description>
    <link>https://dev.to/rodezee</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3880891%2Faf7a03f1-716c-463a-8b80-c9fdef0c4dd6.png</url>
      <title>DEV Community: Rod Vanderzee</title>
      <link>https://dev.to/rodezee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rodezee"/>
    <language>en</language>
    <item>
      <title>Stop Routing, Start Switching, Alpine Turnout 🍦</title>
      <dc:creator>Rod Vanderzee</dc:creator>
      <pubDate>Wed, 15 Apr 2026 17:15:04 +0000</pubDate>
      <link>https://dev.to/rodezee/making-alpinejs-transitions-feel-creamy-with-alpine-turnout-1ep8</link>
      <guid>https://dev.to/rodezee/making-alpinejs-transitions-feel-creamy-with-alpine-turnout-1ep8</guid>
      <description>&lt;h2&gt;
  
  
  Stop Routing, Start Switching
&lt;/h2&gt;

&lt;p&gt;Most SPA routers are heavy, complex, and require you to define your entire site structure in a separate JavaScript file. Alpine Turnout takes a different approach.&lt;/p&gt;

&lt;p&gt;It treats your routes like a Switch.&lt;/p&gt;

&lt;p&gt;By using the &lt;code&gt;x-route&lt;/code&gt; directive, you tell Alpine exactly which elements should be active based on the current path. No config files, no heavy boilerplate—just reactive markup.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes it "Creamy"?
&lt;/h2&gt;

&lt;p&gt;The goal of Turnout was to make the transition between "Multi-Page" and "Single-Page" feel seamless.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The Global Interceptor: You don't need to change your &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tags. Turnout listens for clicks globally and handles the navigation state automatically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automatic Scope Injection: If your route is /user/:id, the :id is automatically available inside your Alpine component scope. No extra fetching or parsing required.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Persistent: Going to your other routes leaves input fields not empty handed but they remain just the way you left them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Smart Scroll Memory: When you "turn back," the plugin remembers exactly where you were scrolling. It’s fluid and organic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Built-in 404s: It even handles the "End of the line" for you if a user wanders off-track.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I believe a demo is worth a thousand lines of code. I built a dedicated playground to showcase exactly how these transitions feel:&lt;/p&gt;

&lt;p&gt;👉 Turnout Playground (Live Demo)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://turnout-playground.netlify.app" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40iuhlep020u9u6w3kb7.gif" alt="Turnout Playground" width="400" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;p&gt;Getting started is simple, just add this in the head of your HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"//unpkg.com/alpine-turnout"&lt;/span&gt; &lt;span class="na"&gt;defer&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"//unpkg.com/alpinejs"&lt;/span&gt; &lt;span class="na"&gt;defer&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, in your markup, do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;x-route=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;x-title=&lt;/span&gt;&lt;span class="s"&gt;"Home"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Welcome to the Station&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;x-route=&lt;/span&gt;&lt;span class="s"&gt;"/profile/:name"&lt;/span&gt; &lt;span class="na"&gt;x-title=&lt;/span&gt;&lt;span class="s"&gt;"User Profile"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Profile of &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;x-text=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(If you do not have &lt;code&gt;x-data&lt;/code&gt; declared yet, put it in body tag)&lt;/p&gt;

&lt;p&gt;Launch your site with &lt;code&gt;npx vite&lt;/code&gt; or try this code in the &lt;a href="https://turnout-playground.netlify.app" rel="noopener noreferrer"&gt;playground&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built this
&lt;/h2&gt;

&lt;p&gt;I wanted the benefits of an SPA without losing the "HTML-first" soul of Alpine.js. Turnout is tiny, fast, and stays out of your way until you need to switch views.&lt;/p&gt;

&lt;p&gt;I’d love for you to try it out, star the repo, or give me some feedback on the "switch" logic!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Test the &lt;a href="https://turnout-playground.netlify.app" rel="noopener noreferrer"&gt;Playground&lt;/a&gt;: Does it feel as smooth as intended?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Break the code: Try it in your edge cases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Contribute: Check out the &lt;a href="https://github.com/rodezee/alpine-turnout" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; Repo.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;#alpinejs&lt;/code&gt; &lt;code&gt;#javascript&lt;/code&gt; &lt;code&gt;#webdev&lt;/code&gt; &lt;code&gt;#frontend&lt;/code&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
