<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="192228" data-post-id="192228">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="harmon25" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/harmon25/120/1274_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  harmon25
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="dorgan" data-post="68" data-topic="34743">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dorgan/48/22107_2.png" class="avatar"> dorgan:</div>
<blockquote>
<p>I’m already seeing real benefits from being indexed in search engines, it’s not about scale but visibility. As a content platform, SEO is crucial. It doesnt even have that much to do with scale. Not having a worldwide scale doesnt mean you shouldn’t care about your content being discoverable.</p>
</blockquote>
</aside>
<p>Another approach to this is just building a static site (Gatsby or w.e)…if the content is not something that needs to be immediately published - you could do something quite simple via an API that writes a JSON file to a storage bucket - and on a regular basis like every evening it kicks off a build, deploying and SEOing the newly added content… of course this also has scaling issues if you are building 100k + pages(unless done incrementally) - but if you want really good SEO - you cant beat serving static content. This is also not a bad idea until you DO reach scaling issues, and then you re-engineer when you actually have users actively publishing content all the time…</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="192228" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/phoenix-liveview-vs-spa/34743/73">Post #72</a>
	                </div>
	            </div>
              <div id="likers-container-192228" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="192228"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #72"></div>
  </section>
</div>
    <div class="postbit" id="192236" data-post-id="192236">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dorgan" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dorgan/120/22107_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dorgan
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>In my particular case, the content is user generated, akin to reddit, so it is immediatly published.<br>
For other cases, your solution may work, but it adds another moving part to the stack.</p>
<p>The reason you can have, say, gatsby, next.js, nuxt, sapper, etc, and don’t suffer from the disconnect between what the backend knows about the markup and what the frontend knows about what to enhance, is because both the browser and node can evaluate the same code(more or less, but you get the idea). With this stack it doesn’t matter if you build an SPA or not, because the client always receives all it needs to show content to the user or crawlers.<br>
But this isn’t the case with Phoenix, so despite having an excellent templating engine, if you want to avoid the disconnect you need to spin up a node server and let it handle the frontend. You can mix them of course, but at some point you think “this would be SO MUCH EASIER(and maybe cheaper) if I could just do everthing in js”, so that’s why I think we see MPA or SPA, and not much in between(maybe github is one of those rare specimen that take the in-between route).</p>
<p>For some stuff, it doesn’t really matter who knows what. A dropdown or an image cropper, for instance, can be built with whatever frontend tool you want.<br>
When you have content that needs a roundtrip to the server to perform some action and reflect the results in the client, however, it <em>does</em> matter and drives the way you design everything. It can be a page navigation to not lose state on some layout pieces(like a chat miniwindow), it can be a change on how certain pieces of content are displayed.</p>
<p>So coming back to the topic of Phoenix LiveView vs SPA, I believe this is where I think LiveView shines, because it allows you add behavior to the markup not without the need to write js, but <em>without the need to spin an additional server to handle the frontend</em> and <em>without having your presentation pieces split between clientside libraries and backend templates</em>. And I believe it’s for this very reason LiveView is coupled to the DOM and it’s not just a data diffing/syncing library. Most people don’t have the scale of github or twitter, and Phoenix channels have already proved to scale very well, so I believe LiveView can take you quite far. If you do reach a really big scale, I would say you’re making enough money to hire a bigger team and maintain more complex stacks.</p>
<p>I hope this makes my stance more clear. I’m not in the SPA or anti SPA team, because I understand both approaches have their places and I’ve already tried both extremes(FWIW, most of the user facing content of my project is phoenix templates intertwined with js enhancements, and the backoffice is mostly handled by js alone). But when you want to sit in the middle ground and keep your stack small, there’s a lot of dragons to tame. You can’t have the cake and eat it too, I guess. It’s a very very wide topic and there’s a lot of factors to have in mind.</p>
<p>I’m not using LiveView because I have some concerns about memory usage with potentially infinite data sets in the client(infinite scrolls), but it does solve real problems for a wide variety of use cases.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="192236" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/phoenix-liveview-vs-spa/34743/74">Post #73</a>
	                </div>
	            </div>
              <div id="likers-container-192236" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="192236"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #73"></div>
  </section>
