나만의 유튜브 사이트 만들기
소개
안녕하세요! 웹스토리보이입니다. 이번에는 메인페이지의 메인 컨텐츠를 만들어 보겠습니다. 메인에는 오늘의 추천영상, 개발자 소개 및 영상 소개를 보여주는 부분입니다. 그럼 한번 시작해보겠습니다.😝
인덱스
- 1. 셋팅하기
- 1_1. Node.js 설치
- 1_2. Vscode 설치
- 1_3. React.js 설치
- 1_4. 폴더 정리하기
- 1_5. 필요한 파일 설치하기
- 2. CSS 셋팅하기
- 2_1. SCSS 설정하기
- 2_2. style.scss 설정하기
- 2_3. fonts.scss 설정하기
- 2_4. vars.scss 설정하기
- 2_5. reset.scss 설정하기
- 2_6. mixin.scss 설정하기
- 2_7. common.scss 설정하기
- 3. 페이지 및 컴퍼넌트 만들기
- 3_1. 페이지 만들기
- 3_2. 컴퍼넌트 만들기
- 4. 섹션 컴퍼넌트 만들기
- 4_1. Main 컨퍼넌트 만들기
- 4_2. Header 컨퍼넌트 만들기
- 4_3. Header 컨퍼넌트 데이터화 하기
- 4_4. Footer 컨퍼넌트 만들기
- 5. 페이지 SEO 작업
- 5_1. App.js 재구성
- 5_2. main 컴퍼넌트 재구성
- 5_3. 모든 페이지 재구성
- 6. 메인 콘텐츠 만들기
- 6_1. 검색 컴퍼넌트 작업
- 6_2. 오늘의 영상 컴퍼넌트 작업
- 6_3. 오늘의 영상 페이지 작업
- 7. 추천 개발자 콘텐츠 만들기
- 7_1. 메인 추천 개발자 섹션 작업
- 7_2. 추천 개발자 페이지 작업
- 7_3. 추천 개발자 섹션 슬라이드 작업
7. 추천 개발자 콘텐츠 만들기
7_1. 메인 추천 개발자 섹션 작업
Home.jsx
페이지에서 Developer
컴퍼넌트를 추가하겠습니다.
import React from 'react'
import Main from '../components/section/Main'
import Today from '../components/contents/Today'
import Developer from '../components/contents/Developer'
const Home = () => {
return (
<Main
title = '웹스토리보이 유튜브'
description='웹스토리보이 유튜버에 오신 것을 환영합니다.'>
<Today />
<Developer />
</Main>
)
}
export default Home
components
폴더 contents
폴더에 Developer
컴퍼넌트를 만들겠습니다.
import React from 'react'
import { developerText } from '../../data/developer';
import { Link } from 'react-router-dom';
const Developer = () => {
return (
<section id='developer'>
<h2>😪 추천 개발자를 소개합니다.</h2>
<div className="develpoer__inner overflow">
{developerText.map((developer, key) => (
<div className="develpoer" key={key}>
<div className="develpoer__img play__icon">
<Link to={`/channel/${developer.channelId}`}>
<img src={developer.img} alt={developer.name} />
</Link>
</div>
<div className="develpoer__info">
<Link to={`/channel/${developer.channelId}`}>
{developer.name}
</Link>
</div>
</div>
))}
</div>
</section>
)
}
export default Developer
data
폴더에 developer.js
파일을 만들겠습니다.
export const developerText = [
{
img: "https://yt3.googleusercontent.com/JU6k565OVstxx_h_7TbzE1aNXKzcxKl33zjPV4p649pqsgS7E3vb0meX9DB1_D_KviDoc4xM=s176-c-k-c0x00ffffff-no-rj",
name: "webstoryboy",
channelAddress: "https://www.youtube.com/@webstoryboy",
channelId: "UCsvQSv7EeCMHyYb9ENKAJZw"
},
{
img: "https://yt3.googleusercontent.com/JuRcVt9OFQgqh7UL1LjihpVLEbjdNXt3tGq-IQfqRMT8wVXgWg_tzyz0S_GVsgqkB3ucBC5fqeY=s176-c-k-c0x00ffffff-no-rj",
name: "조코딩 JoCoding",
channelAddress: "https://www.youtube.com/@jocoding",
channelId: "UCQNE2JmbasNYbjGAcuBiRRg"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaSNRWU5nI-gDyzEdtbhpLqWg8wXNs-FQHf35iMCOw=s176-c-k-c0x00ffffff-no-rj",
name: "생활코딩",
channelAddress: "https://www.youtube.com/@coohde",
channelId: "UCvc8kv-i5fvFTJBFAk6n1SA"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaSn88PvVXWN_Wy5vSr-5Eo_NGDdw_apL6bM7QKfCw=s176-c-k-c0x00ffffff-no-rj",
name: "노마드 코더 Nomad Coders",
channelAddress: "https://www.youtube.com/@nomadcoders",
channelId: "UCUpJs89fSBXNolQGOYKn0YQ"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaSeGpiSPyozdunhf74J4oa2XWHPObm8bKTcbEU=s176-c-k-c0x00ffffff-no-rj",
name: "코딩하는거니",
channelAddress: "https://www.youtube.com/@gunnycoding",
channelId: "UCO7g158NWgLyn98z8v3zduA"
},
{
img: "https://yt3.googleusercontent.com/iofg4f6THo3jyeap1GC23g5qsKD-w62Lu4U9EJBmZe8YtM1NhbNWz4WiyICAXXmwrgbnUh-FNQ=s176-c-k-c0x00ffffff-no-rj",
name: "워니코딩",
channelAddress: "https://www.youtube.com/@WonieSong",
channelId: "UC0uDM1xZMNBAoW2xnzhAQ7g"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaRCkXnBnWEMfpo5c_TXB-tF0FxqiCfv5KoP_9IBC6A=s176-c-k-c0x00ffffff-no-rj",
name: "얄팍한 코딩사전",
channelAddress: "https://www.youtube.com/@yalco-coding",
channelId: "UC2nkWbaJt1KQDi2r2XclzTQ"
},
{
img: "https://yt3.googleusercontent.com/oLi5jJ2AKs_aYpR9UpUpu052M84WIE2j9cpnNb1VnpBHZMHVrTRPwrUIncJGu6--PVR-x-22=s176-c-k-c0x00ffffff-no-rj",
name: "개발하는 정대리",
channelAddress: "https://www.youtube.com/@dev_jeongdaeri",
channelId: "UCutO2H_AVmWHbzvE92rpxjA"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaTw2ZRRi6UzhNeunJh03HOeAnKScgRJygpN7_MsVQ=s176-c-k-c0x00ffffff-no-rj",
name: "코딩애플",
channelAddress: "https://www.youtube.com/@codingapple",
channelId: "UCSLrpBAzr-ROVGHQ5EmxnUg"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaRfTsQsimyyMrWugbbogh_EdsCWWQsKVqh5Fdvq=s176-c-k-c0x00ffffff-no-rj",
name: "김왼손의 왼손코딩",
channelAddress: "https://www.youtube.com/@leftykhim",
channelId: "UC0h8NzL2vllvp3PjdoYSK4g"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaSXgyXVlJGDyr1IaQgHJlGvc4wcFcZJ4S35NATdrYA=s176-c-k-c0x00ffffff-no-rj",
name: "제주코딩베이스캠프",
channelAddress: "https://www.youtube.com/@jejucodingcamp",
channelId: "UC4GnvNKtuJ4cqWsYjxNxAEQ"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaQyV-QwNnxxLKCnfHZrfsGNx7fqFD9YSQ_lweIx6w=s176-c-k-c0x00ffffff-no-rj",
name: "나도코딩",
channelAddress: "https://www.youtube.com/@nadocoding",
channelId: "UC7iAOLiALt2rtMVAWWl4pnw"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaTiHU0ol325VdijS5AX4DQomGs6zlD_y_v0I0A6=s176-c-k-c0x00ffffff-no-rj",
name: "라매개발자",
channelAddress: "https://www.youtube.com/@lamedev",
channelId: "UCr3lkp7TJiJTCY4ffRQ1m2A"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaSnppVkSh38WlQrn-7FzBAqlJpMLdGq4jS2GGHzgQ=s176-c-k-c0x00ffffff-no-rj",
name: "드림코딩",
channelAddress: "https://www.youtube.com/@dream-coding",
channelId: "UC_4u-bXaba7yrRz_6x6kb_w"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaTyIgb-N-SeFznHEn_RkJkF9IirgzvXtEoWOnNt=s176-c-k-c0x00ffffff-no-rj",
name: "ZeroCho TV",
channelAddress: "https://www.youtube.com/@ZeroChoTV",
channelId: "UCp-vBtwvBmDiGqjvLjChaJw"
},
{
img: "https://yt3.googleusercontent.com/x5DWPPquVbSkeJ-UCVuPfnd6nzbkSCkSaXuxRUnD1yGYWixNPErHqMQP4bhP6M86oQcH7pcm=s176-c-k-c0x00ffffff-no-rj",
name: "짐코딩 GYM CODING",
channelAddress: "https://www.youtube.com/@gymcoding",
channelId: "UCZ30aWiMw5C8mGcESlAGQbA"
},
{
img: "https://yt3.googleusercontent.com/PVbwh8OLmp3dTofJ7vmv6zfoRKiFgIvL9SsTYaermGxW3Ga6vONSfC7ymrgpO6gUCd9nKcZp0Sc=s176-c-k-c0x00ffffff-no-rj",
name: "프롱트",
channelAddress: "https://www.youtube.com/@frongt",
channelId: "UCku8mOp8y05Cm6sb9Rp0jMQ"
},
{
img: "https://yt3.googleusercontent.com/1gLFRSPxZUYjlGG-Ap7B2bymZkdp4fFuSTAntouex6mdUQUZ2lA8kWMrzKOLHAdfkzjopcntU7E=s176-c-k-c0x00ffffff-no-rj",
name: "프로그래머 김플 스튜디오",
channelAddress: "https://www.youtube.com/@kimfl",
channelId: "UCdNSo3yB5-FRTFGbUNKNnwQ"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaToAOoB7zZaRe9kVmXGi6QWBBPrESpK8pcaWnBL=s176-c-k-c0x00ffffff-no-rj",
name: "Lama Dev",
channelAddress: "https://www.youtube.com/@LamaDev",
channelId: "UCOxWrX5MIdXIeRNaXC3sqIg"
},
{
img: "https://yt3.googleusercontent.com/4RM7sEvMAp5QokwqBbcQh9_XD53E2PGrfwCClaqT_IAL2FnIzWqxyBN3JuPKMas-dL0do9t-=s176-c-k-c0x00ffffff-no-rj",
name: "JS Dev Hindi",
channelAddress: "https://www.youtube.com/@jsdevhindi",
channelId: "UCRJz8FP29yq_vA5h08dXMPw"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaQneLC0nfXjK4QaNPSG1lZXCUZtuhoFdBtYz1hH=s176-c-k-c0x00ffffff-no-rj",
name: "코딩알려주는누나",
channelAddress: "https://www.youtube.com/@user-yu8so2ck1z",
channelId: "UCfBvs0ZJdTA43NQrnI9imGA"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaQxJlRUxIrCv4zw_kfUsqKHAm1rN32SHAU8Iwla=s176-c-k-c0x00ffffff-no-rj",
name: "동빈나",
channelAddress: "https://www.youtube.com/@dongbinna",
channelId: "UChflhu32f5EUHlY7_SetNWw"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaQZENEAuTWosc8r89GoegTvvjKzdEgBXMv7C4i4=s176-c-k-c0x00ffffff-no-rj",
name: "EdRoh",
channelAddress: "https://www.youtube.com/@EdRohDev",
channelId: "UCMoEx7gz7IbJHv733yEi2aA"
},
{
img: "https://yt3.googleusercontent.com/wg1TITEoPfxvBGfzuqWyt3bqm_qu35ZhMswUv3feetU3xNX_6wsAXZF40OlPIgY4TmqbqCmAZ1U=s176-c-k-c0x00ffffff-no-rj",
name: "JavaScript Mastery",
channelAddress: "https://www.youtube.com/@javascriptmastery",
channelId: "UCmXmlB4-HJytD7wek0Uo97A"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaTs1IEit9EUooQAJkWS4SkpUE7oMDXYrjIgnOk1Kw=s176-c-k-c0x00ffffff-no-rj",
name: "freeCodeCamp.org",
channelAddress: "https://www.youtube.com/@freecodecamp",
channelId: "UC8butISFwT-Wl7EV0hUK0BQ"
},
{
img: "https://yt3.googleusercontent.com/kVYpCZYEfX0_b2_Y7SROJsLahriQfOf6rW4egbSxDGWHDLiqhFcPM8eL56EKYfgjzetQQRx7fA=s176-c-k-c0x00ffffff-no-rj",
name: "How to Become a Developer",
channelAddress: "https://www.youtube.com/@howtobecomeadeveloper",
channelId: "UCkXqOdpo5ul8BosGBFlDgmw"
},
{
img: "https://yt3.googleusercontent.com/O8iON5EAVx6HVKyOV5UMreLFI_0D3mJX373vTEGoNcVRpNP7Lq8swha7BSLWTiEWlZaF7a4ENW8=s176-c-k-c0x00ffffff-no-rj",
name: "Code With Antonio",
channelAddress: "https://www.youtube.com/@codewithantonio",
channelId: "UCW_4e6sUTMWHxlF06aErH9w"
},
{
img: "https://yt3.googleusercontent.com/nwyG0ql8sxARogaFb3sgpjoNd86v7hL9W2eeEysP2LryigBtYtX-J2Mw9H1lpcB9D4sw0aCx9w=s176-c-k-c0x00ffffff-no-rj",
name: "EGATOR",
channelAddress: "https://www.youtube.com/@EGATORTUTORIALS",
channelId: "UCL8l_VxCAN0jOpaLaRAm8sQ"
},
{
img: "https://yt3.googleusercontent.com/a3vK_ZCS_QUX19CV2Xx1RY-CgR7DQzpeWk14UFbKdDv0Ryjc_FPf6Uo4-8NPi34deUay87eusQ=s176-c-k-c0x00ffffff-no-rj",
name: "빔캠프 CSS",
channelAddress: "https://www.youtube.com/@veamcamp",
channelId: "UCvx57s_ZBt5VG4fvlStiq2g"
},
{
img: "https://yt3.googleusercontent.com/wr8dNnJ8dSHjBsHKag3O6ZCKmxJvnxqhpPi-E6sWf83JYKxnevU2iSt3FzLxjzrZOCTRpbi53mg=s176-c-k-c0x00ffffff-no-rj",
name: "코딩카페1",
channelAddress: "https://www.youtube.com/@CodingCafe1",
channelId: "UCt76J5CYnXL-uoJmQPG2Azw"
},
{
img: "https://yt3.googleusercontent.com/AVa5OPep1y0E8bZMIyLDyzg1jTwApHaSCi2RUG0epuLFZe0e80yvYo7MNHd-ApnvOtDgT3A3=s176-c-k-c0x00ffffff-no-rj",
name: "Codegrid",
channelAddress: "https://www.youtube.com/@codegrid",
channelId: "UC7pVho4O31FyfQsZdXWejEw"
},
{
img: "https://yt3.googleusercontent.com/wgnEbc2Ec2JYkeyzUbiHzDlAFObI2Btwo2YRCEF1aCMBiRc5E_zWy8-URBQS3EMQ1yzzaGFR=s176-c-k-c0x00ffffff-no-rj",
name: "Kishan Sheth",
channelAddress: "https://www.youtube.com/@KishanSheth21",
channelId: "UCDT8sIFy3pW8LT6SAbe8xtQ"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaTc-hNjbGDnft48nMktaKF87D8EmpZ9Oacc4XeTew=s176-c-k-c0x00ffffff-no-rj",
name: "Yuri Artiukh",
channelAddress: "https://www.youtube.com/@akella_",
channelId: "UCDo7RTzizoOdPjY8A-xDR7g"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaQOeqOOHYrdr9qaOxYqujnMoTvladljn12PeOdeVA=s176-c-k-c0x00ffffff-no-rj",
name: "디자인베이스",
channelAddress: "https://www.youtube.com/@designbase",
channelId: "UCvYnDMeL-PFZhfIz6oc_U-Q"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaRq6HIiAsf1pv1CHAlIIM6MdbnaX0jqpTCOyIM5TA=s176-c-k-c0x00ffffff-no-rj",
name: "야무",
channelAddress: "https://www.youtube.com/@yamoo9",
channelId: "UCTZRL_OwTjiXYoTjwWg4bww"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaTtbptu4ao5lFu3ElFN61tMr1K0pvo8zd7qw7HeFw=s176-c-k-c0x00ffffff-no-rj",
name: "DesignCourse",
channelAddress: "https://www.youtube.com/@DesignCourse",
channelId: "UCVyRiMvfUNMA1UPlDPzG5Ow"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaR892c9LcaLOEfzAp80Nna198A4lte69Z80LV-2ug=s176-c-k-c0x00ffffff-no-rj",
name: "Code with Ania Kubów",
channelAddress: "https://www.youtube.com/@AniaKubow",
channelId: "UC5DNytAJ6_FISueUfzZCVsw"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaR0SDrl59HyNkJotnB41HBsVLXDUaRMbKFRJIIoJQ=s176-c-k-c0x00ffffff-no-rj",
name: "Coding Artist",
channelAddress: "https://www.youtube.com/@CodingArtist",
channelId: "UC15exV5s79D_aYGADudlwpQ"
},
{
img: "https://yt3.googleusercontent.com/ytc/AOPolaRbhQtG_1StOoOn0z0pfDfAFoe86Gk_kkR1OPhYVg=s176-c-k-c0x00ffffff-no-rj",
name: "Rock's Easyweb",
channelAddress: "https://www.youtube.com/@Ezweb",
channelId: "UCax1DP6hqZowNWF2lquKk0w"
}
]
scss
폴더 section
폴더에 _developer.scss
을 추가하고 작업하겠습니다.
.develpoer__inner {
display: flex;
color: #fff;
flex-wrap: wrap;
.develpoer {
color: #fff;
text-align: center;
margin-right: 20px;
.develpoer__img {
display: block;
width: 150px;
height: 150px;
border-radius: 50%;
overflow: hidden;
margin-bottom: 10px;
}
.develpoer__info {
width: 150px;
text-align: center;
@include line-one;
padding-bottom: 40px;
}
}
}
다음과 같이 개발자 섹션이 완성됩니다.

