A demo project to clone Youtube using RapidAPI.
- System Design
- Rapid API
- Debounce
- Functional Components
- React Hooks
- React File and Folder Structure
- Material UI v5
- Responsive design
- Technologies
- Deployment
- References
- Keywords
- Getting Started with Create React App
- Client (mobile/desktop) makes a GET request to the server (AWS EC2 Ubuntu instance).
- Each request is intercepted by NginX which acts as a reverse proxy/load balancer.
- First checks if the reponse is stored locally in localStorage if not makes the API call to RapidAPI and stores in localStorage for future retrieval
- AWS S3 bucket acts as a object store for images
- AWS Route 53 acts as a DNS provider/resolver
- AWS Cloudfront Distribution CDN caches results
- AWS Certificate Manager is used by AWS Cloudfront Distribution to securely respond to any cached contents
- Git/GitHub/GitHub Actions work as the CICD backbone.
- When a pull request PR is made to the
main
branch, GitHub Actions Runner trigger the CICD workflow updating the latest changes. - In the frontend React is used to display content in a user firendly format.
Rapid API is an online API marketplace that connects developers with thousands of APIs. By using Rapid API to clone Youtube I implemented following features from the Youtube namely:
- Suggested Videos
- Search
- Video Details
- Channel Details
- Channel Videos
Events like onChange
for inputs might be triggered too frequently and cause too many render cycles.
As a user types into a π search bar, we want to wait until they pause or stop typing to perform the search. We don't want to perform the search operation with every single character they type in order to avoid overloading our server with requests. This is particularly applicable in this project since we are using free-tier
Rapid API with rate limit on API access.
export const debounce = (func, delay) => { let debounceTimer; return (...args) => { const context = this; clearTimeout(debounceTimer); debounceTimer = setTimeout(() => func.apply(context, args), delay); } }
Debounce
is a higher order function that takes function as input.
debounceTimer
is the timer that keeps track of when we call our function next.
The returned function clears any existing timer (using clearTimeout
) and starts a new timer every time it's called. Only when the timer runs out (after the delay we specified which in this case is 500 milliseconds), original function is called with the correct context and arguments.
If the returned functin is called again before the timer runs out, it will clear the old timer and strat a new one. This means the original function (func
) is only called once the returned function stops being called for more than delay
milliseconds.
In this project, I implemented react functional components primarily for:
- Simplicity: Functional components are more straightforward and concise than class components.
- Performance: They tend to have a slight performance boost over class components due to their simplicity.
- Reusability: By creating reusable commponents, we can avoid redundancy and ensure consistency across the application.
React Hooks were introduced in React 16.8 and allow you to use state and other React features without writing a class. In this project, I've utilized two very fundamental hooks with best practices: useState
, and useEffect
.
-
useState
is used when the component has some data that changes over time, and we want it to re-render whenever data changes. -
useEffect
lets us perform side effects in function componetns. It's likecomponentDidMount
,componentDidUpdate
, andcomponentWillUnmount
combined in class components.
Best Practices for Using Hooks
- Don't Use Hooks Inside Loops, Conditions, or Nested Functions.
- Only Call Hooks from React Functions.
- Use Multiple State Variables.
- Optimize by Using the Correct Dependency Array in useEffect
This project utilizes a well-structured React file and folder structure to significantly improve the development experience by making the codebase more maintainable and scalable.
youtube-clone/ β βββ node_modules/ βββ public/ β βββ index.html β βββ ... β βββ src/ β β | | | βββ assets/ β β βββ images/ | | βββ youtube-clone-system-design.svg | | β βββ components/ β β βββ β β β βββ Video.jsx β β β βββ VideoDetail.jsx β β β βββ Sidebar.jsx β β β βββ SearchFeed.jsx β β βββ ... β β | βββ hooks/ β β βββββ β β βββ useDebounce.js | | β βββ utils/ β β βββββ β β βββ constants.js β β βββ fetchFromAPI.js β β β βββ App.js β βββ index.css β βββ index.js β βββ ... β βββ .gitignore βββ package.json βββ README.md βββ .env (!Neved Add it to the repo! Check .gitignore rule) βββ ...
This project leverages Material-UI v5 (MUI v5)
, which is a popular React UI framework that follows Google's Material Design guidelines. Material-UI version 5, which was released in September 2021, brought significant changes and improvements to the library. I picked material UI for following reasons:
- New Branding and Package Naming
- Enhanced Customization
- Improved Performance
- New Components and Features
- Better Theming
- Enhanced Documentation
- Adoption of Emotion and Styled-Components
- Dark Mode Support
In summary, MUI v5 significantly benefits frontend development by providing a rich set of components and utilities, excellent customization capabilites, and performance boost. These features allowed me to create powerful, efficient, and fully responsive youtube clone applications faster and with less effort.
I've utilized fully responsive design principle in this Youtube Clone project with a goal to provide an optimal viewing and interaction experience across a wide range of devices from desktop to iOS/Android mobile phones. Here, I'll elaborate on responsie design principles that I've implemented in this project:
Fluid Grids
Fluid grids are essenatial because they let the layout adjust dynamically. In responsive desing, all layout elements are sized in relative units, such as percentages, rather than absoluite units like pixels. This ensures that the layout adapts to the screen's size.
.container {
width: 100%;
max-width: 1200px;
}
Flexible Images
Images should also be responsive, meaning that they should adjust their size according to the screen size. This ensures that images don't render outside their containing element.
img {
max-width: 100%;
height: auto;
}
Media Queries
Media queries allow the applications of different styles for different media types and screen sizes. They are essential in applying different layouts, font sizes, and other styling depending on the screen size.
@media screen and (max-width: 768px) {
.sidebar {
display: none;
}
}
Usable Navigation
Navigation should be easy to use on all devices. This often involves a menu that is horizontal on desktop screens but collapses into a "humburger" menu on mobile devices. However, for this project I've implemented horizontal scrollable menu options on mobile devices since the menu options comprised of a long list.
Significance of Responsive Design in Web Development
βοΈ The list of technologies used in this projects are:
Javascript, React, Rapid API, Material UI v5, Axios, HTML, CSS, AWS, AWS EC2, AWS S3, AWS Route 53, Git, GitHub, VS Code, CertBot, Virtual Hosting.
This app is deployed to AWS Cloud utilizing following technologies but not limited to:
- AWS EC2
- AWS S3
- AWS Route 53
- AWS CloudFront Distribution
- AWS Certificate Manager
- Nginx
- Rapid API
- Local Storage
- Git
- GitHub
- GitHub Actions Runner
π This project is possible based on following open source projects:
- React: https://react.dev/
- React Visualized: https://react.gg/visualized
- React Testing Library: https://testing-library.com/docs/react-testing-library/intro/
- Jest: https://jestjs.io/
- Rapid API: https://rapidapi.com/ytdlfree/api/youtube-v31/
- Free Code Camp: https://www.freecodecamp.org/
- GitHub: https://github.com/adrianhajdin/project_youtube_clone
- CSS Flex Box: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox
- CSS Grid: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout
- Material UI: https://mui.com/material-ui/getting-started/overview/
- Material Tutorial: https://www.youtube.com/watch?v=Xoz31I1FuiY
- CSS Gradient: https://cssgradient.io/
Youtube Clone, Portfolio Showcase, React, JavaScript, ES6, JavaScript Interview, Algorithms, Datastructures, Interview Preparation, Technical Interview, Coding Challenges, Programming Challenges.
This project was bootstrapped with Create React App.
In the project directory, you can run:
npm start
Runs the app in the development mode.
Open http://localhost:3000 to view it in your browser.
The page will reload when you make changes.
You may also see any lint errors in the console.
npm test
Launches the test runner in the interactive watch mode.
See the section about running tests for more information.
npm run build
Builds the app for production to the build
folder.
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.
Your app is ready to be deployed!
See the section about deployment for more information.
npm run eject
Note: this is a one-way operation. Once you eject
, you can't go back!
If you aren't satisfied with the build tool and configuration choices, you can eject
at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except eject
will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
You don't have to ever use eject
. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
You can learn more in the Create React App documentation.
To learn React, check out the React documentation.
This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify