diff --git a/website/docs/providers/stream_provider.mdx b/website/docs/providers/stream_provider.mdx
index 070c96797..b168a30a1 100644
--- a/website/docs/providers/stream_provider.mdx
+++ b/website/docs/providers/stream_provider.mdx
@@ -7,6 +7,8 @@ import TabItem from "@theme/TabItem";
import CodeBlock from "@theme/CodeBlock";
import configProvider from "!!raw-loader!/docs/providers/future_provider/config_provider.dart";
import configConsumer from "!!raw-loader!/docs/providers/future_provider/config_consumer.dart";
+import streamProvider from "!!raw-loader!/docs/providers/stream_provider/live_stream_chat_provider.dart";
+import streamConsumer from "!!raw-loader!/docs/providers/stream_provider/live_stream_chat_consumer.dart";
import { trimSnippet } from "../../src/components/CodeSnippet";
`StreamProvider` is similar to [FutureProvider] but for [Stream]s instead of
@@ -42,3 +44,14 @@ Using `StreamProvider` over [StreamBuilder] has numerous benefits:
[stream.periodic]: https://api.dart.dev/stable/2.15.1/dart-async/Stream/Stream.periodic.html
[family]: ../concepts/modifiers/family
[streambuilder]: https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html
+
+## Usage example: live chat using sockets
+
+`StreamProvider` is used in when we handle stream of asynchronous data
+such as Video Streaming, Weather broadcasting Apis.
+
+{trimSnippet(streamProvider)}
+
+Then, the UI can listen to live streaming chats like so:
+
+{trimSnippet(streamConsumer)}
diff --git a/website/docs/providers/stream_provider/live_stream_chat_consumer.dart b/website/docs/providers/stream_provider/live_stream_chat_consumer.dart
new file mode 100644
index 000000000..79c186f7a
--- /dev/null
+++ b/website/docs/providers/stream_provider/live_stream_chat_consumer.dart
@@ -0,0 +1,26 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+
+import 'live_stream_chat_provider.dart';
+
+/* SNIPPET START */
+Widget build(BuildContext context, WidgetRef ref) {
+ final liveChats = ref.watch(chatProvider);
+ // Like FutureProvider, it is possible to handle loading/error states using AsyncValue.when
+ return liveChats.when(
+ loading: () => const CircularProgressIndicator(),
+ error: (error, stackTrace) => Text(error.toString()),
+ data: (messages) {
+ // Display all the messages in a scrollable list view.
+ return ListView.builder(
+ // Show messages from bottom to top
+ reverse: true,
+ itemCount: messages.length,
+ itemBuilder: (context, index) {
+ final message = messages[index];
+ return Text(message);
+ },
+ );
+ },
+ );
+}
diff --git a/website/docs/providers/stream_provider/live_stream_chat_provider.dart b/website/docs/providers/stream_provider/live_stream_chat_provider.dart
new file mode 100644
index 000000000..d2bb3ad2a
--- /dev/null
+++ b/website/docs/providers/stream_provider/live_stream_chat_provider.dart
@@ -0,0 +1,18 @@
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+
+/* SNIPPET START */
+final chatProvider = StreamProvider>((ref) async* {
+ // Connect to an API using sockets, and decode the output
+ final socket = await Socket.connect('my-api', 4242);
+ ref.onDispose(socket.close);
+
+ var allMessages = const [];
+ await for (final message in socket.map(utf8.decode)) {
+ // A new message has been received. Let's add it to the list of all messages.
+ allMessages = [...allMessages, message];
+ yield allMessages;
+ }
+});