
Aplikasi Chat Real-time Next.js: Bangun dengan WebSocket & Material-UI
Panduan lengkap membangun aplikasi chat real-time menggunakan Next.js, WebSocket (Socket.io), dan Material-UI (MUI) untuk performa optimal dan UI modern.
Pendahuluan
Di era digital yang serba cepat,Β aplikasi chat real-time Next.jsΒ menjadi solusi populer untuk komunikasi instan. Artikel ini membagikan pengalaman praktis membangun aplikasi tersebut menggunakan Next.js, WebSocket (Socket.io), dan Material-UI.
Implementasi Server WebSocket
Pada file server.js
, saya membuat server WebSocket yang terintegrasi dengan Next.js:
const { createServer } = require("http");
const next = require("next");
const { Server } = require("socket.io");
const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = createServer((req, res) => {
handle(req, res);
});
const io = new Server(server);
const channelIntervals = new Map(); // Simpan interval per channel
io.on("connection", (socket) => {
console.log("π’ User connected:", socket.id);
socket.on("joinChannel", (channelId) => {
if (!channelId) return;
console.log(`User ${socket.id} joined channel: ${channelId}`);
socket.join(channelId);
// Fetch pesan dari Discord API
const fetchMessages = async () => {
try {
const response = await fetch(
`https://discord.com/api/v10/channels/${channelId}/messages?limit=10`,
{
method: "GET",
headers: {
Authorization: `Bot ${process.env.DISCORD_BOT_TOKEN}`,
},
}
);
if (!response.ok) throw new Error("Gagal mengambil pesan");
const messages = await response.json();
io.to(channelId).emit("messages", messages);
} catch (error) {
console.error(`β Error fetching messages for ${channelId}:`, error);
}
};
// Hentikan interval lama jika sudah ada
if (channelIntervals.has(channelId)) {
clearInterval(channelIntervals.get(channelId));
}
// Mulai polling tiap 5 detik
fetchMessages();
const interval = setInterval(fetchMessages, 5000);
channelIntervals.set(channelId, interval);
// Cleanup saat disconnect
socket.on("disconnect", () => {
console.log("π΄ User disconnected:", socket.id);
clearInterval(interval);
});
socket.on("leaveChannel", () => {
console.log(`User ${socket.id} left channel: ${channelId}`);
clearInterval(interval);
channelIntervals.delete(channelId);
socket.leave(channelId);
});
});
});
server.listen(3000, () => {
console.log("Server is running on http://localhost:3000");
});
});
Beberapa poin penting dalam implementasi server:
- Integrasi dengan Next.js: Server HTTP dibuat bersama dengan handler Next.js
- Manajemen Room: Setiap channel chat dibuat sebagai room terpisah
- Polling Otomatis: Sistem melakukan polling otomatis ke Discord API setiap 5 detik
- Cleanup Resources: Interval dan koneksi dibersihkan saat user disconnect
Implementasi Client dengan Material-UI
Pada komponen ChatContent
, saya membuat antarmuka pengguna yang kaya fitur dengan Material-UI:
const ChatContent = ({ ticket }) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
const { userData } = useUser();
// Refs dan state management
const bottomRef = useRef(null);
const socketRef = useRef(null);
const [messages, setMessages] = useState([]);
const [message, setMessage] = useState('');
const [file, setFile] = useState(null);
const [loadingMessages, setLoadingMessages] = useState(false);
const [sendingMessage, setSendingMessage] = useState(false);
const [error, setError] = useState(null);
// Setup WebSocket connection
const setupSocket = () => {
if (!ticket?.discordChannelId) return;
if (socketRef.current) {
socketRef.current.disconnect();
}
socketRef.current = io();
socketRef.current.emit('joinChannel', ticket.discordChannelId);
socketRef.current.on('messages', (newMessages) => {
const sortedMessages = [...newMessages].sort((a, b) => {
return new Date(a.timestamp) - new Date(b.timestamp);
});
const formattedMessages = sortedMessages.map(msg => ({
...msg,
timestamp: msg.timestamp ? new Date(msg.timestamp) : new Date()
}));
setMessages(formattedMessages);
});
socketRef.current.on('connect_error', (err) => {
console.error('Socket connection error:', err);
setError('Realtime connection failed. Messages may not update automatically.');
});
};
// ... (fungsi-fungsi lainnya)
};
Fitur Unggulan Implementasi
1. Real-time Message Updates
Dengan WebSocket, pesan muncul secara real-time tanpa perlu refresh halaman. Setiap kali ada pesan baru di channel, semua anggota channel akan menerima update secara otomatis.
2. UI Responsif dengan Material-UI
Saya memanfaatkan berbagai komponen MUI untuk menciptakan antarmuka yang menarik:
<MainCard
content={false}
sx={{
height: '100%',
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'dark.main' : 'grey.50',
pt: 2,
pl: isMobile ? 0 : 2,
borderRadius: '0 12px 12px 0',
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.shorter + 200
})
}}
>
3. Emoji Picker yang Interaktif
Integrasi emoji picker dengan animasi yang halus:
<EmojiPicker
onEmojiClick={(emojiData) => {
setMessage(message + emojiData.emoji);
setEmojiPickerOpen(false);
}}
defaultSkinTone={SkinTones.DARK}
autoFocusSearch={false}
/>
4. Upload File dengan Preview
Sistem mendukung upload file dengan validasi:
const handleFileChange = (e) => {
const selectedFile = e.target.files[0];
if (!selectedFile) return;
// Validasi ukuran file (maksimal 5MB)
const MAX_FILE_SIZE = 5 * 1024 * 1024;
if (selectedFile.size > MAX_FILE_SIZE) {
setError('File size too large (max 5MB allowed)');
return;
}
// Validasi tipe file
const validTypes = [
'image/jpeg',
'image/png',
'image/gif',
'application/pdf',
'text/plain',
'application/msword'
];
if (!validTypes.includes(selectedFile.type)) {
setError('Only images (JPEG, PNG, GIF), PDF, and text files are allowed');
return;
}
setFile(selectedFile);
setError(null);
};
5. Auto-scroll ke Pesan Terbaru
Pengalaman pengguna ditingkatkan dengan auto-scroll otomatis:
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages]);
Hasil
Implementasi WebSocket dengan Next.js dan Material-UI memberikan pengalaman real-time yang mulus dengan antarmuka yang modern.

