Troubleshooting Guide
View SourceThis guide helps you diagnose and fix common issues when working with LiveVue.
Quick Start
New to LiveVue? Start with Getting Started for a working example, then check Basic Usage for common patterns.
Component Issues
Component Not Rendering
Symptoms:
- Empty div where component should be
- No errors in console
- Component works in isolation
Possible Causes & Solutions:
Missing
v-socket
attribute# ❌ Missing v-socket <.vue v-component="Counter" count={@count} /> # ✅ Correct <.vue v-component="Counter" count={@count} v-socket={@socket} />
Component name mismatch
# ❌ File: Counter.vue, but using wrong name <.vue v-component="counter" v-socket={@socket} /> # ✅ Correct - case sensitive <.vue v-component="Counter" v-socket={@socket} />
Check browser console for errors.
Component not found in resolution
// Check your component resolution in assets/vue/index.js const components = { ...import.meta.glob("./**/*.vue", { eager: true }), } // Debug: log available components console.log("Available components:", Object.keys(components))
Component Renders But Doesn't Update
Symptoms:
- Component shows initial state
- Props don't update when server state changes
- No reactivity
Solutions:
Check prop names match
# Server side <.vue user_name={@user.name} v-component="Profile" v-socket={@socket} />
<!-- Client side - prop names must match exactly --> <script setup> const props = defineProps<{ user_name: string // Must match server prop name }>() </script>
Verify assigns are updating
# Add debug logging def handle_event("update", _params, socket) do IO.inspect(socket.assigns, label: "Before update") socket = assign(socket, :count, socket.assigns.count + 1) IO.inspect(socket.assigns, label: "After update") {:noreply, socket} end
Use Vue.js devtools to inspect the component
Open Vue.js devtools in browser and inspect the component. Check if the component is receiving the correct props. Check if the component is re-rendering when the props change.
LiveVue.Encoder Protocol Issues
Symptoms:
Protocol.UndefinedError
when passing structs as props- Component doesn't render with custom struct props
- Error mentions "LiveVue.Encoder protocol must always be explicitly implemented"
Solutions:
Implement the encoder protocol for your structs
defmodule User do @derive LiveVue.Encoder defstruct [:name, :email, :age] end
For third-party structs, use Protocol.derive/3
# In your application.ex or relevant module Protocol.derive(LiveVue.Encoder, SomeLibrary.User, only: [:id, :name])
Debug encoder issues
# Test your encoder implementation iex> user = %User{name: "John", email: "john@example.com"} iex> LiveVue.Encoder.encode(user) %{name: "John", email: "john@example.com"}
For complete implementation details including field selection and custom implementations, see Component Reference.
Common Causes:
- Passing structs without implementing the encoder protocol
- Nested structs where some don't have the protocol implemented
- Third-party library structs that need protocol derivation
TypeScript Errors
Common Error: Cannot find module 'live_vue'
// Add to your env.d.ts or types.d.ts
declare module 'live_vue' {
export function useLiveVue(): any
export function createLiveVue(config: any): any
export function findComponent(components: any, name: string): any
export function getHooks(app: any): any
}
Error: Property 'xxx' does not exist on type
// Define proper interfaces
interface Props {
count: number
user: {
id: number
name: string
}
}
const props = defineProps<Props>()
Event Handling Issues
Events Not Firing
Symptoms:
- Clicking buttons does nothing
- No events reach LiveView
- Console shows no errors
Solutions:
Check event handler syntax
# ❌ Wrong syntax <.vue v-on-click={JS.push("increment")} /> # ✅ Correct syntax <.vue v-on:click={JS.push("increment")} />
Verify event names match
<!-- Vue component --> <button @click="$emit('increment', {amount: 1})">+1</button>
<!-- LiveView template --> <.vue v-on:increment={JS.push("inc")} /> def handle_event("inc", %{"amount" => amount}, socket) do # Handle event end
Check payload structure
# Debug event payload def handle_event("save", params, socket) do IO.inspect(params, label: "Event params") {:noreply, socket} end
Events Fire But Handler Not Called
Check handler function exists:
# Make sure you have the handler defined
def handle_event("my_event", _params, socket) do
{:noreply, socket}
end
Verify event name spelling:
# Event names are case-sensitive
<.vue v-on:save-user={JS.push("save_user")} /> # save-user → save_user
Build and Development Issues
Vite Server Not Starting
Error: EADDRINUSE: address already in use
# Kill process using port 5173
lsof -ti:5173 | xargs kill -9
# Or use different port
npm run dev -- --port 5174
Error: Module not found
# Clear node_modules and reinstall
rm -rf node_modules package-lock.json
npm install
Build Failures
TypeScript compilation errors:
# Check TypeScript version compatibility
npm install typescript@5.5.4 vue-tsc@2.10.0
Vite build errors:
# Clear Vite cache
rm -rf node_modules/.vite
npm run build
Hot Reload Not Working
Check Vite configuration:
// vite.config.js export default defineConfig({ server: { host: '0.0.0.0', // Allow external connections port: 5173, hmr: true } })
Verify watcher configuration:
# config/dev.exs config :my_app, MyAppWeb.Endpoint, watchers: [ npm: ["--silent", "run", "dev", cd: Path.expand("../assets", __DIR__)] ]
SSR Issues
SSR Not Working
Check SSR configuration:
# config/dev.exs
config :live_vue,
ssr_module: LiveVue.SSR.ViteJS,
vite_host: "http://localhost:5173",
ssr: true
For complete SSR configuration options, see Configuration.
Verify Node.js version:
node --version # Should be 19+
SSR Errors in Production
Check NodeJS supervisor:
# application.ex
children = [
{NodeJS.Supervisor, [path: LiveVue.SSR.NodeJS.server_path(), pool_size: 4]},
# ... other children
]
Verify server bundle exists:
ls priv/vue/server.js # Should exist after build
For production SSR setup details, see Configuration.
Performance Issues
Slow Initial Load
Enable lazy loading:
// assets/vue/index.js const components = { Counter: () => import('./Counter.vue'), Modal: () => import('./Modal.vue') }
Optimize bundle size:
# Analyze bundle npm run build -- --analyze
Memory Leaks
Clean up event listeners:
<script setup>
import { onUnmounted } from 'vue'
import { useLiveVue } from 'live_vue'
const live = useLiveVue()
const cleanup = live.handleEvent('data_update', handleUpdate)
onUnmounted(() => {
cleanup() // Important: clean up listeners
})
</script>
Clear timers and intervals:
<script setup>
import { onUnmounted } from 'vue'
const interval = setInterval(() => {
// Do something
}, 1000)
onUnmounted(() => {
clearInterval(interval)
})
</script>
Debugging Techniques
Enable Debug Mode
// In browser console or app.js
window.liveVueDebug = true
Component Inspection
- Use Vue DevTools browser extension
- Add debug logging:
<script setup> import { watch } from 'vue' const props = defineProps<{count: number}>() watch(() => props.count, (newVal, oldVal) => { console.log('Count changed:', oldVal, '→', newVal) }) </script>
Network Debugging
- Monitor WebSocket traffic in browser DevTools
- Log LiveView events:
def handle_event(event, params, socket) do IO.inspect({event, params}, label: "LiveView Event") # ... handle event end
Common Error Messages
Cannot read property 'mount' of undefined
Cause: Component resolution failed
Solution: Check component name and file path
// Debug component resolution
// find component does it by default, you might need to do it if you override it
console.log("Resolving component:", componentName)
console.log("Available components:", Object.keys(components))
ReferenceError: process is not defined
Cause: Node.js globals in browser code
Solution: Add to Vite config:
// vite.config.js
export default defineConfig({
define: {
global: 'globalThis',
'process.env': {}
}
})
Module "live_vue" has been externalized
Cause: SSR configuration issue
Solution: Check Vite SSR config:
// vite.config.js
export default defineConfig({
ssr: {
noExternal: ['live_vue']
}
})
Getting Help
Before Asking for Help
- Check browser console for errors
- Verify all configuration steps (see Configuration)
- Test with minimal reproduction case
- Check if issue exists in example project
Where to Get Help
- GitHub Issues: For bugs and feature requests
- GitHub Discussions: For questions and community help
- Elixir Forum: For general Phoenix/Elixir questions
- Vue.js Discord: For Vue-specific questions
Creating Bug Reports
Include:
- LiveVue version
- Phoenix/LiveView versions
- Node.js version
- Minimal reproduction case
- Error messages and stack traces
- Browser and OS information
Next Steps
- FAQ for conceptual questions
- Architecture to understand how things work
- Configuration for advanced setup options
- GitHub Issues to report bugs