7_2. 추천 개발자 페이지 작업
이번에는 페이지에서 데이터를 불러오도록 하겠습니다.
pages
폴더에 Developer.jsx
를 다음과 같이 수정하겠습니다.
import React from 'react'
import Main from '../components/section/Main'
import { developerText } from '../data/developer'
import { Link } from 'react-router-dom'
const Developer = () => {
return (
<Main
title = "추천 개발자"
description="오늘의 추천 개발자 유튜버입니다.">
<section id='developerPage'>
<h2>🥰 오늘의 추천 개발자입니다.</h2>
<div className="develpoer__inner">
{developerText.map((developer, key) => (
<div className="develpoer" key={key}>
<div className="develpoer__img play__icon">
<Link to={`/channel/${developer.channelId}`}>
<img src={developer.img} alt={developer.name} />
</Link>
</div>
<div className="develpoer__info">
<Link to={`/channel/${developer.channelId}`}>
{developer.name}
</Link>
</div>
</div>
))}
</div>
</section>
</Main>
)
}
export default Developer
7_3. 추천 개발자 섹션 슬라이드 작업
이번에는 Swiper를 이용하여 이미지 슬라이드를 구현하겠습니다.
contents
폴더에 Developer.jsx
파일을 다음과 같이 변경하겠습니다.
import React from 'react'
import { developerText } from '../../data/developer';
import { Link } from 'react-router-dom';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';
import 'swiper/css/pagination';
import 'swiper/css/navigation';
import { Navigation, Autoplay } from 'swiper/modules';
const Developer = () => {
return (
<section id='developer'>
<h2>😪 추천 개발자를 소개합니다.</h2>
<div className='develpoer__inner'>
<Swiper
slidesPerView={4}
spaceBetween={15}
navigation={true}
autoplay={{
delay: 5000,
disableOnInteraction: false,
}}
breakpoints={{
640: {
slidesPerView: 5,
spaceBetween: 15,
},
768: {
slidesPerView: 6,
spaceBetween: 15,
},
1024: {
slidesPerView: 7,
spaceBetween: 20,
},
1240: {
slidesPerView: 8,
spaceBetween: 20,
},
1640: {
slidesPerView: 9,
spaceBetween: 20,
},
2000: {
slidesPerView: 10,
spaceBetween: 20,
},
}}
modules={[Navigation, Autoplay]}
className='mySwiper'
>
{developerText.map((developer, key) => (
<SwiperSlide key={key}>
<div className='develpoer' key={key}>
<div className='develpoer__img play__icon'>
<Link to={`/channel/${developer.channelId}`}>
<img src={developer.img} alt={developer.name} />
</Link>
</div>
<div className='develpoer__info'>
<Link to={`/channel/${developer.channelId}`}>
{developer.name}
</Link>
</div>
</div>
</SwiperSlide>
))}
</Swiper>
</div>
</section>
)
}
export default Developer
마무리
swiper를 이용하여 자동 플레이도 설정하고 반응형도 완료하였습니다. 수고하셨습니다. 😲
예제 목록
- 1. 나만의 유튜브 사이트 만들기 : 셋팅하기
- 2. 나만의 유튜브 사이트 만들기 : CSS 셋팅하기
- 3. 나만의 유튜브 사이트 만들기 : 페이지 및 컴퍼넌트 만들기
- 4. 나만의 유튜브 사이트 만들기 : 섹션 컴퍼넌트 만들기
- 5. 나만의 유튜브 사이트 만들기 : 페이지 SEO 작업
- 6. 나만의 유튜브 사이트 만들기 : 메인 콘텐츠 만들기
- 7. 나만의 유튜브 사이트 만들기 : 추천 개발자 콘텐츠 만들기
- 8. 나만의 유튜브 사이트 만들기 : 나머지 페이지 콘텐츠 만들기
- 9. 나만의 유튜브 사이트 만들기 : 페이지 로딩 작업 만들기
- 10. 나만의 유튜브 사이트 만들기 : 서치 페이지 만들기
- 11. 나만의 유튜브 사이트 만들기 : 비디오 페이지 만들기
- 12. 나만의 유튜브 사이트 만들기 : 채널 페이지 만들기
- 13. 나만의 유튜브 사이트 만들기 : 마무리 및 배포하기
댓글