</div>
    <div class="postbit" id="192238" data-post-id="192238">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lud" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lud/120/14382_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lud
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="dorgan" data-post="60" data-topic="34743">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dorgan/48/22107_2.png" class="avatar"> dorgan:</div>
<blockquote>
<p>Personally, I wouldn’t have “pre-made components like material ui” as a metric, because when I started with VueJS the complain was that there was a lack of component uis and it wasn’t wise to pick it for a new project. Same for svelte until a few months ago. First comes the solution, only then one would care about component libraries if they’re so important.</p>
</blockquote>
</aside>
<p>I know Vue has Quasar, it is great. Was was new for Svelte a few months ago?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="192238" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/phoenix-liveview-vs-spa/34743/75">Post #74</a>
	                </div>
	            </div>
              <div id="likers-container-192238" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="192238"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #74"></div>
  </section>
</div>
    <div class="postbit" id="192239" data-post-id="192239">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dorgan" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dorgan/120/22107_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dorgan
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a href="https://sveltematerialui.com/" rel="noopener nofollow ugc">https://sveltematerialui.com/</a> for instance. Also Svelte-prosemirror, Sapper, you can check <a href="https://madewithsvelte.com/" rel="noopener nofollow ugc">https://madewithsvelte.com/</a> and find a whole lot of bindings for other libraries. Before Svelte 2 it wasn’t popular enough and it was lacking on community-made bindings and libraries in general.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="192239" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/phoenix-liveview-vs-spa/34743/76">Post #75</a>
	                </div>
	            </div>
              <div id="likers-container-192239" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="192239"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #75"></div>
  </section>
</div>
    <div class="postbit" id="192266" data-post-id="192266">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="harmon25" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/harmon25/120/1274_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  harmon25
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="dorgan" data-post="74" data-topic="34743">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dorgan/48/22107_2.png" class="avatar"> dorgan:</div>
<blockquote>
<p>In my particular case, the content is user generated, akin to reddit, so it is immediatly published.<br>
For other cases, your solution may work, but it adds another moving part to the stack.</p>
</blockquote>
</aside>
<p>Yea would not do this unless it was the only type of content. I am pretty impressed with the JAM stack ideas though. They are doing a good job of replacing the usage of systems like WordPress/Drupal - which imo are a stain on the web and we would be better off without. They did serve a purpose, but are now a liability.  There is a huge amount of web development done in that space, the public site that is not an app but maybe needs some sort of CMS functionality - and is better off not being dynamic in that it just adds a larger attack surface - and running costs. The future of most static/marketing sites with any cms requirements are better served with something like <a href="https://www.netlifycms.org/" rel="noopener nofollow ugc">netlifycms</a></p>
<aside class="quote no-group" data-username="dorgan" data-post="74" data-topic="34743">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dorgan/48/22107_2.png" class="avatar"> dorgan:</div>
<blockquote>
<p>But when you want to sit in the middle ground and keep your stack small, there’s a lot of dragons to tame. You can’t have the cake and eat it too, I guess.</p>
</blockquote>
</aside>
<p>You are right about this - at least our current state of Phoenix + JS integration is not helping to tame the dragons…The difficult position the phoenix team was in when deciding what to do in regards to static asset management and the stumbling with <code>brunch</code> as the initial bundler is I believe what led us down this path, and did not leave a positive impression of the JS community with the phoenix team…<br>
The migration to webpack has been good - but I think something to bridge the divide more cleanly like what the guys behind <a href="https://hexdocs.pm/asset_import/readme.html" rel="noopener nofollow ugc">asset_import</a> have done would be a step in the right direction…</p>
<p>I think we have somewhat concluded this discussion and it is clear there is room for LiveView and SPAs and even fully static sites. Factors such as the team building it, the users/target market, the requirements of the UI; its the age old answer of ‘it depends’…</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="192266" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/phoenix-liveview-vs-spa/34743/77">Post #76</a>
	                </div>
	            </div>
              <div id="likers-container-192266" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="192266"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #76"></div>
  </section>
</div>
    <div class="postbit" id="192274" data-post-id="192274">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="AstonJ" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/AstonJ/120/15_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  AstonJ
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="harmon25" data-post="72" data-topic="34743">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/harmon25/48/1274_2.png" class="avatar"> harmon25:</div>
<blockquote>
<p>I think you should give React another look also, its functional approach and simplicity really shines when combined with Elixir - the context switching between JSX ↔ Elixir is not bad at all. (its honestly no worse than writing eex,leex templates…)</p>
</blockquote>
</aside>
<p>React does indeed look like the best atm, at least from the various sites I’ve seen using it. Some do feel a little too similar (bit like when Bootstrap took off) so it’s good to see more UI kits coming out. I will definitely check it out at some point but I want to see how I get on with Svelte first. I like that it’s the newest of the bunch and that we may be able to help shape the direction it may go in by providing feedback etc.</p>
<p>I’m enjoying seeing the Svelte portal grow on Devtalk too, could be worth keeping an eye on for anyone interested in Svelte <img src="https://forum.elixirforum.com/uploads/default/original/2X/6/6c3193d1dd46244da3c8c6f719c9f5e2abdd5ae8.gif?v=15" title=":003:" class="emoji emoji-custom" alt=":003:" loading="lazy" width="20" height="20"></p>
<aside class="onebox allowlistedgeneric" data-onebox-src="https://devtalk.com/svelte">
  <header class="source">
      <img src="https://devtalk.com/favicon-32x32.png" class="site-icon" alt="" width="32" height="32">

      <a href="https://devtalk.com/svelte" target="_blank" rel="noopener nofollow">devtalk.com</a>
  </header>

  <article class="onebox-body">
    <div class="aspect-image" style="--aspect-ratio:690/362;"><img src="https://devtalk.com/assets/og_images/svelte-8f689aa58c3b27eec5de1820b9acc139f4751cb381009a50f55aa9a067a51849.png" class="thumbnail" alt="" width="690" height="362"></div>

<h3><a href="https://devtalk.com/svelte" target="_blank" rel="noopener nofollow">Svelte Frontend Framework Portal | Devtalk</a></h3>

  <p>Svelte portal on Devtalk - see what's trending, discuss, share news, articles, blog posts, libraries or ask questions about Svelte in our forum.</p>


  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>
 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="192274" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/phoenix-liveview-vs-spa/34743/78">Post #77</a>
	                </div>
	            </div>
              <div id="likers-container-192274" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="192274"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #77"></div>
  </section>
