a. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
b. <meta name="description" content="캐스퍼에 당첨될 수 있는 기회!! 이벤트 참여하고 캐스퍼 EV를 받아가세요!!" />
c. <meta property="og:${title, description, image}" />
💡 Does not support SVG image - meta tag 에 이미지 형식은 svg 가 안된다!!! ⇒ png, jpg 사용
a. react-helmet-async 설치
yarn add react-helmet-async
b. App.js 에서 HelmetProvider를 사용하여 감싸준다.
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개의 큰 컴포넌트에만 적용
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
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에 미치는 영향
다양한 라이브러리를 찾아보다가
다음 3개의 라이브러리를 주요 사용하는 것을 확인할 수 있었다.
우선 2번인 react-snapshot 의 경우 1번과 거의 유사하지만 다운로드 수도 적고 거의 사용하지 않는다는 사실을 알 수 있었다.
1번인 react-snap 은 많이 활용되는 라이브러리였지만 CRA와 잘 통합되고 React18버전을 제대로 지원하지 않기 때문에 React의 버전을 17로 다운시켜야 한다는 단점이 있었다.
Vite와 React 18 환경에서 Hybrid Approach를 구현하려면 Puppeteer와 Prerender를 사용하는 것이 가장 유연하고 강력한 방법이다.
실행 순서
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;
를 통해 해결할 수 있다.
prerendering 기술은 SSG 방식과 유사한 것 같지만, 약간의 차이점이 존재합니다.
둘다 빌드 시점에 정적인 html 파일을 만들지만, prerendering은 완성된 리액트 페이지를 캡쳐해서, 미리 크롤러에게 정보를 제공하고 사용자에게 빠른 화면을 보여줄 수 있는 기술이라고 생각하면 되겠습니다..! 따라서 기술적 요구사항에 맞게 next와 같은 ssr 프레임워크를 선택하거나, Prerendering 기술을 적용하여 SEO를 최적화하는 것이 필요하다고 생각합니다!!!