Setup
Confused about something?
Let us know how we can improve:
Let us know how we can improve:
The easiest way to build a chat application with this tutorial is to create a new project using the `create-react-app` (CRA). CRA provides a boilerplate React application with all of the necessary configurations for modern JavaScript:
yarn global add create-react-app
Note: Make sure that you have the most recent version of Node.js and Yarn installed.
If you’re on macOS with Homebrew installed and don’t already have the requirements on your machine, you can run the following command:
brew install node && brew install yarn
Next, run the following commands to create a new React project called `chat-example`.
create-react-app chat-example
cd chat-example
yarn add stream-chat stream-chat-react
This will create the skeleton of the chat application project and install the Stream Chat Components.
The first part of this tutorial shows you how to build a WhatsApp / Facebook Messenger style chat and the second part of this tutorial shows how to build chat for a livestream event.
To follow the rest of this tutorial, you will need to get a free 4 weeks trial of Chat. No credit card is required.
Or proceed with a sandbox environment.
Part 1 - WhatsApp / Facebook Messenger Style Chat with React
Confused about something?
Let us know how we can improve:
Let us know how we can improve:
Message List & MessageInput
The core of the Chat interface from Stream is the message list component. Let's initialize the connection to Stream and configure the component. Replace the code in src/App.js
with:
import React from 'react';
import { Chat, Channel, ChannelHeader, Thread, Window } from 'stream-chat-react';
import { MessageList, MessageInput } from 'stream-chat-react';
import { StreamChat } from 'stream-chat';
import 'stream-chat-react/dist/css/index.css';
const chatClient = new StreamChat('gx5a64bj4ptz');
const userToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiZGFyay1maXJlZmx5LTYifQ.rSmEPByOBQBwVUc2WjsyLbwf40E1rOCl9oApWsSrRYE';
chatClient.setUser(
{
id: 'dark-firefly-6',
name: 'Dark firefly',
image: 'https://getstream.io/random_png/?id=dark-firefly-6&name=Dark+firefly'
},
userToken,
);
const channel = chatClient.channel('messaging', 'godevs', {
// add as many custom fields as you'd like
image: 'https://cdn.chrisshort.net/testing-certificate-chains-in-go/GOPHER_MIC_DROP.png',
name: 'Talk about Go',
});
const App = () => (
<Chat client={chatClient} theme={'messaging light'}>
<Channel channel={channel}>
<Window>
<ChannelHeader />
<MessageList />
<MessageInput />
</Window>
<Thread />
</Channel>
</Chat>
);
export default App;
Next run yarn start
to see the chat in action
Note how we're creating the `channel('messaging', 'godevs')` channel.
- The first argument is the chat type and the second argument the chat ID
- The chat type controls which features are enabled and the permissions associated with this chat
- The chat ID is a unique reference to this specific channel
If you look at the following lines of code:
<Chat client={chatClient}>
<Channel channel={channel} theme={'messaging light'}>
<ChannelHeader />
<Window>
<MessageList />
<MessageInput />
</Window>
<Thread />
</Channel>
</Chat>
These react chat components create a fully functional chat UI that is fully customizable. Out of the box you’ll notice that the following features are enabled:
- URL unfurling/preview (Try sending a link to a Youtube video to see this in action)
- Video Playback
- File uploads & Previews
- /slash commands such as /giphy and /imgur. You can also implement your own slash commands to make your chat environment and team more productive.
- Presence – Who is online
- Typing Indicators
- Message Status Indicators (sending, received)
- Automatic AI Powered Spam & Profanity Protection
- Moderators & User Roles
- Emoticons
- Seen/Read Indicators
- Threads & Replies
- Reactions
- Autocomplete on users, emoticons and commands
Channel List
The next example shows you how to render a list of channels. This component is convenient if you want to show a user a list of all the channels they are a member of.
The example below shows how to use the ChannelList component. Update src/App.js with the following code:
import React from 'react';
import { Chat, Channel, ChannelList, Window } from 'stream-chat-react';
import { ChannelHeader, MessageList } from 'stream-chat-react';
import { MessageInput, Thread } from 'stream-chat-react';
import { StreamChat } from 'stream-chat';
import 'stream-chat-react/dist/css/index.css';
const chatClient = new StreamChat('gx5a64bj4ptz');
const userToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiZGFyay1maXJlZmx5LTYifQ.rSmEPByOBQBwVUc2WjsyLbwf40E1rOCl9oApWsSrRYE';
chatClient.setUser(
{
id: 'dark-firefly-6',
name: 'Dark firefly',
image: 'https://getstream.io/random_png/?id=dark-firefly-6&name=Dark+firefly' },
userToken,
);
const filters = { type: 'messaging', members: { $in: ['dark-firefly-6'] } };
const sort = { last_message_at: -1 };
const channels = chatClient.queryChannels(filters, sort);
const App = () => (
<Chat client={chatClient} theme={'messaging light'}>
<ChannelList
filters={filters}
sort={sort}
/>
<Channel>
<Window>
<ChannelHeader />
<MessageList />
<MessageInput />
</Window>
<Thread />
</Channel>
</Chat>
);
export default App;
Note that ChannelList
will automatically set the channel
property of the Channel
component.
Customizing your first component
The underlying API as well as the React Components are extremely flexible. With little to no coding, you can easily build any type of chat. The example below shows you how to swap out the default message component with your own. Update src/App.js with the following code:
import React from 'react';
import { Chat, Channel, ChannelList, Window } from 'stream-chat-react';
import { ChannelHeader, MessageList } from 'stream-chat-react';
import { MessageInput, Thread } from 'stream-chat-react';
import { StreamChat } from 'stream-chat';
import 'stream-chat-react/dist/css/index.css';
const chatClient = new StreamChat('gx5a64bj4ptz');
const userToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiZGFyay1maXJlZmx5LTYifQ.rSmEPByOBQBwVUc2WjsyLbwf40E1rOCl9oApWsSrRYE';
// custom channel preview component
class MyChannelPreview extends React.Component {
render() {
const {setActiveChannel, channel} = this.props;
const unreadCount = channel.countUnread();
return (
<div className="channel_preview">
<a href="#" onClick={(e) => setActiveChannel(channel, e)}>
{channel.data.name}
</a>
<span>
Unread messages: {unreadCount}
</span>
</div>
);
}
}
// a very minimalistic message component
class MyMessageComponent extends React.Component {
render() {
return <div><b>{this.props.message.user.name}</b> {this.props.message.text}</div>;
}
}
chatClient.setUser(
{
id: 'dark-firefly-6',
name: 'Dark firefly',
image: 'https://getstream.io/random_png/?id=dark-firefly-6&name=Dark+firefly'
},
userToken,
);
const filters = { type: 'messaging', members: { $in: ['dark-firefly-6'] } };
const sort = { last_message_at: -1 };
const channels = chatClient.queryChannels(filters, sort);
const App = () => (
<Chat client={chatClient} theme={'messaging light'}>
<ChannelList
filters={filters}
sort={sort}
Preview={MyChannelPreview}
/>
<Channel Message={MyMessageComponent}>
<Window>
<ChannelHeader />
<MessageList />
<MessageInput />
</Window>
<Thread />
</Channel>
</Chat>
);
export default App;
The docs for the React Components are available here. If you are looking to build a more complex integration with Stream Chat, please look at our API docs here or try one of our other React tutorials.
Part 2: Live Stream Chat Example with React
Confused about something?
Let us know how we can improve:
Let us know how we can improve:
As a next exercise let's see how we can customize the above example to work well for a livestream.
Live Stream Chat
There are a few differences when building chat for a livestream:
- The user interface is typically more compact
- Typing as well as message seen/read states tend to get noisy
Have a look at the example below for building a livestream chat:
import React from 'react';
import { Chat, Channel, ChannelHeader, Window } from 'stream-chat-react';
import { MessageList, MessageInput, MessageLivestream } from 'stream-chat-react';
import { MessageInputSmall, Thread } from 'stream-chat-react';
import { StreamChat } from 'stream-chat';
import 'stream-chat-react/dist/css/index.css';
const chatClient = new StreamChat('gx5a64bj4ptz');
const userToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiZGFyay1maXJlZmx5LTYifQ.rSmEPByOBQBwVUc2WjsyLbwf40E1rOCl9oApWsSrRYE';
chatClient.setUser(
{
id: 'dark-firefly-6',
name: 'Dark firefly',
image: 'https://getstream.io/random_png/?id=dark-firefly-6&name=Dark+firefly'
},
userToken,
);
const channel = chatClient.channel('livestream', 'spacex', {
image: 'https://goo.gl/Zefkbx',
name: 'SpaceX launch discussion',
});
const App = () => (
<Chat client={chatClient} theme={'livestream dark'}>
<Channel channel={channel} Message={MessageLivestream}>
<Window hideOnThread>
<ChannelHeader live />
<MessageList />
<MessageInput Input={MessageInputSmall} focus />
</Window>
<Thread fullWidth />
</Channel>
</Chat>
);
export default App;
There are a few important differences compared to the first example:
- The theme is set to ‘livestream dark’ and is optimized for the compact layout next to a livestream.
- We're using the
livestream
chat type. This chat type disables typing and seen/read states. - The
MessageInputSmall
takes up less space. You can still use:emoticons:
and other rich text input features.
Custom Message and Attachment Types
The Chat API allows you to store custom data for users, messages, events, channels and attachments, allowing for a fully customized chat experience. Build chat exactly how you want.
As an example, let’s say that you want to attach a product to your message. We'll do this by supporting a custom product
message attachment:
import React from 'react';
import { Chat, Channel, Attachment } from 'stream-chat-react';
import { ChannelHeader, MessageList, Window } from 'stream-chat-react';
import { MessageInput, Thread } from 'stream-chat-react';
import { StreamChat } from 'stream-chat';
import 'stream-chat-react/dist/css/index.css';
const chatClient = new StreamChat('gx5a64bj4ptz');
const userToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiZGFyay1maXJlZmx5LTYifQ.rSmEPByOBQBwVUc2WjsyLbwf40E1rOCl9oApWsSrRYE';
class MyAttachmentComponent extends React.Component {
render() {
const { attachments } = this.props;
attachments.forEach(attachment => {
if (attachment.type === 'product') {
return (
<div className="product">
Product:
<a href={attachment.url} target="_blank">
<img src={attachment.image} height={'100px'} /><br />
{attachment.name}
</a>
</div>
);
}
})
return <div>testing<Attachment {...this.props} /></div>
}
}
chatClient.setUser(
{
id: 'dark-firefly-6',
name: 'Dark firefly',
image: 'https://getstream.io/random_png/?id=dark-firefly-6&name=Dark+firefly'
},
userToken,
);
const channel = chatClient.channel('messaging', 'godevs', {
// add as many custom fields as you like
image: 'https://cdn.chrisshort.net/testing-certificate-chains-in-go/GOPHER_MIC_DROP.png',
name: 'Talk about Go',
});
const attachments = [{
type: 'product',
name: 'iPhone',
url: 'https://goo.gl/ppFmcR',
image: 'https://goo.gl/J2gQpi',
}]
channel.sendMessage({
text: 'Your selected product is out of stock, would you like to select one of these alternatives?',
attachments: attachments,
});
const App = () => (
<Chat client={chatClient} theme={'messaging'}>
<Channel channel={channel} Attachment={MyAttachmentComponent}>
<Window>
<ChannelHeader />
<MessageList />
<MessageInput />
</Window>
<Thread />
</Channel>
</Chat>
)
export default App;
You could use a similar approach to embed any object from your site. Perhaps a livescore of a game, payments, location sharing or anything else you want to implement.
Final Thoughts
Confused about something?
Let us know how we can improve:
Let us know how we can improve:
We hope that you enjoyed this tutorial. By using Stream’s Chat Components, you and your team will be able to get your application, with chat, up and running in minutes.
Now that you’ve completed the tutorial on Stream Chat, you can build anything chat related with our components. If you need to build for other platforms, check out our react native chat or the iOS Swift Chat. If you have a use-case that doesn’t quite seem to work, or simply have questions, please don’t hesitate to reach out here.