My replica to YouTube App, one of the largest online video streaming and sharing social media platforms owned by Google. KTube App in React.js using the newest version of Material UI, which contains a stunning new video section, custom categories responsive channel, and video cards channel pages. The user can play the video straight from the App, browse related videos, and search intended videos. Along with building this App, I have learned a lot on API fetching, dependencies and packages management, React functional components and their reusability, React file and folder structure, Vscode extension usage, fetching media queries for satisfactory responsiveness on various devices using RapidAPI to fetch data from unlimited sources.
⏬
Please carefully read LICENSE.md about the Open Source restrictions and the personal use policy of this project under GPL-3.0 license, any commericial uses on this project by other than the owner @KrystalZhang612 or the authorized users and organizations, will be subjected to copyright violation with sebsequent legal potential concerns.*
Method to Run & Test the Project Locally
Prerequisites & Setups
Debugging&Troubleshooting
Synchronous Developing Notes
Testing Result
Tags and Topics
Version | Supported |
---|---|
git 2.13.1+ | ✅ |
node js 16.15.1+ | ✅ |
npm 5.6.1+ | ✅ |
yarn 3.0.0+ | ✅ |
Download git version 2.13.1 or higher
. Download git at https://git-scm.com/downloads
Download node 16.15.1 or higher
. Download node at https://nodejs.org/en/download/
Create a file named fetchFromAPI.js
in src/utils
Obtain a free YouTube API Key at https://rapidapi.com/ytdlfree/api/youtube-v31
Replace YOUR OWN YOUTUBE KEY
in fetchFromAPI.js with you obtained API key:
import axios from 'axios';
export const BASE_URL = 'https://youtube-v31.p.rapidapi.com';
const options = {
params: {
maxResults: 50,
},
headers: {
'X-RapidAPI-Key': 'YOUR OWN YOUTUBE API KEY',
'X-RapidAPI-Host': 'youtube-v31.p.rapidapi.com',
},
};
export const fetchFromAPI = async (url) => {
const { data } = await axios.get(`${BASE_URL}/${url}`, options);
return data;
};
Vscode 1.74
ReactJS
RapidAPI Vscode Client
Node.JS npm/npx
Yarn
Material UI
JavaScript
ES7+ React/Redux/React-Native snippets Vscode Extension
npm Intellisense Vscode Extension
RapidAPI YouTubeV3 API Key
Create React app in Vscode Terminal:
Create React app in Vscode Terminal:
Check who own the node_modules:
ls -la /usr/local/lib/node_modules
Change the ownership to my own username:
sudo chown -R MYUSERNAME: /usr/local/lib/node_modules
Install needed dependencies in Vscode Terminal:
yarn add @emotion/react @emotion/styled @mui/icons-material
@mui/material axios react-router-dom
Audit all dependencies to the latest version:
npm install --legacy-peer-deps
Install needed font at https://mui.com/material-ui/getting-started/installation/
crbugs deprecated npm start not working error. DEBUGGING: Install React-Player running:
yarn add react-player.
Customize search bar text input and icon in SearchBar.jsx:
<input
className="search-bar"
placeholder="Search for videos on KTube..."
value=""
onChange={() => {}}
/>
<IconButton type="submit" sx={{ p: '10px', color: 'red' }}>
<Search />
</IconButton>
</Paper>
)
Navbar is done customizing.
Customize Sidebar by fetching sidebar sections from constants.js in Sidebar.jsx:
{categories.map((category) => (
<button
className="category-btn"
style={{
background: category.name ===
selectedCategory && '#FC1503',
color: 'white'
}}
key={category.name}
>
<span style={{
color: category.name ==
selectedCategory ? 'white' : 'red',
marginRight: '15px'
sidebar done customizing.PNG
Fetch API from RapidAPI, and design VideoCard.jsx:
const VideoCard = ({ video: { id: { videoId }, snippet } }) => (
<Card sx={{ width: { xs: '100%', sm: '358px', md: "320px", },
boxShadow: "none", borderRadius: 0 }}>
<Link to={videoId ? `/video/${videoId}` :
`/video/cV2gBU6hKfY`}>
<CardMedia image={snippet?.thumbnails?.high?.url ||
demoThumbnailUrl} alt={snippet?.title}
Design ChannelCard.jsx:
sx={{
boxShadow: 'none',
borderRadius: '20px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: { xs: '356px', md: '320px' },
height: '326px',
margin: 'auto',
marginTop,
Now the video page fetched based on categories successfully!
videos of categories fetched.PNG
Fetch channel details and API data in ChannelDetail.jsx:
useEffect(() => {
const fetchResults = async () => {
const data = await
fetchFromAPI(`channels?part=snippet&id=${id}`);
setChannelDetail(data?.items[0]);
const videosData = await
fetchFromAPI(`search?channelId=${id}&part=snippet%2Cid&order=date`);
setVideos(videosData?.items);
};
Customize feed searching option in SearchFeed.jsx:
const SearchFeed = () => {
const [videos, setVideos] = useState(null);
const { searchTerm } = useParams();
useEffect(() => {
fetchFromAPI(`search?part=snippet&q=${searchTerm}`)
.then((data) => setVideos(data.items))
}, [searchTerm]);
return (
<Box p={2} minHeight="95vh">
<Typography variant="h4" fontWeight={900} color="white" mb={3}
ml={{ sm: "100px" }}>
Search Results for <span style={{ color: "#FC1503"
}}>{searchTerm}</span> videos
</Typography>
<Box display="flex">
searching feed works, showing results.PNG
To make the videos playable, fetch React Player in VideoDetails.jsx:
<Box sx={{ width: "100%", position: "sticky", top: "86px" }}>
<ReactPlayer url={`https://www.youtube.com/watch?v=${id}`}
className="react-player" controls />
<Typography color="#fff" variant="h5" fontWeight="bold"
p={2}>
...
full-stack, responsive, javascript, vscode, react-native-js, rapid-api, npm, npx, html5, css3, video-sharing-upload-app, eslint, yarn, axios, youtube.
App Netlify deployment process:
Vscode -> public folder-> add new file named _redirects
with inputs /* /index.html 200
Vscode-> Terminal -> npm run build
Right click the generated dist folder Reveal in files explorer/finder
Netlify-> overview-> Sites-> Drag dist folder to upload to deploy
Once done deploying, options-> edit site name -> customize site name
Browse the deployed public sites anytime.
Krystal Zhang https://github.com/KrystalZhang612
This file was generated by KTube-readme, on December 13th, 2022