-
Notifications
You must be signed in to change notification settings - Fork 2
SEO 최적화
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="description"
content="캐스퍼에 당첨될 수 있는 기회!! 이벤트 참여하고 캐스퍼 EV를 받아가세요!!"
/>
<meta property="og:title" content="캐스퍼 이벤트" />
<meta
property="og:description"
content="캐스퍼에 당첨될 수 있는 기회!! 이벤트 참여하고 캐스퍼 EV를 받아가세요!!"
/>
<meta
property="og:image"
content="https://softeer4-team8.s3.ap-northeast-2.amazonaws.com/%E1%84%86%E1%85%B5%E1%84%82%E1%85%B5+%E1%84%8F%E1%85%B1%E1%84%8C%E1%85%B3+7.svg"
/>
a. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- 역할: 이 메타 태그는 웹페이지가 다양한 디바이스에서 잘 표시되도록 화면의 크기를 조정한다.
- SEO 효과: 검색 엔진은 반응형 디자인(모바일 친화적)을 선호한다. 이 태그는 모바일 디바이스에서 페이지가 올바르게 표시되도록 하여, 모바일 사용자 경험을 향상시키고, 모바일 검색 결과에서의 순위를 높이는 데 기여함.
b. <meta name="description" content="캐스퍼에 당첨될 수 있는 기회!! 이벤트 참여하고 캐스퍼 EV를 받아가세요!!" />
- 역할: 페이지의 내용을 간략히 설명하는 메타 태그이다.
- SEO 효과: 이 설명은 검색 엔진 결과 페이지(SERP)에서 페이지 제목 아래에 표시되며, 클릭률(CTR)에 큰 영향을 미친다. 잘 작성된 메타 설명은 더 많은 클릭을 유도할 수 있고, 높은 클릭률은 검색 엔진 알고리즘에 긍정적인 신호를 보내 순위를 높이는 데 도움을 줄 수 있다.
c. <meta property="og:${title, description, image}" />
- 역할: Open Graph 프로토콜을 사용하여 소셜 미디어에서 페이지가 공유될 때 표시되는 제목, 설명, 이미지를 정의한다.
- SEO 효과: 이 제목, 설명, 이미지는 소셜 미디어에서 페이지가 공유될 때 나타난다. 해당 기능은 사용자에게 페이지를 방문하도록 유도할 수 있으며, 이는 트래픽 증가로 이어져 SEO에 긍정적인 영향을 미칠 수 있다.
a. react-helmet-async 설치
```jsx
yarn add react-helmet-async
```
b. App.js 에서 HelmetProvider를 사용하여 감싸준다.
```jsx
import React from 'react';
import { HelmetProvider } from 'react-helmet-async';
import { Outlet } from 'react-router-dom';
function App() {
return (
<HelmetProvider>
<Outlet />
</HelmetProvider>
);
}
export default App;
```
c. 컴포넌트에서 Helmet
사용 ⇒ Header 탭에 있는 3개의 큰 컴포넌트에만 적용
```jsx
import React from 'react';
import EventIntroMain from '@/pages/eventIntro/EventIntroMain';
import EventIntroNav from '@/pages/eventIntro/EventIntroNav';
import EventIntroRewards from '@/pages/eventIntro/EventIntroRewards';
import { animationVariants } from '@/styles/FramerMotion';
import { motion } from 'framer-motion';
import { Helmet } from 'react-helmet-async';
function EventIntro() {
return (
<div>
<Helmet>
<title>캐스퍼 이벤트 소개</title>
<meta
name="description"
content="캐스퍼 EV를 받을 수 있는 이벤트에 대해 자세히 알아보세요. 이벤트 참여 방법과 다양한 보상을 소개합니다."
/>
<meta property="og:title" content="캐스퍼 이벤트 소개" />
<meta
property="og:description"
content="캐스퍼 EV를 받을 수 있는 이벤트에 참여해보세요!"
/>
<meta
property="og:image"
content="https://softeer4-team8.s3.ap-northeast-2.amazonaws.com/%E1%84%86%E1%85%B5%E1%84%82%E1%85%B5+%E1%84%8F%E1%85%B1%E1%84%8C%E1%85%B3+7.svg"
/>
</Helmet>
<EventIntroMain />
<div className="bg-gradient-lightblue-white-vertical mt-[1px]">
<EventIntroNav />
<motion.div
initial="hidden"
animate="visible"
variants={animationVariants}
transition={{
duration: 0.6,
ease: 'easeOut',
delay: 0.1,
}}
>
<EventIntroRewards />
</motion.div>
</div>
</div>
);
}
export default EventIntro;
```
해당 코드는 예시 코드로 탭에 있는 페이지 중 하나를 맡고 있는 코드이다.
가장 부모요소 바로 아래에 Public/index.html 에서 meta태그를 적용하는 방식과 동일하게 작성하고 바깥을 **`<Helmet></Helmet>`** 으로 감싸주면 적용이 된다.
a. Robot.txt
```jsx
User-agent: *
Allow: /public/
Sitemap: https://casper-event.store/sitemap.xml
```
robots.txt
파일은 웹사이트의 루트 디렉토리에 위치하며, 검색 엔진 크롤러(또는 봇)에게 어떤 페이지나 디렉토리를 크롤링할 수 있는지 또는 할 수 없는지를 지시한다.
이 파일은 웹사이트의 크롤링 규칙을 정의하여 검색 엔진이 어떻게 사이트를 탐색할지 결정하는 데 도움을 준다.
SEO에 미치는 영향
-
크롤링 제어:
robots.txt
파일을 통해 특정 페이지나 디렉토리에 대한 크롤링을 차단함으로써, 검색 엔진이 중요하지 않거나 중복된 콘텐츠를 색인하지 않도록 할 수 있다. 예를 들어, 로그인 페이지나 관리자 페이지는 검색 엔진에 노출될 필요가 없으므로 이를 차단할 수 있다. - 서버 리소스 절약: 크롤러가 불필요한 페이지를 크롤링하지 않도록 하여 서버 리소스를 절약할 수 있다. 이는 서버에 대한 부하를 줄이고 사이트의 성능을 유지하는 데 도움이 된다.
- 중복 콘텐츠 방지: 사이트 내 중복 콘텐츠가 있는 경우, 검색 엔진이 중복 페이지를 색인하는 것을 방지하여 검색 엔진의 혼동을 줄일 수 있다.
b. sitemap.xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://casper-event.store/</loc>
<lastmod>2024-08-21</lastmod>
<priority>1.0</priority>
</url>
<url>
<loc>https://casper-event.store/event</loc>
<lastmod>2024-08-21</lastmod>
<priority>0.8</priority>
</url>
<url>
<loc>https://casper-event.store/introduce</loc>
<lastmod>2024-08-21</lastmod>
<priority>0.6</priority>
</url>
</urlset>
sitemap.xml
파일은 웹사이트의 모든 페이지에 대한 정보를 담고 있으며, 검색 엔진 크롤러에게 사이트의 구조를 알려준다. 이 파일은 사이트의 모든 URL을 나열하고, 각 페이지의 우선순위, 변경 날짜, 업데이트 빈도 등을 제공하여 크롤러가 페이지를 보다 효과적으로 탐색할 수 있도록 합니다.
SEO에 미치는 영향
- 검색 엔진 색인 향상: 검색 엔진이 웹사이트의 페이지를 보다 빠르고 정확하게 색인할 수 있도록 돕는다. 특히, 사이트 구조가 복잡하거나 페이지가 자주 업데이트되는 경우 유용하다.
- 우선순위 제공: 사이트맵에서 각 페이지의 중요도를 정의할 수 있어, 검색 엔진이 더 중요한 페이지를 우선적으로 크롤링하고 색인할 수 있다.
- 크롤러 효율성 향상: 크롤러가 사이트의 모든 페이지를 발견하고 탐색할 수 있도록 보장하여, 누락된 페이지가 없도록 한다.
다양한 라이브러리를 찾아보다가
- react-snap
- react-snapshot
- Puppeteer와 Prerender
다음 3개의 라이브러리를 주요 사용하는 것을 확인할 수 있었다.
우선 2번인 react-snapshot 의 경우 1번과 거의 유사하지만 다운로드 수도 적고 거의 사용하지 않는다는 사실을 알 수 있었다.
1번인 react-snap 은 많이 활용되는 라이브러리였지만 CRA와 잘 통합되고 React18버전을 제대로 지원하지 않기 때문에 React의 버전을 17로 다운시켜야 한다는 단점이 있었다.
Vite와 React 18 환경에서 Hybrid Approach를 구현하려면 Puppeteer와 Prerender를 사용하는 것이 가장 유연하고 강력한 방법이다.
- 동적 컨텐츠 처리: Puppeteer를 사용하여 동적 컨텐츠와 사용자 상호작용을 포함한 페이지를 사전 렌더링할 수 있다.
- 서버 사이드 렌더링 유사 효과: 서버 사이드에서 페이지를 렌더링하여 SEO와 초기 로딩 성능을 개선할 수 있다.
- Vite와의 호환성: Vite 프로젝트와 잘 통합될 수 있으며, 설정을 통해 Vite 빌드 결과물에 적용할 수 있다.
실행 순서
a. 패키지 설치
```jsx
yarn add puppeteer
```
b. vite.config.js 파일 수정 ( vite 환경에서만 !!! )
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react-swc';
import { resolve } from 'path';
import svgr from 'vite-plugin-svgr';
import prerender from '@prerenderer/rollup-plugin';
import dotenv from 'dotenv';
dotenv.config();
export default defineConfig({
plugins: [
react(),
svgr(),
prerender({
routes: [
'/',
'/event',
'/event/worldCup',
'/event/miniQuiz',
'/introduce',
],
renderer: '@prerenderer/renderer-puppeteer',
rendererOptions: {
maxConcurrentRoutes: 1,
renderAfterTime: 500,
},
postProcess(renderedRoute) {
const apiUrl = process.env.VITE_API_URL;
renderedRoute.html = renderedRoute.html
.replace(/http:/i, 'https:')
.replace(/(https:\/\/)?(localhost|127\.0\.0\.1):\d*/i, apiUrl);
},
}),
],
resolve: {
alias: [
{ find: '@', replacement: resolve(__dirname, 'src') },
{ find: '@pages', replacement: resolve(__dirname, 'src/pages') },
],
},
});
위의 코드가 우리 프로젝트의 전체 vite.config.js 이며 prerender를 import 하고
routes에 적용한 주소를 적어주고 postProcess 에 서버를 적어줘야 한다.
이때 서버를 로컬에서 돌리면 apiUrl 대신 localhost:3000을 적어주면 되고 만약 배포되어 있는 서버인 경우
.env 파일에서 가져와야 하는데 vite.config.js. 파일은 빌드 도구 이기때문에 직접적으로 가져올 수 있는 방법이 없다.
따라서 api 통신에서 사용하는 방법과 같이 가져오게 되면
위와 같은 에러를 볼 수 있다.
“VITE_API_URL” 이 undefined이다.
-
dotenv 패키지 설치
yarn add dotenv
-
vite.config.js 파일 수정
import dotenv from 'dotenv'; dotenv.config();
-
apiUrl 가져오기
const apiUrl = process.env.VITE_API_URL;
를 통해 해결할 수 있다.
lighthouse 로 적용하기 전의 SEO 점수를 확인했을 때
lighthouse 로 적용한 후 SEO 점수를 확인했을 때
SEO 점수가 100점까지 오른 것을 확인해 볼 수 있다.