나만의 유튜브 사이트 만들기
소개
안녕하세요! 웹스토리보이입니다. 이 강의는 React 프레임워크와 YouTube API를 이용하여 자신만의 간단한 영상 사이트를 만들어보겠습니다. React의 기본 개념을 이해하고, 컴포넌트를 구조화하고 상태를 관리하는 방법을 학습하게 될 것입니다. 또한 YouTube Data API를 활용하여 외부 데이터를 가져오는 방법을 익히고, API 응답을 처리하여 사용자에게 의미 있는 정보를 제공하는 방법을 이해하게 됩니다. 이로써 자신만의 유튜브 사이트를 만들고, 활용해보는 것을 목표로 합니다. 그럼 한번 시작해볼까요? 🥳
인덱스
- 1. 셋팅하기
- 1_1. Node.js 설치
- 1_2. Vscode 설치
- 1_3. React.js 설치
- 2. 라이브러리 설치하기
- 2_1. 폴더 정리하기
- 2_2. 라이브러리 설치하기
- 3. Git 연동하기
- 3_1. 저장소 만들기
- 3_2. 모든 파일 올리기
- 3_3. 깃 상태 확인하기
- 4. SCSS 셋팅하기
- 4_1. SCSS 설정하기
- 4_2. style.scss 설정하기
- 4_3. fonts.scss 설정하기
- 4_4. vars.scss 설정하기
- 4_5. reset.scss 설정하기
- 4_6. mixin.scss 설정하기
- 4_7. common.scss 설정하기
- 5. 페이지 만들기
- 5_1. 페이지 만들기
- 5_2. 페이지 컴퍼넌트 만들기
- 6. 섹션 컴퍼넌트 구조화하기
- 6_1. 전체 레이아웃 만들기
- 6_2. 섹션 컴퍼넌트 만들기
- 7. 헤더 영역 완성하기
- 7_1. 헤더 영역 구조 잡기
- 7_2. 헤더 영역 디자인 작업
- 8. 헤더 영역 데이터 작업
- 8_1. 헤더 영역 데이터 작업
- 8_2. 반복문과 map()
- 8_3. 메뉴 활성화하기
- 8_4. 컴퍼넌트 세부화 시키기
- 9. 컴퍼넌트 비동기 작업
- 8_1. 컴퍼넌트 props 사용하기
- 8_2. React.Suspense 사용하기
- 10. 페이지 SEO 작업
- 10_1. 메인 페이지 SEO 설정하기
- 10_2. 모든 페이지 SEO 설정하기
- 11. 메인 콘텐츠 작업
- 11_1. 검색 컴퍼넌트 작업하기
- 11_2. 메인 컴퍼넌트 작업하기
- 12. 추천 영상 작업
- 12_1. 메인 추천 영상 작업
- 12_2. 추천 영상 반응형 작업
- 12_3. 추천 영상 페이지 작업
- 13. 추천 개발자 작업
- 13_1. 메인 추천 개발자 작업
- 13_2. 추천 개발자 페이지 작업
13. 추천 개발자 작업
13_1. 메인 추천 개발자 작업
메인 페이지의 오늘의 추천 개발자 섹션을 작업하겠습니다. 데이터는 다 만들어 놨기 때문에 복사해서 사용하시면 될 거 같습니다. 이미지는 상단 소스 받기에서 다운 받으시면 됩니다.
우선 데이터를 추가하겠습니다.
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"
}
]
components
> contents
> Developer.jsx
파일을 수정하겠습니다.
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="developer__inner overflow">
{developerText.map((developer, key) => (
<div className="developer" key={key}>
<div className="developer__img play__icon">
<Link to={`/channel/${developer.channelId}`}>
<img src={developer.img} alt={developer.name} />
</Link>
</div>
<div className="developer__info">
<Link to={`/channel/${developer.channelId}`}>
{developer.name}
</Link>
</div>
</div>
))}
</div>
</section>
)
}
export default Developer
scss
> section
> _developer.scss
파일을 수정하겠습니다.
SCSS 파일을 추가하면 style.scss
에 추가하여야 연동이 됩니다.
.developer__inner {
display: flex;
flex-wrap: wrap;
&.overflow {
width: 100%;
height: 200px;
overflow: hidden;
}
.developer {
margin-right: 20px;
.developer__img {
width: 150px;
height: 150px;
border-radius: 50%;
overflow: hidden;
margin-bottom: 10px;
}
.developer__info {
width: 150px;
text-align: center;
@include line-one;
padding-bottom: 40px;
}
}
}
@media (max-width: 1200px){
.developer__inner {
justify-content: center;
.developer {
margin-right: 0;
.developer__img {
width: 130px;
height: 130px;
margin: 10px auto;
}
.developer__info {}
}
}
}
@media (max-width: 800px){
.developer__inner {
margin-top: 70px;
}
}
추천 개발자 메인 페이지 결과물입니다.
13_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="developer__inner">
{developerText.map((developer, key) => (
<div className="developer" key={key}>
<div className="developer__img play__icon">
<Link to={`/channel/${developer.channelId}`}>
<img src={developer.img} alt={developer.name} />
</Link>
</div>
<div className="developer__info">
<Link to={`/channel/${developer.channelId}`}>
{developer.name}
</Link>
</div>
</div>
))}
</div>
</section>
</Main>
)
}
export default Developer
추천 개발자 페이지 결과물입니다.
마무리
git 올리기
터미널에서 다음과 같이 작성하겠습니다. 새로운 페이지가 올라오는 것을 확인 할 수 있습니다.
webstoryboy@Webstoryboyui-iMac webs-youtube % git add .
webstoryboy@Webstoryboyui-iMac webs-youtube % git status
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git restore --staged ..." to unstage)
new file: src/assets/scss/section/_developer.scss
modified: src/assets/scss/style.scss
modified: src/components/contents/Developer.jsx
new file: src/data/developer.js
modified: src/pages/Developer.jsx
webstoryboy@Webstoryboyui-iMac webs-youtube % git commint -m "추천 개발자 작업"
git: 'commint' is not a git command. See 'git --help'.
The most similar command is
commit
webstoryboy@Webstoryboyui-iMac webs-youtube % git push -u origin main
branch 'main' set up to track 'origin/main'.
Everything up-to-date
webstoryboy@Webstoryboyui-iMac webs-youtube % git commit -m "추천 개발자 작업"
[main 60c5b4e] 추천 개발자 작업
5 files changed, 334 insertions(+), 5 deletions(-)
create mode 100644 src/assets/scss/section/_developer.scss
create mode 100644 src/data/developer.js
webstoryboy@Webstoryboyui-iMac webs-youtube % git push -u origin main
Enumerating objects: 26, done.
Counting objects: 100% (26/26), done.
Delta compression using up to 8 threads
Compressing objects: 100% (15/15), done.
Writing objects: 100% (15/15), 5.49 KiB | 5.49 MiB/s, done.
Total 15 (delta 7), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (7/7), completed with 6 local objects.
To https://github.com/webstoryboy/webs-youtube.git
e538766..60c5b4e main -> main
branch 'main' set up to track 'origin/main'.
추천 개발자 섹션과 페이지를 완성하였습니다. 이 부분은 나중에 이미지 슬라이드를 구현하기 때문에 반응형은 페이지에만 작업을 하였습니다. 오늘도 수고하셨습니다. 😘
예제 목록
- 1. 나만의 유튜브 사이트 만들기 : 셋팅하기
- 2. 나만의 유튜브 사이트 만들기 : 라이브러리 설치하기
- 3. 나만의 유튜브 사이트 만들기 : Git 연동하기
- 4. 나만의 유튜브 사이트 만들기 : SCSS 셋팅하기
- 5. 나만의 유튜브 사이트 만들기 : 페이지 만들기
- 6. 나만의 유튜브 사이트 만들기 : 섹션 컴퍼넌트 구조화하기
- 7. 나만의 유튜브 사이트 만들기 : 헤더 영역 완성하기
- 8. 나만의 유튜브 사이트 만들기 : 헤더 영역 데이터 작업
- 9. 나만의 유튜브 사이트 만들기 : 컴퍼넌트 비동기 작업
- 10. 나만의 유튜브 사이트 만들기 : 페이지 SEO 작업
- 11. 나만의 유튜브 사이트 만들기 : 메인 콘텐츠 작업
- 12. 나만의 유튜브 사이트 만들기 : 추천 영상 작업
- 13. 나만의 유튜브 사이트 만들기 : 추천 개발자 작업
- 14. 나만의 유튜브 사이트 만들기 : 메인 섹션 나머지 콘텐츠 작업
- 15. 나만의 유튜브 사이트 만들기 : 비디오 컴퍼넌트 통합 작업
- 16. 나만의 유튜브 사이트 만들기 : Swiper 이미지 슬라이드 작업
- 17. 나만의 유튜브 사이트 만들기 : 나머지 페이지 작업
- 18. 나만의 유튜브 사이트 만들기 : 검색 및 유튜브 API 설정하기
- 19. 나만의 유튜브 사이트 만들기 : Rapid API 및 더보기 설정하기
- 20. 나만의 유튜브 사이트 만들기 : 비디오 상세 페이지 만들기
- 21. 나만의 유튜브 사이트 만들기 : 채널 상세 페이지 만들기
- 22. 나만의 유튜브 사이트 만들기 : 버그 고치기
- 23. 나만의 유튜브 사이트 만들기 : 빌드 및 배포하기
댓글