nuxt-live-cursors
v0.3.2
Published
Real-time live cursors for Nuxt - see other visitors on your site
Maintainers
Readme
nuxt-live-cursors
Real-time live cursors for Nuxt. Show other visitors on your site with avatars and random nicknames.
Built on Nitro WebSocket - zero external dependencies, no third-party services.
Features
- Live cursor positions via WebSocket (syncs on both mouse move and scroll)
- Hide/show other cursors toggle in profile popover
- Random SVG avatars (powered by @nextorders/avatar)
- Built-in localization (English, Russian) with easy extension via PR
- Unique colors per visitor
- Online bar with visitor avatars
- Profile popover with shuffle button
- Auto-reconnect on disconnect
- Cursor filtering by current page
- Configurable via
nuxt.config.ts - Slots for full customization
Setup
npx nuxi module add nuxt-live-cursorsOr install manually:
npm i nuxt-live-cursors// nuxt.config.ts
export default defineNuxtConfig({
modules: ['nuxt-live-cursors'],
})Usage
Add the component to your app.vue:
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
<LiveCursors />
</template>That's it. Cursors will appear automatically with English nicknames.
Position
Control where the online bar appears:
<LiveCursors position="bottom-right" />Options: top-left, top-center, top-right, bottom-left, bottom-center (default), bottom-right.
Localization
Pass the locale prop to switch language:
<LiveCursors locale="ru" />With @nuxtjs/i18n:
<LiveCursors :locale="locale" />
<script setup>
const { locale } = useI18n()
</script>Built-in locales: en, ru. Unsupported locales fall back to English.
Want to add a language? Submit a PR with a new file in src/runtime/locales/.
Configuration
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['nuxt-live-cursors'],
liveCursors: {
// WebSocket endpoint path (default: '/_live-cursors-ws')
wsPath: '/_live-cursors-ws',
// Avatar endpoint path (default: '/_live-cursors-avatar')
avatarPath: '/_live-cursors-avatar',
// Throttle interval in ms (default: 50)
throttleMs: 50,
},
})Composable
Use useLiveCursors() for custom implementations:
const {
cursors, // other visitors' cursors on current page
cursorsHidden, // ref<boolean> — toggle to hide/show other cursors
onlineUsers, // all connected visitors
onlineCount, // total count
myId, // your unique ID
myNameKey, // your nickname key (resolve via locales)
myColor, // your cursor color
myAvatar, // your avatar URL
isConnected, // WebSocket connection status
shuffle, // randomize your identity
} = useLiveCursors()Slots
The <LiveCursors> component provides slots for customization:
<LiveCursors locale="ru">
<!-- Customize cursor name display -->
<template #cursor-name="{ cursor }">
{{ cursor.nameKey }}
</template>
<!-- Customize your name in profile -->
<template #my-name>
Custom Name
</template>
<!-- Customize profile actions (full layout control) -->
<template #profile-actions="{ shuffle, cursorsHidden, toggleCursors, labels }">
<button @click="shuffle">{{ labels.shuffle }}</button>
<button @click="toggleCursors">
{{ cursorsHidden ? labels.showCursors : labels.hideCursors }}
</button>
</template>
<!-- Customize online counter text -->
<template #online-text="{ count }">
{{ count }} visitors
</template>
</LiveCursors>Live example
See it in action on kosarev.space — open in two tabs and watch the cursors.
Read the case study for implementation details.
CSP
If you use Content-Security-Policy, add WebSocket to connect-src:
connect-src 'self' wss: ws:License
MIT
