State Machines in Vue: A Union Type, One Function and a Tiny useReducer 0 ▲ alexop.dev 2 hours ago · 10 min read1912 words · Tech · hide Every Vue app I’ve worked on has these three lines: const user = ref<User | null>(null) const isLoading = ref(false) const error = ref<string | null>(null) That’s three refs: one for the data, one for the spinner and one for the error. It has a bug, and I shipped it more than once. The fix is a state machine. That sounds like a library you have to learn first. It’s a TypeScript type and one function. The bug Here’s the whole component. It loads a profile and shows it. <script setup lang="ts"> const user = ref<User | null>(null) const isLoading = ref(false) const error = ref<string | null>(null) async function load() { isLoading.value = true try { user.value = await fetchUser() } catch { error.value = 'Could not load the profile' } finally { isLoading.value = false } } </script> <template> <button @click="load">Load profile</button> <p v-if="isLoading">Loading…</p> <p v-else-if="error">{{ error }}</p> </template> Load the profile once. It works. Now the server goes down and you press… Commenting on Bubbles has been removed. Why? If you want to talk about this post, write to the author, use the comments on their blog if it has them, or reply with a "RE:" post on your own blog. Suggestions? feedback@bubbles.town