Navigate back to the homepage
Browse Repo

Building a Twitter Sidebar Clone with Material-UI and React

Taminoturoko Briggs
August 28th, 2021 · 9 min read

Material-UI is an open-source React component library for building responsive UI applications. It’s a reliable component library that provides React components that can be easily customized to meet our UI development needs. Material-UI is based on Google’s Material Design, providing a high-quality digital experience while developing front-end applications.

Benefits of using Material-UI

  • Well-designed responsive components, helping you to focus more on business logic.
  • A large community and properly written document.
  • Design consistency
  • Faster development with ready-made components.

These are just some of the benefits of using Material-UI.

Material-UI also has some drawbacks like:

  • Missing components.
  • Also, it’s not intuitive to use.

Material-UI usage

To get started with Material-UI, you have to first install the npm package. You can do that with this command:

1// with npm
2$ npm install @material-ui/core
4// with yarn
5$ yarn add @material-ui/core

After installation, to start using the components all you have to do is import them. Here is a quick example of how you can use the Button components.

1import Button from '@material-ui/core/Button';
3function App() {
4 return (
5 <Button>
6 Hello World
7 </Button>
8 );

This is really all you need to start using Material UI.

Here are some use cases for Material UI.

  • Icons — There are over 1,100+ React material icons ready to use from the official site. There is also an option to change the looks of these icons to be either Filled, Outlined, Rounded, etc. null
1import AddShoppingCartIcon from '@material-ui/icons/AddShoppingCart'
2import AddAPhotoOutlinedIcon from '@material-ui/icons/AddAPhotoOutlined'
3import HomeRoundedIcon from '@material-ui/icons/HomeRounded'
4import ContactMailTwoToneIcon from '@material-ui/icons/ContactMailTwoTone'
5import MailSharpIcon from '@material-ui/icons/MailSharp'
7function App(){
8 return (
9 <div style={{display: 'flex', justifyContent: 'space-evenly', marginTop: 70}}>
10 <AddShoppingCartIcon fontSize="large"/>
11 <AddAPhotoOutlinedIcon fontSize="large"/>
12 <HomeRoundedIcon fontSize="large"/>
13 <ContactMailTwoToneIcon fontSize="large"/>
14 <MailSharpIcon fontSize="large"/>
15 </div>
17 )

Here, we imported the Icons from the material-ui icon package then rendered them in the App component. We also passed a fontSize prop to the icons with a value “large”, which will make the icons large. This is one of the props that can be used to customize the icons. You can take a look at others in the Icon API docs.

Note: Before using Material-UI icons, you have to install the icon package which is @material-ui/icons.

  • Grid systems — With Material UI Grid component, you can create responsive grid layouts. null
1import Grid from '@material-ui/core/Grid'
2import Paper from '@material-ui/core/Paper'
4function App() {
5 return (
6 <Grid container style={{width: '90%', margin: '0 auto'}}>
7 <Grid item xs={12}>
8 <Paper style={{height: 100, margin: 10}}></Paper>
9 </Grid>
10 <Grid item xs={6}>
11 <Paper style={{height: 100, margin: 10}}></Paper>
12 </Grid>
13 <Grid item xs={6}>
14 <Paper style={{height: 100, margin: 10}}></Paper>
15 </Grid>
16 </Grid>
17 );

At the top of the code, we imported the Grid component from the material-ui package, we also imported a Paper component which adds a nice box-shadow to the Grid. The Grid component behaves like a CSS flexbox. In the first Grid component we rendered, we passed a prop called container, this makes it have a flex container behaviour, it defines a flex context for all its direct children. Then, in the other Grid’s which are under the container Grid, we passed an item prop to them, this gives them a flex item behaviour, we also passed an xs prop which defines the number of grid space the component will use for very small screen and also wider screen if not handled. The highest number of grids is 12 which means the Grid component we passed an xs prop of 12 to will occupy the entire screen width. There are also other props that can be used to target other screen sizes like xl for very large screens, md for middle screens, etc. You can take a look at the others in the Grid API docs.

  • Navigations — Material-UI has different navigation components that you can utilize to meet your navigation requirements, like Bottom Navigation, Breadcrumb, etc. Here is an example of how to use the Bottom Navigation component.


1import {useState} from 'react'
2import BottomNavigation from '@material-ui/core/BottomNavigation'
3import BottomNavigationAction from '@material-ui/core/BottomNavigationAction'
4import FolderIcon from '@material-ui/icons/Folder'
5import RestoreIcon from '@material-ui/icons/Restore'
6import FavoriteIcon from '@material-ui/icons/Favorite'
7import LocationOnIcon from '@material-ui/icons/LocationOn'
9function App() {
10 const [value, setValue] = useState('recents')
11 const handleChange = (event, newValue) => {
12 setValue(newValue)
13 }
14 return (
15 <BottomNavigation value={value} onChange={handleChange} style={{width: 500, margin: '70px auto'}}>
16 <BottomNavigationAction label="Recents" value="recents" icon={<RestoreIcon />} />
17 <BottomNavigationAction label="Favorites" value="favorites" icon={<FavoriteIcon />} />
18 <BottomNavigationAction label="Nearby" value="nearby" icon={<LocationOnIcon />} />
19 <BottomNavigationAction label="Folder" value="folder" icon={<FolderIcon />} />
20 </BottomNavigation>
21 )

To create Bottom navigation that displays a nice animation when clicked, this is literally all you have to do. In the above code what we did majorly was setting an initial value to the state, we defined a handleChange function that is responsible for changing the state when it is called, we rendered the ButtomNavigation component passing it a value prop which holds the current value of the state, we also passed an onChange event which calls the handleChange function, Finally, we used the BottomNavigationAction component to display action for the Bottom Navigation.

Exploring Material-UI

Using Material-UI to meet your UI needs can really save a lot of time while developing an application. In the previous section, we have seen some cool components that Material-UI provides but that isn’t all, Material-UI has a lot more. Also, there are API references for each Material-UI component which can be a big help when making use of them. In this section, we will cover all of this and we will also cover Material-UI styles.

Material-UI component

Material-UI components are divided into eight(8) categories. Here is a list of the categories and the most common of their components:

  • Layout — Container, Grid, Box, Image List, etc.
  • Inputs — Button, Checkbox, Radio, Text Field, etc.
  • Navigation — Button Navigation, Breadcrumbs, Drawer, Link Menu, etc.
  • Surfaces — App Bar, Paper, Card, Accordion.
  • Feedback — Progress, Dialog, Snackbar, Backdrop.
  • Data Display — Avatar, Badge, Chip, Divider, Icons, Material Icons, etc.
  • Utils — CSS Baseline, Modal, Click Away Listener, Portal, etc.
  • Lab — Alert, Autocomplete, Pagination, Speed Dail, etc.

To view the list of all the components Material-UI provides, go to the Material-UI official site, click on the menu icon, and in the sidebar click on Components.

Material-UI component API

The component API provides detailed documentation of the props and CSS customization points for Material-UI components.

You will find the component API section in the sidebar of Material-UI’s official site.

Material-UI styles

Material-UI styles provide an alternative means of styling components, whether or not you are using Material-UI components. It’s not compulsory to use Material-UI’s styling solution since it is interoperable with all the major styling solutions. There are three APIs you can use to generate and apply Material UI styles, they are:

  • Hook API
  • Styled components API
  • Higher-order components API

You can read about these APIs and how to get started with them in Material-UI docs

At this point, you know what Material-UI is, its benefits, and more. Now let’s build something with it. In the following sections, we will build a Twitter sidebar clone, utilizing Material Icons and button components.

Getting started

First, let’s create a new React app and also Install the dependencies for our application.

Creating and setting up React

Type the following command in your terminal to create a new React app

1$ npx create-react-app twitter_sidebar

Here our app’s name is twitter_sidebar, but you can give it any name you want as long as it’s not a restricted npm name. After the installation is complete, in the src directory of the twitter_sidebar app delete (optional) the following files:

  • App.test.js
  • logo.svg
  • setupTests.js

We deleted these files because they are not relevant to us in our project.

That’s not all, clean up the App.js file and let what is left look like this:


1import "./App.css";
3function App() {
4 return (
6 );
8export default App;

Now that we have set up our React app, let’s install the dependencies for our app.

Installing dependencies

In the terminal, make sure you are in the the twitter_sidebar directory, then type in the following command to install the dependencies for our app.

1// with npm
2$ npm install @material-ui/core @material-ui/icons
4// with yarn
5$ yarn add @material-ui/core @material-ui/icons

These are the dependencies we need to build Twitter sidebar clone.

Open Source Session Replay

Debugging a web application in production may be challenging and time-consuming. OpenReplay is an Open-source alternative to FullStory, LogRocket and Hotjar. It allows you to monitor and replay everything your users do and shows how your app behaves for every issue. It’s like having your browser’s inspector open while looking over your user’s shoulder. OpenReplay is the only open-source alternative currently available.


Happy debugging, for modern frontend teams - Start monitoring your web app for free.

Building Twitter sidebar clone

This is what we are going to build in this section.


On the main Twitter sidebar, when you click on the More button, you will see a menu just like the one in our second image. We are going to be building that too. There are a few Twitter icons Material-UI does not have. For does we will improvise with other Material-UI icons. without further ado, let’s begin.

Building Sidebar component

In the src directory, create a Sidebar.js file and add the following lines of code:


1import "./sidebar.css";
2import SidebarLink from "./SidebarLink";
4function Sidebar(){
5 return(
6 <div className="sidebar">
7 <SidebarLink text="Home" />
8 <SidebarLink text="Explore" />
9 <SidebarLink text="Notifications" />
10 <SidebarLink text="Messages" />
11 <SidebarLink text="Bookmarks" />
12 <SidebarLink text="Lists" />
13 <SidebarLink text="Profile" />
14 <SidebarLink text="More" />
15 </div>
16 );
19export default Sidebar;

The SidebarLink component we used represents the options present in the Twitter sidebar clone. We will create this component shortly. But first, let’s add the styling for our Sidebar component. In the src directory, create a sidebar.css file and add the following CSS style:


2 width: 250px;
3 min-width: 250px;
4 padding: 20px 20px;
5 margin: 20px auto 0 auto;
6 box-shadow: 0 0 6px hsl(210 14% 90%);

Now, let’s create the SidebarLink component. In the src directory, create a SidebarLink.js file and add the following lines of code:


1import "./sidebarLink.css";
3function SidebarLink({ text }) {
4 return(
5 <div className="link" >
6 <h2>{text}</h2>
7 </div>
8 );
10export default SidebarLink;

Let’s add some styling for this component. In the src directory, create a sidebarLink.css file and add the following style:

2 display: flex;
3 align-items: cover;
4 cursor: pointer;
5 border-radius: 30px;
8 background-color: #e8f5fe;
9 color: #50b7f5;
10 transition: color 100ms ease-out;
11} > h2{
13 font-weight: 700;
14 font-size: 20px;
15 margin-right: 20px;

Let’s see how far we have gone in building the Twitter sidebar clone. But first, we need to render the Sidebar component. Open the App.js file and add the Sidebar component to the return statements. The App.js file should now look like this:


1import "./App.css"
2import Sidebar from "./Sidebar"
4function App() {
5 return (
6 <Sidebar/>
7 );
10export default App

Run the development server and open this link: http://localhost:3000/, you will see a screen like this:


It’s not yet looking like the Twitter sidebar clone we want to build. Some things are missing, like the icons and button. We will use Material-UI components to handle that.

Using Material-UI components

We have already installed the dependencies needed to use Material-UI in our app, what we need to do now is to import the needed components and start using them. First, let’s add the icons. In the Sidebar.js file import the icons from Material-UI like this:


2import HomeIcon from "@material-ui/icons/Home";
3import SearchIcon from "@material-ui/icons/Search";
4import NotificationsNoneIcon from "@material-ui/icons/NotificationsNone";
5import MailOutlineIcon from "@material-ui/icons/MailOutline";
6import BookmarkBorderIcon from "@material-ui/icons/BookmarkBorder";
7import ListAltIcon from "@material-ui/icons/ListAlt";
8import PermIdentityIcon from "@material-ui/icons/PermIdentity";
9import MoreHorizIcon from "@material-ui/icons/MoreHoriz";

Then, pass the icon components as props to SidebarLink like this:


2 <SidebarLink text="Home" Icon={HomeIcon} />
3 <SidebarLink text="Explore" Icon={SearchIcon} />
4 <SidebarLink text="Notifications" Icon={NotificationsNoneIcon} />
5 <SidebarLink text="Messages" Icon={MailOutlineIcon} />
6 <SidebarLink text="Bookmarks" Icon={BookmarkBorderIcon} />
7 <SidebarLink text="Lists" Icon={ListAltIcon} />
8 <SidebarLink text="Profile" Icon={PermIdentityIcon} />
9 <SidebarLink text="More" Icon={MoreHorizIcon}/>

Now we need to destructure the icons component from the SidebarLink props and also add it to the <div> element. In the SidebarLink.js file, modify the SidebarLink component to look like this:


2function SidebarLink({ text, Icon }) {
3 return(
4 <div className="link">
5 <Icon />
6 <h2>{text}</h2>
7 </div>
8 );

Let’s add some styling for the icons. In the sidebarLink.css file, add the following CSS style:

src/sidebarLink.css > .MuiSvgIcon-root {
2 padding: 20px;

In our CSS, we styled the .MuiSvgIcon-root class name, this is how you style the root element of the Material UI icon component. You will see all the CSS customization points for the icons in the Material-UI SvgIcon API documentation.

Now if you start the development server and open the app, it should look like this:


We have successfully added the icons, now what is left is to add the button. In the Sidebar.js file import the Button component from Material-UI as follows:


2import { Button } from "@material-ui/core";

Now, include the Button component before the ending of the <div> element of the Sidebar component like this:


2<Button id="tweet">
3 Tweet

Here, we gave the button and id of “tweet”. You might be wondering why we used an id instead of a class name. That’s because id have higher specificity than class, so styling we give the Button will override the style already given to the Button.


1function Sidebar(){
2 return(
3 <div className="sidebar">
4 <SidebarLink text="Home" active={true} Icon={HomeIcon} />
5 <SidebarLink text="Explore" Icon={SearchIcon} />
6 <SidebarLink text="Notifications" Icon={NotificationsNoneIcon} />
7 <SidebarLink text="Messages" Icon={MailOutlineIcon} />
8 <SidebarLink text="Bookmarks" Icon={BookmarkBorderIcon} />
9 <SidebarLink text="Lists" Icon={ListAltIcon} />
10 <SidebarLink text="Profile" Icon={PermIdentityIcon} />
11 <SidebarLink text="More" Icon={MoreHorizIcon}/>
12 <Button id="tweet">
13 Tweet
14 </Button>
15 </div>
16 );

Let’s add some styling to make the Button component look nice. In the sidebar.css file add the following lines of code:


2 width: 100%;
3 height: 50px;
4 background-color: hsl(203, 89%, 64%);
5 border-radius: 20px;
6 color: white;
7 font-weight: 700;
8 text-transform: inherit;

Now our Twitter sidebar clone looks like this:


If you click on the Tweet button, you will see a nice animation that displays from the point in the button you clicked. This is one cool feature Material-UI adds to all its clickable components.

Now let’s add the feature where when you click on the More button a menu will appear. For that, we are going to use Material-UI’s Menu component. Open the Sidebar.js file and add the following imports:


2import {useState} from 'react'
3import Menu from '@material-ui/core/Menu';
4import MenuItem from '@material-ui/core/MenuItem';

These are what we need to start using the Menu component. We also need to import the Icons we are going to use for the menu. Add the following imports to the Sidebar.js file:


2import BookmarkBorderOutlinedIcon from '@material-ui/icons/BookmarkBorderOutlined';
3import ListAltOutlinedIcon from '@material-ui/icons/ListAltOutlined';
4import ChatOutlinedIcon from '@material-ui/icons/ChatOutlined';
5import OfflineBoltOutlinedIcon from '@material-ui/icons/OfflineBoltOutlined';
6import PostAddOutlinedIcon from '@material-ui/icons/PostAddOutlined';
7import CallMadeOutlinedIcon from '@material-ui/icons/CallMadeOutlined';
8import BarChartOutlinedIcon from '@material-ui/icons/BarChartOutlined';
9import SettingsOutlinedIcon from '@material-ui/icons/SettingsOutlined';
10import HelpOutlineOutlinedIcon from '@material-ui/icons/HelpOutlineOutlined';
11import BrushOutlinedIcon from '@material-ui/icons/BrushOutlined';
12import AccessibilityNewOutlinedIcon from '@material-ui/icons/AccessibilityNewOutlined';

Now that we have imported the Menu component, we need to render it in the Sidebar component. Add this code before the ending of the <div> element in the return statement of the Sidebar component:


3 id="long-menu"
4 open={open}
5 onClose={handleClose}

We passed an id of “long-menu”, an open prop with a variable open. If this variable is equal to true the menu will be open, otherwise, it wont’t. We also passed an onClose prop which calls a handleClose function, this function will be responsible for closing the Menu. First, let’s create the open variable. This variable will reside in the state, which means we have to create a state for the Sidebar component. We will do that using the useState hook which we imported earlier.

Add this line of code at the beginning of the Sidebar component:


2const [open, setOpen] = useState(false);

Now, let’s create the handleClose function. Add the following lines after the state we just created:


2const handleClose = () => {
3 setOpen(false);

Now, let’s make it possible that when More is clicked on our Twitter sidebar clone it will display the Material-UI Menu. For that, we need to change the More link to a Button then add an onClick event to it.

In the Sidebar component, replace the the SidebarLink which has text prop equal to “More” with this:


2<Button onClick={handleClick} id="moreLinks">
3 <MoreHorizIcon/> More

The onClick event calls a handleClick function that will be responsible for changing the state to true. Let’s create the handleClick function. Add the following lines of code under the useState hook of Sidebar component:


2const handleClick = (event) => {
3 setOpen(true);

The More button on our Twitter sidebar clone now works, but if you click on it now you won’t see anything. This is because we haven’t added the menu links. Let’s do that now. At the beginning of the Sidebar component, add the following line of code:


2const options = [
3 { link: 'Bookmarks', icon: <BookmarkBorderOutlinedIcon fontSiz0px/> },
4 { link: 'List', icon: <ListAltOutlinedIcon/> },
5 { link: 'Topic', icon: <ChatOutlinedIcon/> },
6 { link: 'Moments', icon: <OfflineBoltOutlinedIcon/> },
7 { link: 'Newsletters', icon: <PostAddOutlinedIcon/> },
8 { link: 'Twitter Ads', icon: <CallMadeOutlinedIcon/> },
9 { link: 'Analytics', icon: <BarChartOutlinedIcon/> },
10 { link: 'Settings', icon: <SettingsOutlinedIcon/> },
11 { link: 'Help Center', icon: <HelpOutlineOutlinedIcon/> },
12 { link: 'Display', icon: <BrushOutlinedIcon/> },
13 { link: 'Keyboard shortcuts', icon: <AccessibilityNewOutlinedIcon/> },
15 ];

This is an Array of the links and icons present in the menu. All we have to do now is to iterate through it and display it within the Material-UI Menu component. We are going to use JavaScript’s map function to loop through it, then we will use the MenuItem component we imported earlier to display it with the Menu.

Add the following lines of code within the Menu:


2{ => (
3 <MenuItem key={} onClick={handleClose}>
4 {option.icon} {}
5 </MenuItem>

The Sidebar component now looks like this:


2function Sidebar(){
3 const options = [
4 { link: 'Bookmarks', icon: <BookmarkBorderOutlinedIcon fontSiz0px/> },
5 { link: 'List', icon: <ListAltOutlinedIcon/> },
6 { link: 'Topic', icon: <ChatOutlinedIcon/> },
7 { link: 'Moments', icon: <OfflineBoltOutlinedIcon/> },
8 { link: 'Newsletters', icon: <PostAddOutlinedIcon/> },
9 { link: 'Twitter Ads', icon: <CallMadeOutlinedIcon/> },
10 { link: 'Analytics', icon: <BarChartOutlinedIcon/> },
11 { link: 'Settings', icon: <SettingsOutlinedIcon/> },
12 { link: 'Help Center', icon: <HelpOutlineOutlinedIcon/> },
13 { link: 'Display', icon: <BrushOutlinedIcon/> },
14 { link: 'Keyboard shortcuts', icon: <AccessibilityNewOutlinedIcon/> },
16 ];
18 const [open, setOpen] = useState(false);
20 const handleClick = (event) => {
21 setOpen(true);
22 };
23 const handleClose = () => {
24 setOpen(false);
25 };
26 return(
28 <div className="sidebar">
29 <SidebarLink text="Home" Icon={HomeIcon} />
30 <SidebarLink text="Explore" Icon={SearchIcon} />
31 <SidebarLink text="Notifications" Icon={NotificationsNoneIcon} />
32 <SidebarLink text="Messages" Icon={MailOutlineIcon} />
33 <SidebarLink text="Bookmarks" Icon={BookmarkBorderIcon} />
34 <SidebarLink text="Lists" Icon={ListAltIcon} />
35 <SidebarLink text="Profile" Icon={PermIdentityIcon} />
36 <Button onClick={handleClick} id="moreLinks">
37 <MoreHorizIcon/> More
38 </Button>
39 <Button id="tweet">
40 Tweet
41 </Button>
43 <Menu
44 open={open}
45 onClose={handleClose}
46 id="long-menu"
47 >
48 { => (
49 <MenuItem key={} onClick={handleClose}>
50 {option.icon} {}
51 </MenuItem>
52 ))}
53 </Menu>
54 </div>
55 );

Our Twitter sidebar clone now looks something like this when the More button has been clicked:


In our Twitter sidebar clone things like the More button, the Menu and the icons are not looking nice. Let’s add some styling to fix that. In the sidebar.css file, add the following styling:


2 width: 100%;
3 border-radius: 30px;
4 font-weight: 700;
5 justify-content: unset;
6 font-size: 20px;
7 margin-right: 20px;
8 text-transform: inherit;
9 color: black;
10 height: 60px;
11 padding-left: 10px;
12 padding-right: 30px;
13 margin-bottom: 5px;
15#moreLinks .MuiSvgIcon-root{
16 margin-right: 20px;
19 background-color: hsl(205, 92%, 95%);
20 color: hsl(203, 89%, 64%);
21 transition: color 100ms ease-out;
23#long-menu .MuiMenu-paper{
24 width: 220px;
25 max-height: 100vh;
26 left: 40% !important;
27 top: unset !important;
29#long-menu .MuiListItem-root{
30 padding-bottom: 15px;
31 padding-top: 15px;
34 border-bottom: 1px solid hsl(210, 12%, 95%);
36.MuiListItem-root .MuiSvgIcon-root{
37 font-size: 20px;
38 color: hsl(210, 12%, 20%);
39 font-weight: 400;
40 margin-right: 10px;

With that, we are done building the Twitter sidebar clone, it now looks like this when the More button has been clicked:



Material-UI is really a helpful library to use when developing the frontend. I really like the way all its clickable components display a cool animation when clicked and also how it makes it easy to use and customize SVG icons. Though there are still some useful icons and components that it doesn’t have yet, overall Material-UI is a nice component library to use in any web application.

More articles from OpenReplay Blog

How To Parse and Render Markdown In Vuejs

Markdown is a tool to help you write HTML without the hustle of the tags, however turning it into HTML is not that trivial.

August 27th, 2021 · 5 min read

Getting Started with React Cosmos

Learn about the power of React Cosmos in this getting started tutorial

August 23rd, 2021 · 7 min read
© 2021 OpenReplay Blog
Link to $ to $ to $