
How to Build Realtime Features in Next.js Using Supabase
๐ How to Build Realtime Features in Next.js Using Supabase
Realtime features allow your application to update instantly without page refresh.
Common examples:
Live chat
Notifications
Order tracking
Admin dashboards
Stock updates
Collaborative apps
Supabase provides realtime subscriptions directly from your Postgres database.
This guide shows how to implement realtime features in a Next.js App Router project.
1. Prerequisite: Supabase Auth & Client Setup
This tutorial assumes your Supabase project and authentication are already configured.
๐ Follow the full setup guide here:
How to Add Supabase Auth in Next.js
That guide covers:
Supabase client setup
Environment variables
User session handling
Protected routes
Realtime features typically rely on authenticated users.
2. Install Supabase Client
If not already installed:
npm install @supabase/supabase-jsCreate a client:
import { createClient } from "@supabase/supabase-js";
export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
);3. Enable Realtime on a Table
Realtime works only when replication is enabled.
In Supabase dashboard:
Database โ Replication โ Enable realtime
Enable it for tables like:
messages
orders
notifications
4. Example: Realtime Chat
Client component:
"use client";
import { useEffect, useState } from "react";
import { supabase } from "@/lib/supabase";
export default function Chat() {
const [messages, setMessages] = useState([]);
useEffect(() => {
loadMessages();
const channel = supabase
.channel("messages-channel")
.on(
"postgres_changes",
{ event: "INSERT", schema: "public", table: "messages" },
(payload) => {
setMessages((prev) => [...prev, payload.new]);
}
)
.subscribe();
return () => supabase.removeChannel(channel);
}, []);
async function loadMessages() {
const { data } = await supabase.from("messages").select("*");
setMessages(data || []);
}
return (
<div>
{messages.map((m) => (
<p key={m.id}>{m.text}</p>
))}
</div>
);
}New messages appear instantly.
5. Example: Live Order Status
Realtime updates when order status changes.
supabase
.channel("orders")
.on(
"postgres_changes",
{ event: "UPDATE", table: "orders" },
(payload) => {
console.log("Order updated", payload.new);
}
)
.subscribe();Use for:
Delivery tracking
Admin panels
Warehouse dashboards
6. Example: User Notifications
Subscribe per user:
const userId = session.user.id; // from Supabase Auth
supabase
.channel("notifications")
.on(
"postgres_changes",
{
event: "INSERT",
table: "notifications",
filter: `user_id=eq.${userId}`,
},
(payload) => {
showToast(payload.new.message);
}
)
.subscribe();This prevents unnecessary updates.
7. Example: Presence (Online Users)
Supabase realtime also supports presence.
Example:
const channel = supabase.channel("online-users");
channel.on("presence", { event: "sync" }, () => {
const state = channel.presenceState();
console.log(state);
});
channel.subscribe(async (status) => {
if (status === "SUBSCRIBED") {
await channel.track({ user: "user-id" });
}
});Used for:
Online indicators
Collaborative apps
Multiplayer dashboards
8. Performance Tips for Realtime
Use filters to avoid excessive events:
Subscribe only to needed tables
Filter by user ID
Avoid global subscriptions
Unsubscribe on component unmount
Realtime should be targeted, not global.
9. Security Best Practices
Always:
Enable Row Level Security
Filter events per user
Avoid exposing sensitive columns
Validate writes on server
Realtime mirrors database changes โ security matters.
10. When to Use Realtime
Use realtime when:
Users expect instant updates
Data changes frequently
Collaboration exists
Notifications matter
Do not use realtime for:
Static content
SEO pages
Heavy analytics streams without filtering
Conclusion
Supabase realtime makes it easy to build interactive applications without managing WebSocket infrastructure.
Combined with Next.js:
Server handles logic
Supabase handles realtime
Client updates instantly
This enables modern experiences like chat, live dashboards, and collaborative tools with minimal complexity.