React UI Kit

How to Build an Airbnb Clone

Follow this tutorial step-by-step to build an Airbnb clone using React JS & Firebase.

Hiep Le • Mar 3, 2022

App and web development have come a long way over the last few years. We use a lot of aggregator business model apps every day such as AirBnb, Uber, Grab and so on. Using the React CometChat UI Kit, Firebase backend services, you will learn how to build the AirBnb clone.

Follow along the steps to build the AirBnb clone that will allow users:

1. User Login/Registration

  • A way for end-users to login and register

  • 2 user types - host and non-host

2. Home Page

  • Search bar

  • 3 tabs for Homes, experiences & Online experiences

  • Profile page

3. Chat

  • Each listing must have a button to ‘Contact Host’ which initiates a text chat.

  • Use the React UI Kit and select the right components.

  • Add inbox page (only conversations in the navigation tab).

  • Login the logged-in user to CometChat.

  • Add API call when a user registers so that the user is created in CometChat.

Prerequisites

To follow this tutorial, you must have a degree of understanding of the general use of React.js. This will help you to improve your understanding of this tutorial.

Installing the App Dependencies

Step 1: you need to have Node.js installed on your machine

Step 2: create a new project with the name airbnb by running the following statement.

Step 3: You need to copy the dependencies from here, and then run “npm install”

*Note: At this time of writing this tutorial, we are using the Firebase SDK with the version @8.9.1

Configuring CometChat SDK

  1. Head to CometChat Dashboard and create an account.

Register a new CometChat account if you do not have one

Register a new CometChat account if you do not have one

2. After registering a new account, you need to the log in to the CometChat dashboard.

Log in to the CometChat Dashboard with your created account

Log in to the CometChat Dashboard with your created account

3. From the dashboard, add a new app called "airbnb-clone".

Create a new CometChat app - Step 1

Create a new CometChat app - Step 1

Create a new CometChat app - Step 2

Create a new CometChat app - Step 2

4. Select this newly added app from the list.

Select your created app

Select your created app

5. From the Quick Start copy the APP_ID, REGION, and AUTH_KEY, which will be used later.

Copy the the APP_ID, REGION, and AUTH_KEY

Copy the the APP_ID, REGION, and AUTH_KEY

6. Navigate to the Users tab, and delete all the default users (very important).

Navigate to Users tab and delete all the default users

Navigate to Users tab and delete all the default users

7. Navigate to the Groups tab and delete all the default groups (very important).

Navigate to Group tab and delete all the default groups

Navigate to Group tab and delete all the default groups

8. Create a file called **.env** in the root folder of your project.

9. Import and inject your secret keys in the **.env** file containing your CometChat and Firebase in this manner.

10. Make sure to include **.env** in your gitIgnore file from being exposed online.

Setting Up the Firebase Project

According to the requirements of the Airbnb clone, you need to let users create a new account and login to the application, Firebase will be used to achieve that. Head to Firebase to create a new project and activate the email and password authentication service. This is how you do it:

To begin using Firebase, you’ll need a Gmail account. Head over to Firebase and create a new project.

Firebase

Firebase

Firebase provides support for authentication using different providers. For example, Social Auth, phone numbers, as well as the standard email and password method. Since you will be using the email and password authentication method in this tutorial, you need to enable this method for the project you created in Firebase, as it is by default disabled.

Under the authentication tab for your project, click the sign-in method and you should see a list of providers currently supported by Firebase.

Firebase Authentication

Firebase Authentication

Next, click the edit icon on the email/password provider and enable it.

Enable Firebase Authentication with Email and Password

Enable Firebase Authentication with Email and Password

Now, you need to go enable Firebase Realtime Database. We will Firebase Realtime Database to store the information of the users in the application. Please refer to the following part for more information.

Choose “Realtime Database” option

Choose “Realtime Database” option

Click on “Create Database

Click on “Create Database"

Select location where you realtime database will be stored

Select location where you realtime database will be stored

Select “Start in test mode” for the learning purpose

Select “Start in test mode” for the learning purpose

Please follow the guidance from Firebase. After following all steps, you will see the database URL. If you just need to update the “REACT_APP_FIREBASE_DATABASE_URL” variable in your .env file with that value.

