Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Valian/live_vue/llms.txt
Use this file to discover all available pages before exploring further.
Component issues
Component not rendering
Symptoms:
- Empty div where component should be
- No errors in console
- Component works in isolation
Possible causes and solutions:
1. Missing v-socket attribute
# ❌ Missing v-socket
<.vue v-component="Counter" count={@count} />
# ✅ Correct
<.vue v-component="Counter" count={@count} v-socket={@socket} />
2. 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.
3. 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:
1. 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>
2. 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
3. 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 and 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:
1. Implement the encoder protocol for your structs
defmodule User do
@derive LiveVue.Encoder
defstruct [:name, :email, :age]
end
2. For third-party structs, use Protocol.derive/3
# In your application.ex or relevant module
Protocol.derive(LiveVue.Encoder, SomeLibrary.User, only: [:id, :name])
3. Debug encoder issues
# Test your encoder implementation
iex> user = %User{name: "John", email: "[email protected]"}
iex> LiveVue.Encoder.encode(user)
%{name: "John", email: "[email protected]"}
For complete implementation details including field selection and custom implementations, see Basic usage.
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:
1. Check event handler syntax
# ❌ Wrong syntax
<.vue v-on-click={JS.push("increment")} />
# ✅ Correct syntax
<.vue v-on:click={JS.push("increment")} />
2. 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
3. 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:
Vite build errors:
# Clear Vite cache
rm -rf node_modules/.vite
npm run build
Hot reload not working
1. Check Vite configuration:
// vite.config.js
export default defineConfig({
server: {
host: '0.0.0.0', // Allow external connections
port: 5173,
hmr: true
}
})
2. Verify watcher configuration:
# config/dev.exs
config :my_app, MyAppWeb.Endpoint,
watchers: [
npm: ["--silent", "run", "dev", cd: Path.expand("../assets", __DIR__)]
]
3. Understand HMR scope:
- Vue files: Hot Module Replacement works seamlessly - changes to
.vue files are reflected instantly without page refresh
- Elixir files: Changes to
.ex and .heex files trigger a LiveView re-render via Phoenix’s code reloading, not Vite HMR. This still provides fast feedback but works through LiveView’s WebSocket connection rather than Vite’s HMR
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/static/server.mjs # Should exist after build
For production SSR setup details, see Configuration.
Slow initial load
1. Enable lazy loading:
// assets/vue/index.js
const components = {
Counter: () => import('./Counter.vue'),
Modal: () => import('./Modal.vue')
}
2. 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
1. Use Vue DevTools browser extension
2. 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
1. Monitor WebSocket traffic in browser DevTools
2. 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
- Create a fresh project with Igniter to verify the issue isn’t in your configuration
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