Beberapa poin kunci yang berhasil saya terapkan:
- Integrasi yang baik antara Next.js API routes dengan WebSocket server
- Manajemen state yang efisien untuk data real-time
- Antarmuka pengguna yang responsif dan kaya fitur dengan Material-UI
- Mekanisme fallback dan error handling yang robust
Dengan pendekatan ini, aplikasi chat menjadi lebih interaktif dan menyenangkan untuk digunakan.
Butuh Bantuan Profesional? Tavern Studio Siap Membantu!
Membangun project Next.js membutuhkan keahlian teknis dan pengalaman. Jika Anda ingin:
π Website bisnis yang cepat dan SEO-friendly
π¨ Desain modern dengan Tailwind CSS
π§ Integrasi API & database
π Optimasi performa dan keamanan
Tavern Studio siap menjadi mitra IT Anda! Kami menyediakan jasa pengembangan web, mobile, dan sistem berbasis Next.js dengan kualitas terbaik.
Kenapa Memilih Tavern Studio?
β Tim developer berpengalaman
β Solusi tailor-made sesuai kebutuhan bisnis
β Dukungan purna jual yang responsif
β Harga kompetitif dengan hasil maksimal
Hubungi Kami Sekarang!
π§ Email: ta***********@*****ok.com
π WhatsApp: +62 857-6621-8870
Jangan ragu untuk berkonsultasi gratis! Kami siap membantu mewujudkan project Next.js impian Anda. π
Dengan Next.js dan dukungan dari Tavern Studio, website Anda akan memiliki performa tinggi, tampilan elegan, dan mudah dikelola. Segera mulai project Anda hari ini! π