Database Url

Database Url

On the other hand, your Firebase real-time database will be expired in the future. To update the rules you just need to select the “Rules” tab and update the date/time in milliseconds as you can see in the image below.

Database rules

Database rules

In this project, we also need to upload the house’s image. Therefore, we have to enable the Firebase Storage service, the Firebase Storage service helps us store the assets files including images, videos and so on. To enable the Firebase Storage service, please follow the below steps

Enable Firebase Storage Service

Enable Firebase Storage Service

 Click on the “Next” button

Click on the “Next” button

Click on the “Done” button

Click on the “Done” button

Update the rules

Update the rules

For the learning purposes, we need to update the rules of the Firebase Storage service. It means that everyone, who can access to the application, can upload to the Firebase storage.

Now, you need to go and register your application under your Firebase project. On the project’s overview page, select the add app option and pick web as the platform.

Firebase Dashboard

Firebase Dashboard

Once you’re done registering the application, you’ll be presented with a screen containing your application credentials.

Data Structure - User

Data Structure - User

The above image describes the data structure of the users. A user will contain the following information:

  • About: The introduction of the user.

  • Address: The user’s address.

  • Avatar: The user’s avatar.

  • Email: The user’s email.

  • Full-name: The user’s full name.

  • id: The user’s id.

  • Role: The user’s role - 0 is a normal user, 1 is a host.

  • Work: The user’s job.

In this application, the hosts can upload the houses. For this reason, we need to store the houses on the Firebase Realtime Database. The below image describes the data structure of the houses.

s becfabeefaaaedefacadcb screenbshotb batb

Data Structure - Houses

  • Address: the house’s address.

  • CreatedBy: the user’s id whose created the house.

  • Description: the house’s description.

  • id: the house’s id.

  • Image: the house’s image.

  • Name: the house’s name.

  • Price: the house’s price. ($/night).

Configuring Styling for the Application

Inside your project structure, open the index.css files and paste the codes here. index.css file will contain all CSS of the application.

Configuring Constants for the Application

We need to define a folder which is called “constants”. The constants folder contains all of the constants that are used in the application such as the firebase keys, the local storage keys, the routes. Please create the “constants” folder inside the “src” folder, and create the “firebase-keys.js” file, “storage-keys.js” file, the “routes.js” file. You can get the content of those files from here.

Creating React Context

In this application, we need to pass some data between the components. We can have several options to achieve that such as using state management libraries, RxJS, and so on. However, we can get in-built support from React by using the React Context API. the React Context API helps us pass data through the component tree without passing down at every level. Please create the “context” folder inside the “src” folder, and then create the “AppContext.js” file inside it. The full source code of the “AppContext.js” file can be found here.

  • user: it is used to store the authenticated information.

  • cometChat: it is used to store the CometChat instance.

Initializing CometChat for the Application

The below codes initialize CometChat in your app before it spins up. The AppContext.js file uses your CometChat API Credentials. We will get CometChat API Credentials from the .env file. Please do not share your secret keys on GitHub.

Configuring the Firebase File

You need to create a “firebase.js” file inside the “src” folder and you need to enable Firebase realtime database. This file is responsible for interfacing with Firebase authentication and database services. Also, it makes ready our email/password authentication service provider enabling us to sign in with google. Secret keys will be stored in the .env file. As mentioned above, please do not share your secret keys on GitHub. Please create the “firebase.js” file inside “src” folder. The full source code can be found here.

Creating Services

We should follow the DRY principle in our code. DRY stands for “do not repeat yourself”. It means that we should not duplicate the business logic. To avoid duplication in our code, we need to create some service files. Each file contains some methods that will be used to handle an individual aspect in our application, for example, showing the notification, creating the CometChat group, inserting the data to the Firebase Realtime Database service, and so on. Please create the “services” folder inside the “src” folder. Inside the “services” folder, please create the below files. For the content of each file, you can find here.

cometchat.js: Handles actions related to CometChat services.

firebase.js: Handles actions related to Firebase services.

route.js: Handles actions related to navigating between pages, routing.

storage.js: Handles actions related to the local storage.

ui.js: Handles actions related to the UI such as showing the notification, showing/hiding the loading indicator.

Project Structure

The image below reveals the project structure. Make sure you see the folder arrangement before proceeding.

Project Structure

Project Structure

Now, let's make the rest of the project components as seen in the image above.

The App.js File

The App.js file is responsible for rendering different components by the given routes. For example, it will render the login page if the user has not logged in, yet or it renders the home page if the user has signed in to the system. The full source code of the App.js file can be found here.

The Loading Component

The Loading Component

The Loading Component

The loading component will be shown when the system performs some side effects such as interacting with Firebase or calling CometChat APIs, and so on. This component will be used to increase user experience. If we do not have this component, the end-users cannot know when the data is loaded successfully. Please create the “components” folder inside the “src” folder, and create the “common” folder inside it. The “common” folder is used to store the common components that will be used in different places in your application. After that, you need to create the “Loading.js” file inside the “common” folder. The full source code of the loading component can be found here.

The Login Component

The Login Component

The Login Component

This component is responsible for authenticating our users using the Firebase authentication service. It accepts the user credentials and either signs him up or in, depending on if he is new to our application. See the code below and observe how our app interacts with Firebase and the CometChat SDK. Please create the “login” folder inside the “components” folder, and create the “Login.js” file inside the “login” folder. The full source code can be found here.

The above code indicates that we are using withModal as a higher-order component. This higher-order component will be used to reuse the code of showing and hiding the custom modal. In this case, we want to show the sign-up modal to let end-users register new accounts. We will discuss the sign-up component in the following section.

We store the authenticated Information to the local storage for further usage such as getting that information in different places in the application, prevent the end-users come back to the login page after signing in to the application.

To login to the CometChat, we call the login function from the “cometchat.js” file, you can refer to the below code snippet for more information.

The withModal - Higher-Order Component

As mentioned above, we would like to show the SignUp component as a modal. Actually, we have multiple modals in the application, and we should avoid duplicating common functionalities such as showing/hiding the modals, and so on. To reuse the common logic, we can have several options. In this project, we will create a higher-order component called “withModal”. That higher-oder component helps us to avoid duplicating code and we can customize the UI for the modals. Please follow the below code snippet for more information. Please create the “Modal.js” file inside the common folder. The full source code can be found here.

The Sign Up Component

The SignUp Component

The SignUp Component

The sign-up component will help end-users to register new accounts. This component will do two things. The first thing is to register new accounts on Firebase by using the Firebase authentication service. Aside from that, it also registers new accounts on CometChat by using the CometChat SDK. Please create the “register” folder inside the “components” folder, and create the “SignUp.js” file inside it. The full source code can be found here.

To create a new CometChat account, we call createAccount function from the “cometchat.js” file. You can refer to the below code snippet below for more information.

Add the CometChat UI to Our Application

Before we can use the CometChat Pro React UI kit, we need to add it in our project so that we can reference it. In this case, we are using React UI Kit v3.0. To do that, follow the next steps:

Step 1: Clone the CometChat React UI Kit Repository like so:

Step 2: Copy the folder of the CometChat Pro React UI Kit you just cloned into the src folder of your project:

Project Structure

Project Structure

React UI Kit Dependencies

React UI Kit Dependencies

Step 3: Copy all the dependencies from the package.json file of the CometChat Pro React UI Kit folder and paste them in the dependencies section of the package.json file of your project.

Step 4: Save the file and install the dependencies like so: npm install

As soon as the installation is completed, you now have access to all the React UI Components. The React UI kit contains different chat UI components for different purposes as you can see in the documentation here. It includes:

1. CometChatUI

2. CometChatUserListWithMessages

3. CometChatGroupListWithMessages

4. CometChatConversationListWithMessages

5. CometChatMessages

6. CometChatUserList

7. CometChatGroupList

8. CometChatConversationList

The Private Route Component

We need to have some private routes in our application. It means that the end-users cannot access those routes if they have not logged in to the application. To achieve that, we need to create the PrivateRoute component. The PrivateRoute component will check the authenticated information in the local storage, if the information is existing in the local storage, the users can access the private routes, and vice versa. Please create the “PrivateRoute.js” file inside the “common” folder. The full source code can be found here.

The Header Component

The Header Component

The Header Component

The Header component is used to display the app’s icon, the user’s avatar, the greeting, some menu items and the log out button. The full source code of the Header component can be found here.

The Logout Feature

The Logout Feature

The Logout Feature

After clicking the log out button, a confirm dialog will be displayed to ask the end-users whether they want to sign out from the application. To handle the logout process, the following steps will be executed:

  • Call the logout function of CometChat.

  • Remove the authenticated information from the global state, and the local storage.

  • Redirect the end-users to the log in page.

Please refer to the below code snippet for more information.

The Create Component

The Create Component

The Create Component

After the users click on the “Create” item on the header component, the Create component will be displayed as a modal. According to the above image, the users can choose the house’s image, and then input the house’s information including the house’s name, the house’s price, and the house’s description. In this case, we apply validation to validate the form such the the house’s price must be number, and other fields must be required.

After the users click on the “Create” button, the application will upload the house’s image, and insert the house’s information to the Firebase Realtime Database service. Please create the “create” folder inside the “components” folder, and then create the “Create.js” file inside it. The full source code can be found here.

The Home Component

The Home Component

The Home Component

The home component will take the responsibility for rendering the background image, and some text to make our UI be more attractive, we do not have the business logic that needs to be handled here. Please create the “home” folder inside the “components” folder, and create the “Home.js” file inside it. The full source code can be found here.

The Search Component

The Search Component

The Search Component

The users can type the keywords on the search box, and then click on the “Search” button. The keyword will be saved to the local storage, the users will be redirected to the search result page. The search result page will be used to display the list of houses that are matched to the keywords. We discuss it in the following section. Please create the “search” folder inside the “components” folder, and then create the “Search.js” file inside it. The full source code can be found here.

The Search Results Component

The Search Results Component

The Search Results Component

The search result component will get the keywords from the local storage, and then query the list of houses from the Firebase Realtime Database service, the Firebase service should return the list of houses that the address of each house should equaled to the keywords. After getting the houses, the search result component will pass them to the Houses component. The Houses component will be discussed in the following section.Please create the “SearchResults.js” file inside the “search” folder. The full source code can be found here.

The Houses Component

The Houses Component

The Houses Component

As mentioned above, the Home component will get the list of houses from the Firebase Realtime Database service, and then pass the response to the Houses component via props. For this reason, the Houses component will be used to render the houses in the application. Each item in the list will be rendered by using the House component. We will talk about the House component in the following section. Please create the “houses” folder inside the “components” folder, and create the “Houses.js” file inside it. The full source code can be found here.

The House Component

The House Component

The House Component

Each house in the list will be rendered by using the House component, in the Houses component, we will display the list of houses by using the map function, and then pass each item to the House component via props. Please create the “house.js” file inside the “houses” folder. The full source code can be found here.

The HouseDetail Component

The HouseDetail Component

The HouseDetail Component

After clicking on any item on the house list, the house information will be saved to the local storage. The house detail component will be shown. Inside the house detail component, we get the selected house information from the local storage and then display that information on the screen. On the other hand, the users can book the house, or they can chat with the host.

Please create the “detail” folder inside the “components” folder, and then create the “HouseDetail.js” file inside it. The full source code can be found here.

As we can see from the above code snippet, inside the house detail component, we use many other components, and they are house detail name component, house detail sub-component, house detail images component, house detail description component, house detail form component. All of them will be discussed here.

The House Detail Name Component

The House Detail Name Component

The House Detail Name Component

The house detail name component is used to display the name of the house. It will receive the house information as props. Please create the “HouseDetailName.js” file inside the “detail” folder. The full source code can be found here.

The House Detail Sub Component

The House Detail Sub Component

The House Detail Sub Component

The house detail sub component is used to display the rating and the address of the house. It will receive the house information as props. Please create the “HouseDetailSub.js” file inside the “detail” folder. The full source code can be found here.

The House Detail Images Component

The House Detail Images Component

The House Detail Images Component

