Skip to content

f9ine99/LivePulse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Realtime Visitor Counter

Small hobby project to learn and play with:

  • Next.js (App Router)
  • Supabase Realtime Presence
  • WebSocket presence only (no REST fetch, no DB polling)

The page shows:

👀 X people are viewing this page right now

What this does

When a user opens the page:

  1. The browser joins a Supabase realtime channel for the current route.
  2. The client tracks its presence in that channel.
  3. Every connected client updates the count from shared presence state.
  4. On tab close, unload, or disconnect, presence is removed and everyone updates.

Project structure

app/
  globals.css
  layout.js
  page.js
components/
  realtime-visitor-counter.js
lib/
  supabase-browser.js
docs/
  implementation.md

Requirements

  • Node.js 20+
  • A Supabase project
  • Supabase project URL and anon key

Setup

  1. Install dependencies:
npm install
  1. Create local env file:
cp .env.example .env.local
  1. Set values in .env.local:
  • NEXT_PUBLIC_SUPABASE_URL
  • NEXT_PUBLIC_SUPABASE_ANON_KEY
  1. Start development server:
npm run dev
  1. Open http://localhost:3000 in multiple tabs or browsers and watch the count update live.

Scripts

  • npm run dev - start development server
  • npm run build - build the app
  • npm run start - start the built app (optional)

How counting works

  • Channel name is derived from route pathname (visitors:<sanitized-path>).
  • Presence state is read from channel.presenceState().
  • Count is calculated as the total number of active presence entries.
  • The component subscribes to presence events:
    • sync
    • join
    • leave
  • No table queries are used.

Implementation notes

  • Client uses a singleton Supabase browser client.
  • Auth session persistence is disabled (persistSession: false) because this demo does not need user auth state.
  • Cleanup is explicit:
    • channel.untrack() on teardown
    • supabase.removeChannel(channel) on teardown
    • untrack() also runs on pagehide and beforeunload

Troubleshooting

  • Error: Missing NEXT_PUBLIC_SUPABASE_URL or NEXT_PUBLIC_SUPABASE_ANON_KEY.
    • Set both values in .env.local and restart dev server.
  • Count does not change across tabs:
    • Verify both tabs are on the same route.
    • Verify keys point to the same Supabase project.
    • Check browser console/network for websocket blocking.

Deep dive

See docs/implementation.md for lifecycle, channel strategy, customization points, and extension ideas.

About

LivePluse is supabase based hobby project to showcase how supabase realtime presence work aim to show websocket and memory state presence

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors