본문 바로가기
Tutorial/youtube

10. 나만의 유튜브 사이트 만들기 : 페이지 SEO 작업

by @webstoryboy 2023. 9. 15.
Tutorial/Portfolio

나만의 유튜브 사이트 만들기

by @webs 2023. 09. 01.
10
나만의 유튜브 사이트 만들기 : 페이지 SEO 작업
난이도 중간

소개

안녕하세요! 웹스토리보이입니다. 이 강의는 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 설정하기

10. 페이지 SEO 작업

10_1. 메인 페이지 SEO 설정하기

리액트는 싱글 페이지로 구성되어 있기 때문에 SEO에 대한 노출이 약한 편입니다. 그래서 리액트의 단점을 극복하기 위한 방법으로 페이지 별로 페이지에 대한 설명이나 타이틀을 작업해주겠습니다. 이 작업을 하기 위해서는 react-helmet-async 라이브러리가 설치되어 있어야 합니다.

SEO는 "Search Engine Optimization"의 약어로, 검색 엔진 최적화를 의미합니다. SEO는 웹사이트나 웹 페이지를 검색 엔진(예: Google, Bing, Yahoo)에서 높은 순위로 표시되도록 최적화하는 프로세스와 전략을 나타냅니다. 이를 통해 웹사이트가 검색 결과 페이지(SERP)에서 더 높은 순위에 나타나고, 더 많은 유기적(자연적) 트래픽을 확보하려는 목적으로 사용됩니다

main이라는 컴퍼넌트를 모든 페이지에서 사용하기 때문에 여기에 타이틀과 설명을 추가하는 SEO 잡업을 하였습니다.

import React from 'react'
import { Helmet, HelmetProvider } from 'react-helmet-async'

import Header from './Header'
import Footer from './Footer'

const Main = ( props ) => {
    return (
        <HelmetProvider>
            <Helmet 
                titleTemplate="%s | Webs Youtube" 
                defaultTitle="Webs Youtube" 
                defer={false}
            >
                {props.title && <title>{props.title}</title>}
                <meta name="description" content={props.description} />
            </Helmet>

            <Header />
            <main id="main" role="main">
                {props.children}
            </main>
            <Footer />
        </HelmetProvider>
    )
}

export default Main
  • HelmetProvider : react-helmet-async의 HelmetProvider 컴포넌트를 사용하여 Helmet 컴포넌트를 초기화합니다. Helmet은 페이지의 헤드 태그에 메타 데이터와 타이틀을 동적으로 추가하거나 변경하는 데 사용됩니다.
  • Helmet : Helmet 컴포넌트를 사용하여 페이지의 메타 데이터와 타이틀을 설정합니다. 이 컴포넌트를 사용하면 서버 사이드 렌더링(SSR) 및 동적 페이지 제목 설정과 같은 작업을 쉽게 수행할 수 있습니다. 주로 title, meta, link, script 등의 태그를 동적으로 조작하는 데 사용됩니다.
  • titleTemplate : 페이지 타이틀의 템플릿을 설정합니다. %s는 나중에 실제 타이틀로 대체됩니다.
  • defaultTitle : 기본 타이틀을 설정합니다. 페이지 타이틀이 없는 경우 사용됩니다.
  • defer : true로 설정하면 렌더링 전까지 <Helmet> 컴포넌트가 기다립니다.
  • <title>과 <meta> 태그 : props로 전달된 title과 description 값을 사용하여 페이지의 타이틀과 메타 설명을 설정합니다. props.title과 props.description이 없는 경우, 기본값으로 "Webs Youtube"가 타이틀로 설정됩니다.

10_2. 모든 페이지 SEO 설정하기

이제 나머지 페이지도 main 컴퍼넌트를 불러오고 페이지 별로 타이틀과 설명을 추가하면 됩니다. 그럼 페이지가 변경되면 타이틀이 변경되는 것을 확인할 수 있습니다.

import React from 'react'
import Main from '../components/section/Main'

const Channel = () => {
    return (
        <Main 
            title = "유튜브 채널"
            description="유튜브 채널페이지입니다.">
            Channel
        </Main>
    )
}

export default Channel
import React from 'react'
import Main from '../components/section/Main'

const Developer = () => {
    return (
        <Main 
            title = "추천 개발자"
            description="오늘의 추천 개발자 유튜버입니다.">
            Developer
        </Main>
    )
}

export default Developer
import React from 'react'
import Main from '../components/section/Main'

const Gsap = () => {
    return (
        <Main 
            title = "GSAP 사이트"
            description="GSAP 사이트 튜토리얼 강의입니다.">
            Gsap
        </Main>
    )
}

export default Gsap
import React from 'react'
import Main from '../components/section/Main'

const Home = () => {
    return (
        <Main 
            title = "웹스토리보이 유튜브"
            description="웹스토리보이 유튜버 사이트에 오신 것을 환영합니다.">
            Home
        </Main>
    )
}

export default Home
import React from 'react'
import Main from '../components/section/Main'

const Not = () => {
    return (
        <Main 
            title = "잘못된 페이지"
            description="접근이 잘못된 페이지입니다.">
            Not
        </Main>
    )
}

export default Not
import React from 'react'
import Main from '../components/section/Main'

const Port = () => {
    return (
        <Main 
            title = "포트폴리오 사이트"
            description="포트폴리오 사이트 튜토리얼 강의입니다.">
            Port
        </Main>
    )
}

export default Port
import React from 'react'
import Main from '../components/section/Main'

const Search = () => {
    return (
        <Main 
            title = "유투브 검색"
            description="유튜브 검색 결과 페이지입니다.">
            Search
        </Main>
    )
}

export default Search
import React from 'react'
import Main from '../components/section/Main'

const Today = () => {
    return (
        <Main 
            title = "추천 영상"
            description="오늘의 추천 유튜브 영상입니다.">
            Today
        </Main>
    )
}

export default Today
import React from 'react'
import Main from '../components/section/Main'

const Video = () => {
    return (
        <Main 
            title = "유튜브 비디오 영상"
            description="유튜브 비디오 영상을 볼 수 있습니다.">
            Video
        </Main>
    )
}

export default Video
import React from 'react'
import Main from '../components/section/Main'

const Webd = () => {
    return (
        <Main 
            title = "웹디자인 기능사"
            description="웹디자인 기능사 튜토리얼 강의입니다.">
            Webd
        </Main>
    )
}

export default Webd
import React from 'react'
import Main from '../components/section/Main'

const Website = () => {
    return (
        <Main 
            title = "웹표준 사이트"
            description="웹표준 사이트 튜토리얼 강의입니다.">
            Website
        </Main>
    )
}

export default Website
import React from 'react'
import Main from '../components/section/Main'

const Youtube = () => {
    return (
        <Main 
            title = "유튜브 사이트"
            description="유튜브 사이트 튜토리얼 강의입니다.">
            Youtube
        </Main>
    )
}

export default Youtube

페이지 이동 할 때마다 타이틀이 변경되는 것을 확인할 수 있습니다.

youtube2023

마무리

git 올리기

터미널에서 다음과 같이 작성하겠습니다. 새로운 페이지가 올라오는 것을 확인 할 수 있습니다.

webstoryboyhwang@Webstoryboyui-MacBookPro webs-youtube % git add .
webstoryboyhwang@Webstoryboyui-MacBookPro webs-youtube % git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
    (use "git restore --staged <file>..." to unstage)
        modified:   src/components/section/Main.jsx
        modified:   src/pages/Channel.jsx
        modified:   src/pages/Developer.jsx
        modified:   src/pages/Gsap.jsx
        modified:   src/pages/Home.jsx
        modified:   src/pages/Not.jsx
        modified:   src/pages/Port.jsx
        modified:   src/pages/Search.jsx
        modified:   src/pages/Today.jsx
        modified:   src/pages/Video.jsx
        modified:   src/pages/Webd.jsx
        modified:   src/pages/Website.jsx
        modified:   src/pages/Youtube.jsx

webstoryboyhwang@Webstoryboyui-MacBookPro webs-youtube % git commit -m "페이지 SEO 작업"
[main 4276736] 페이지 SEO 작업
    13 files changed, 54 insertions(+), 19 deletions(-)
webstoryboyhwang@Webstoryboyui-MacBookPro webs-youtube % git push -u origin main
Enumerating objects: 37, done.
Counting objects: 100% (37/37), done.
Delta compression using up to 10 threads
Compressing objects: 100% (18/18), done.
Writing objects: 100% (19/19), 2.32 KiB | 2.32 MiB/s, done.
Total 19 (delta 13), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (13/13), completed with 3 local objects.
To https://github.com/webstoryboy/webs-youtube.git
    813080f..4276736  main -> main
branch 'main' set up to track 'origin/main'.

라이브러리 소스를 이용하여 모든 페이지에 타이틀 작업 및 설명 부분을 완성하였습니다. 이렇게 한다고 해도 검색에 잘 노출될지는 의문이지만 그래도 안하는 것보단 낫겠죠! 수고하셨습니다 🤩


예제 목록

댓글