The house detail images component is used to display the images of the house. It will receive the house information as props. Please create the “HouseDetailImages.js” file inside the “detail” folder. The full source code can be found here.

The House Detail Description Component

The House Detail Description Component

The House Detail Description Component

The house detail description component is used to display the description of the house. It will receive the house information as props. Please create the “HouseDetailDescription.js” file inside the “detail” folder. The full source code can be found here.

The House Detail Form Component

The House Detail Form Component

The House Detail Form Component

The house detail form component is used to display the price and the rating of the house. On the other hand, it contains two buttons - the book button and the chat with host button. If the users click on the book button, they can book the house. Following that, if the users click on the chat with host button, they can chat with the owner of the house. It will receive the house information as props. Please create the “HouseDetailForm.js” file inside the “detail” folder. The full source code can be found here.

The Profile Component

The Profile Component

The Profile Component

As mentioned in the above image, we can view the profile by clicking on the greeting of the header. The profile information will be saved to the local storage, and the profile component will get that information from the local storage. Please create the “profile” folder inside the “components” folder, and create the “Profile.js” file inside it. The full source code can be found here.

As we can see from the above code snippet, the Profile component uses many other components to display the information on the screen, and they are the profile left component, the profile intro component, the profile houses component. All of them will be discussed here.

The Profile Left Component

The Profile Left Component

The Profile Left Component

The profile left component is used to display the user’s avatar, the badges, and some verified information. Please create the “ProfileLeft.js” file inside the “profile” component. The full source code can be found here.

The Profile Intro Component

The Profile Intro Component

The Profile Intro Component

The profile intro component is used to display the introduction of the user as you can see from the above image. Please create the “ProfileIntro.js” file inside the “profile” folder. The full source code can be found here.

The Profile Houses Component

The Profile Houses Component

The Profile Houses Component

We need to display the list of houses that were created by the authenticated user. The houses component will take the responsibility to do that. It will interact with the Firebase Realtime Database service to get the houses of the authenticated user. After that, it will show the response by using the map function, each house will be passed to the profile house component for displaying. The profile house component will be discusses in the following section. Please create the “ProfileHouses.js” file inside the “profile” folder. The full source code can be found here.

The Profile House Component

The Profile House Component

The Profile House Component

As mentioned above, each house will be rendered by using the profile house component. The profile house component will accept the house information as props. Please create the “ProfileHouse.js” file inside the “profile” folder. The full source code can be found here.

The Chat Component

The Chat Component

The Chat Component

In this application, the users can chat with others. For this reason, if the users click on the “chat” item on the header, the users will be redirected to the chat page. In the Chat component, we use the CometChatUI component from the CometChat UI Kit. Please create the “chat” folder inside the “components” folder, and create the “Chat.js” file inside it. The full source code can be found here.

The Chat With Host Component

The Chat With Host Component

The Chat With Host Component

On the house detail page, the users can click on the “Chat with Host” button. After clicking on that button, the users will be redirected to the chat with host page. The host here is the person who uploaded the house for renting. In this ChatWithHost component, we use the CometChatMessages from the CometChat UI Kit and pass the seller id to the chatWithUser prop. Please create the “ChatWithHost.js” file inside the “chat” component. The full source code can be found here.

Wrapping Up

In conclusion, we have done an amazing job in developing a Airbnb clone by leveraging React.js, Firebase, CometChat SDK, and React UI Kit. You’ve been introduced to the chemistry behind Airbnb and how the CometChat SDK makes the Airbnb clone buildable.

You have seen how to build most of the chat functionalities such as real-time messaging using CometChat. I hope you enjoyed this tutorial and that you were able to successfully add mentions into your React chat app. Jump into the comments and let me know your experience.

About the Author

Hiep Le is a software engineer. He takes a huge interest in building software products and is a full-time software engineer. Most of his work is focused on one thing - to help people learn.

Hiep Le

CometChat

Hiep Le is a software engineer. He takes a huge interest in building software products and is a full-time software engineer. Most of his work is focused on one thing - to help people learn.

Try out CometChat in action

Experience CometChat's messaging with this interactive demo built with CometChat's UI kits and SDKs.