💬 Gifted Chat
The most complete chat UI for React Native
demo
Coding Bootcamp in Paris co-founded by Farid Safi
Click to learn more
Scalable chat API/Server written in Go
API Tour | React Native Gifted tutorial
Features
react-native-web
able (since 0.10.0) web configuration- Write with TypeScript (since 0.8.0)
- Fully customizable components
- Composer actions (to attach photos, etc.)
- Load earlier messages
- Copy messages to clipboard
- Touchable links using react-native-parsed-text
- Avatar as user's initials
- Localized dates
- Multi-line TextInput
- InputToolbar avoiding keyboard
- Redux support
- System message
- Quick Reply messages (bot)
Versions notes
- Since v0.10.0 removed
react-native-video
dependency.
Dependency
- Use version
0.2.x
for RN >= 0.44.0
- Use version
0.1.x
for RN >= 0.40.0
- Use version
0.0.10
for RN < 0.40.0
Installation
- Using npm:
npm install react-native-gifted-chat --save
- Using Yarn:
yarn add react-native-gifted-chat
You have a question ?
- Please check this readme and may find a response
- Please ask on StackOverflow first: https://stackoverflow.com/questions/tagged/react-native-gifted-chat
- Find response on existing issues
- Try to keep issues for issues
Example
import React from 'react'
import { GiftedChat } from 'react-native-gifted-chat'
class Example extends React.Component {
state = {
messages: [],
}
componentWillMount() {
this.setState({
messages: [
{
_id: 1,
text: 'Hello developer',
createdAt: new Date(),
user: {
_id: 2,
name: 'React Native',
avatar: 'https://placeimg.com/140/140/any',
},
},
],
})
}
onSend(messages = []) {
this.setState(previousState => ({
messages: GiftedChat.append(previousState.messages, messages),
}))
}
render() {
return (
<GiftedChat
messages={this.state.messages}
onSend={messages => this.onSend(messages)}
user={{
_id: 1,
}}
/>
)
}
}
Advanced example
See App.js
for a working demo!
"Slack" example
See the files in example-slack-message
for an example of how to override the default UI to make something that looks more like Slack -- with usernames displayed and all messages on the left.
Message object
e.g. Chat Message
{
_id: 1,
text: 'My message',
createdAt: new Date(Date.UTC(2016, 5, 11, 17, 20, 0)),
user: {
_id: 2,
name: 'React Native',
avatar: 'https://facebook.github.io/react/img/logo_og.png',
},
image: 'https://facebook.github.io/react/img/logo_og.png',
video: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4',
}
e.g. System Message
{
_id: 1,
text: 'This is a system message',
createdAt: new Date(Date.UTC(2016, 5, 11, 17, 20, 0)),
system: true,
}
e.g. Chat Message with Quick Reply options
See PR #1211
interface Reply {
title: string
value: string
messageId?: any
}
interface QuickReplies {
type: 'radio' | 'checkbox'
values: Reply[]
keepIt?: boolean
}
{
_id: 1,
text: 'This is a quick reply. Do you love Gifted Chat? (radio) KEEP IT',
createdAt: new Date(),
quickReplies: {
type: 'radio',
keepIt: true,
values: [
{
title: '😋 Yes',
value: 'yes',
},
{
title: '📷 Yes, let me show you with a picture!',
value: 'yes_picture',
},
{
title: '😞 Nope. What?',
value: 'no',
},
],
},
user: {
_id: 2,
name: 'React Native',
},
},
{
_id: 2,
text: 'This is a quick reply. Do you love Gifted Chat? (checkbox)',
createdAt: new Date(),
quickReplies: {
type: 'checkbox',
values: [
{
title: 'Yes',
value: 'yes',
},
{
title: 'Yes, let me show you with a picture!',
value: 'yes_picture',
},
{
title: 'Nope. What?',
value: 'no',
},
],
},
user: {
_id: 2,
name: 'React Native',
},
}
Props
messages
(Array) - Messages to displaytext
(String) - Input text; default is undefined
, but if specified, it will override GiftedChat's internal state (e.g. for redux; see notes below)placeholder
(String) - Placeholder when text
is empty; default is 'Type a message...'
messageIdGenerator
(Function) - Generate an id for new messages. Defaults to UUID v4, generated by uuiduser
(Object) - User sending the messages: { _id, name, avatar }
onSend
(Function) - Callback when sending a messagealwaysShowSend
(Bool) - Always show send button in input text composer; default false
, show only when text input is not emptylocale
(String) - Locale to localize the datestimeFormat
(String) - Format to use for rendering times; default is 'LT'
dateFormat
(String) - Format to use for rendering dates; default is 'll'
isAnimated
(Bool) - Animates the view when the keyboard appearsloadEarlier
(Bool) - Enables the "Load earlier messages" buttononLoadEarlier
(Function) - Callback when loading earlier messagesisLoadingEarlier
(Bool) - Display an ActivityIndicator
when loading earlier messagesrenderLoading
(Function) - Render a loading view when initializingrenderLoadEarlier
(Function) - Custom "Load earlier messages" buttonrenderAvatar
(Function) - Custom message avatar; set to null
to not render any avatar for the messageshowUserAvatar
(Bool) - Whether to render an avatar for the current user; default is false
, only show avatars for other usersshowAvatarForEveryMessage
(Bool) - When false, avatars will only be displayed when a consecutive message is from the same user on the same day; default is false
onPressAvatar
(Function(user
)) - Callback when a message avatar is tappedonLongPressAvatar
(Function(user
)) - Callback when a message avatar is long-pressedrenderAvatarOnTop
(Bool) - Render the message avatar at the top of consecutive messages, rather than the bottom; default is false
renderBubble
(Function) - Custom message bubblerenderSystemMessage
(Function) - Custom system messageonLongPress
(Function(context
, message
)) - Callback when a message bubble is long-pressed; default is to show an ActionSheet with "Copy Text" (see example using showActionSheetWithOptions()
)inverted
(Bool) - Reverses display order of messages
; default is true
renderUsernameOnMessage
(Bool) - Indicate whether to show the user's username inside the message bubble; default is false
renderMessage
(Function) - Custom message containerrenderMessageText
(Function) - Custom message textrenderMessageImage
(Function) - Custom message imagerenderMessageVideo
(Function) - Custom message videoimageProps
(Object) - Extra props to be passed to the <Image>
component created by the default renderMessageImage
videoProps
(Object) - Extra props to be passed to the video component created by the required renderMessageVideo
lightboxProps
(Object) - Extra props to be passed to the MessageImage
's LightboxisCustomViewBottom
(Bool) - Determine wether renderCustomView is displayed before or after the text, image and video views; default is false
renderCustomView
(Function) - Custom view inside the bubblerenderDay
(Function) - Custom day above a messagerenderTime
(Function) - Custom time inside a messagerenderFooter
(Function) - Custom footer component on the ListView, e.g. 'User is typing...'
; see example/App.js for an examplerenderChatFooter
(Function) - Custom component to render below the MessageContainer (separate from the ListView)renderInputToolbar
(Function) - Custom message composer containerrenderComposer
(Function) - Custom text input message composerrenderActions
(Function) - Custom action button on the left of the message composerrenderSend
(Function) - Custom send button; you can pass children to the original Send
component quite easily, for example to use a custom icon (example)renderAccessory
(Function) - Custom second line of actions below the message composeronPressActionButton
(Function) - Callback when the Action button is pressed (if set, the default actionSheet
will not be used)bottomOffset
(Integer) - Distance of the chat from the bottom of the screen (e.g. useful if you display a tab bar)minInputToolbarHeight
(Integer) - Minimum height of the input toolbar; default is 44
listViewProps
(Object) - Extra props to be passed to the messages <ListView>
; some props can't be overridden, see the code in MessageContainer.render()
for detailstextInputProps
(Object) - Extra props to be passed to the <TextInput>
keyboardShouldPersistTaps
(Enum) - Determines whether the keyboard should stay visible after a tap; see <ScrollView>
docsonInputTextChanged
(Function) - Callback when the input text changesmaxInputLength
(Integer) - Max message composer TextInput lengthparsePatterns
(Function) - Custom parse patterns for react-native-parsed-text used to linkify message content (like URLs and phone numbers), e.g.:
<GiftedChat
parsePatterns={(linkStyle) => [
{ type: 'phone', style: linkStyle, onPress: this.onPressPhoneNumber },
{ pattern: /#(\w+)/, style: { ...linkStyle, styles.hashtag }, onPress: this.onPressHashtag },
]}
/>
extraData
(Object) - Extra props for re-rendering FlatList on demand. This will be useful for rendering footer etc.minComposerHeight
(Object) - Custom min height of the composer.maxComposerHeight
(Object) - Custom max height of the composer.
scrollToBottom
(Bool) - Enables the scrollToBottom Component (Default is false)scrollToBottomComponent
(Function) - Custom Scroll To Bottom Component containerscrollToBottomOffset
(Integer) - Custom Height Offset upon which to begin showing Scroll To Bottom Component (Default is 200)scrollToBottomStyle
(Object) - Custom style for Bottom Component containeralignTop
(Boolean) Controls whether or not the message bubbles appear at the top of the chat (Default is false - bubbles align to bottom)onQuickReply
(Function) - Callback when sending a quick reply (to backend server)renderQuickReplies
(Function) - Custom all quick reply viewquickReplyStyle
(StyleProp) - Custom quick reply view stylerenderQuickReplySend
(Function) - Custom quick reply send viewshouldUpdateMessage
(Function) - Lets the message component know when to update outside of normal cases.
Imperative methods
focusTextInput()
- Open the keyboard and focus the text input box
The messages
prop should work out-of-the-box with Redux. In most cases this is all you need.
If you decide to specify a text
prop, GiftedChat will no longer manage its own internal text
state and will defer entirely to your prop.
This is great for using a tool like Redux, but there's one extra step you'll need to take:
simply implement onInputTextChanged
to receive typing events and reset events (e.g. to clear the text onSend
):
<GiftedChat
text={customText}
onInputTextChanged={text => this.setCustomText(text)}
/>
Notes for Android
If you are using Create React Native App / Expo, no Android specific installation steps are required -- you can skip this section. Otherwise we recommend modifying your project configuration as follows.
-
Make sure you have android:windowSoftInputMode="adjustResize"
in your AndroidManifest.xml
:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:windowSoftInputMode="adjustResize"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
-
For Expo, there are at least 2 solutions to fix it:
-
If you plan to use GiftedChat
inside a Modal
, see #200.
Notes for local development
Native
- Install
yarn add -g expo-cli
expo start
react-native-web
With expo
- Install
yarn add -g expo-cli
expo start -w
With create-react-app
yarn add -D react-app-rewired
touch config-overrides.js
module.exports = function override(config, env) {
config.module.rules.push({
test: /\.js$/,
exclude: /node_modules[/\\](?!react-native-gifted-chat|react-native-lightbox|react-native-parsed-text)/,
use: {
loader: 'babel-loader',
options: {
babelrc: false,
configFile: false,
presets: [
['@babel/preset-env', { useBuiltIns: 'usage' }],
'@babel/preset-react',
],
plugins: ['@babel/plugin-proposal-class-properties'],
},
},
})
return config
}
Questions
License
Author
Feel free to ask me questions on Twitter @FaridSafi!
Contributors
Hire an expert!
Looking for a ReactNative freelance expert with more than 12 years experience? Contact Xavier from his website!