</div>
    <div class="postbit" id="193055" data-post-id="193055">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="50kudos" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/50kudos/120/4435_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  50kudos
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Just read ALL comments on this thread, I was “yes” “yes” multiple times. It’s quite many good points if I have to quote. I had done a project using phoenix channel with SPA 3 years ago. Currently I am on a project that produces worst case of leex diff, client patch (via <code>live_patch</code>) tooks 7 seconds! And then I switched view layer to Elm and just push pure data (push_event/3) down, and it now takes ~ 1 second! (Bonus: 7MB memory for components diff tracking is now 0.9MB)</p>
<p>Compared to low level phoenix channel + SPA, liveview + SPA is a lot easier. (Server + Client) side routing for free!, <code>push_event</code>/<code>this.handleEvent</code> for free..</p>
<p>So I agree with many points in this thread, liveview without presentation/view layer is still super solid (again, push_event, this.handleEvent, routing (live_patch, handle_param etc). I kinda think all those phx- stuff should be js API. Keep those form stuff since it goes to server anyway. Finally yeah, there’s still room for liveview + SPA indeed, basically liveview + virualdom lib + vanillajs lib + custom element should work well together. Not re-inventing lots of thing on their own virtual[king]dom; the web platform today has many borders (no micro frontend thanks!)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="193055" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/phoenix-liveview-vs-spa/34743/79">Post #78</a>
	                </div>
	            </div>
              <div id="likers-container-193055" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="193055"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #78"></div>
  </section>
</div>
    <div class="postbit" id="193544" data-post-id="193544">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="marciol" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/marciol/120/4223_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  marciol
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>This is one of the more clarifying threads about this subject I have seen, and in general, you summarized very well the possibilities that are open to getting full advantage of Phoenix LiveView when doing SPAs.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="193544" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/phoenix-liveview-vs-spa/34743/80">Post #79</a>
	                </div>
	            </div>
              <div id="likers-container-193544" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="193544"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #79"></div>
  </section>
</div>
    <div class="postbit" id="377970" data-post-id="377970">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="adamu" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/adamu/120/31482_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  adamu
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Sorry for the thread resurrect from a perpetual LV-newbie, but I’ve been thinking about this topic. Specifically in relation to this observation from the HTMX thread:</p>
<aside class="quote no-group" data-username="garrison" data-post="18" data-topic="31888" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"><a href="https://forum.elixirforum.com/t/htmx-a-js-library-sort-of-like-liveview/31888/18" rel="nofollow">HTMX - A js library sort of like liveview</a></div>
<blockquote>
<p>There is really only one difference between LiveView and HTMX: LiveView is stateful and HTMX is not. Everything else (like the much more thorough list above) is directly downstream of that.</p>
<p>Honestly the differences between what LiveView is (a stateful app on the server patching a thin client) and what HTMX is (stateless XHR into DOM) are substantial enough that I don’t really see how they can be compared at all. This is not to say that one is better than the other - they just do completely different things. The programming model is wildly different, and so are the use cases.</p>
<p>The only other thing to note is that what LiveView does is really only possible on the BEAM, as it can actually handle that many stateful connections without catching fire. The HTMX approach on the other hand is something you can do on any stack (including Phoenix!). But again, they are <em>completely different</em> approaches that are not useful for solving the same problems.</p>
</blockquote>
</aside>
<p>Managing the UI state on the server seems fine if there is a single server, but what do you do if you want to scale an app to have multiple server nodes? The client could disconnect and reconnect to a different server. Would its UI get reset (unless perhaps Erlang distribution is used to synchronise between server nodes)? Or would you simply have to force the client to do a full reload in this case?</p>
<p>If you are managing the state on the client with stateless connections, it shouldn’t matter which node the background API requests hit, as it will all be managed on the client.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="377970" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/phoenix-liveview-vs-spa/34743/81">Post #80</a>
	                </div>
	            </div>
              <div id="likers-container-377970" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="377970"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #80"></div>
  </section>
</div>
    <div class="postbit" id="377974" data-post-id="377974">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="LostKobrakai" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/LostKobrakai/120/3072_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  LostKobrakai
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Yes the UI would by default reset. But that only matters for stuff that the server doesn’t know about. All the information that lives on the server should render the absolute same no matter which app server you hit. That’s most of the value you get from LV – not needing to jump through hoops to bring stuff you need the server for anyways onto the client in a way it can be updated and react to user input.</p>
<p>Then there’s forms, which by definition pose temp. client side state. LV has means to submit current form values on reconnect, so the server can respond in a way that take those form values into account.</p>
<p>Another given form of client side state is the URL. So things like tabs or modals could change the url, so on reconnect the server will know based on the URL what to do. Another common example of that is search forms or pagination.</p>
<p>You might also have additional client side state that a developer brings into the picture. For those you can use <code>connect_params</code>, which the LV js client can receive and – just like the form recovery – send up on reconnect for the server to account for.</p>
<p>Lastly you might have state, which both the client and the server want to have a say in and that’s where things get more complicated given the nature of dealing with distributed state.</p>
<p>So far for the theory. In practise you still sometimes needs to get your hands a bit dirty to separate purely client side state from purely server side state due to how morphdom works. It wholesale replaces dom nodes without ids and also removes all client side changes unless they’re made in a way for LV to recognise them. If LV would use different means of updating the DOM client side that complexity could be improved upon, but I doubt that’ll happen.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="377974" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/phoenix-liveview-vs-spa/34743/82">Post #81</a>
	                </div>
	            </div>
              <div id="likers-container-377974" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="377974"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #81"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/34743/load_more?page=9">Load more posts (10 remaining)</a>
</div></template></turbo-stream>