Dynamic React Sitemap 만들기 (feat. React-Router-Sitemap)

React로 앱을 만들고 배포하다보면 구글서치콘솔과 연결이 필요한 순간이 있었습니다.

Google 애드센스와 공유하기 전에 크롤러가 내 사이트를 잘 크롤링하고 사이트가 활성화되었을 때 사용자 동향도 추적하는 것을 확인했습니다.

이렇게 해주는 기능이 있기 때문에 내 도메인과의 연결이 필수입니다.

하지만 SPA(Single Page Application)이기 때문에 크롤러가 페이지를 크롤링하고 인덱싱하는 데 어려움이 있었습니다.

사이트맵 자체가 인덱싱에 큰 도움이 된다는 것은 아니지만 안 하는 것보다는 나을 것 같다는 생각이 들었습니다.

Google 검색을 통해 React로 사이트맵을 수동으로 만드는 방법을 검색했습니다.


있습니다.
.이 경로가 지정되어 있습니까?

검색하면 할수록 날짜가 터무니없이 작다는 느낌이 듭니다.
물론 내가 쓴 편지가 독자에게 맞는 상황이라면 좋겠죠.

내가 겪는 상황은 항상 나에게 특별하게 느껴졌다.

최근 Google 검색에 대한 응답으로 사이트맵을 생성하려면

npm i --save react-router-sitemap

react 프로젝트에 react-router-sitemap 설치 후

sitemapRoutes.js 파일을 만듭니다.

import React from 'react';
import {  Route } from 'react-router';
 
export default (
  <Route>
    <Route path="/" />
    <Route path="/login" />
    <Route path="/join" />
  </Route>
);

이때 기본 SitemapRoutes 내보내기 부분은 라우팅을 담당하는 구성 요소에서 사이트맵을 만들어야 하는 부분을 가져옵니다.

“element={}” 부분을 삭제하고 Routes를 Route로 변경합니다.

마지막으로 sitemapGenerator.js에 다음 코드를 입력하고 빌드 파일 생성 시 sitemap.xml을 생성할 스크립트를 등록합니다.

require("babel-register")({
  presets: ("es2015", "react")
});
 
const router = require("./sitemapRoutes").default; // sitemapRoutes.js의 경로
const Sitemap = require("react-router-sitemap").default;

function generateSitemap() {
    return (
      new Sitemap(router)
          .build("https://enter_your_domain_name")
          .save("./public/sitemap.xml") // sitemap.xml 파일이 생성될 위치
    );
}

generateSitemap();

아래에서는 React에서 사이트맵을 만드는 방법에 대한 자세한 방법이 많기 때문에 기사는 건너뛰겠습니다.

그러나 아래와 같이 라우팅을 내부적으로 구현하는 생성에는 문제가 있습니다.

      <Routes>
        <Route path="/" element={<App />}>
          <Route index element={<MainScreens />} />
          <Route path="login" element={<LoginPage />} />
          <Route path="join" element={<JoinPage />} />
          <Route path="my-page/:id" element={<MyPage />} />
       </Routes>

React에서 동적 라우팅을 구현했을 텐데 예상되는 값은 “/my-page/ASJ2ASDAD#ASD3” 등입니다.
ID 뒤에

예를 들어 값을 할당하려고 합니다.
나. 실제 방문한 이용자의 아이디. /mypage/:id 접속시 당연히 404는 찾을 수 없습니다.

그런데 아래와 같이 사이트맵이 생성되었습니다.
이것은 내가 기대했던 것과 다릅니다.

물론 이렇게 등록하면 크롤러가 이 주소를 방문하게 되고 인덱싱은 하지 않습니다.

<url> <loc>https://www.mydomain.co.kr/my-page/:id</loc> </url>

동적 라우팅을 구현해 보겠습니다.

동적 라우팅을 구현하려면 이전에 구현한 sitemapRoutes.js 및 sitemapGenerator.js를 수정해야 합니다.

import React from "react";
import { Route } from "react-router";
import fetch from "node-fetch";

const getUrl = async () => {
  const data = await fetch("http://localhost:4001/articles");
  const result = await data.json();
  const urlArray = await result.data.map((article) => {
    return article._id;
  });
  
  const temp = (
    <Route path="/">
      <Route index />
      <Route path="login" />
      <Route path="join" />
      {urlArray.map((url) => {
        return <Route path={`article/${url}`} />;
      })}
      ...
      <Route path="/about" />
    </Route>
  );
  return temp;
};
const getRoute = async () => {
  const route = await getUrl();
  return route;
};
export default getRoute();​

아이템에 대한 정보를 데이터베이스에서 불러와야 하는 상황에서 불러와서 데이터를 받고,

urlArray에 항목의 ID 값을 저장한 후 temp를 선언하여 사이트맵을 생성하기 위한 경로로 초기화합니다.

urlArray에 포함된 :id에 할당할 값은 map 함수를 통해 route 및 temp로 반환됩니다.

그런 다음 getRoute 함수를 선언하여 경로를 비동기 함수로 가져오고 내부적으로 getUrl()을 실행한 다음 경로를 반환합니다.

이때 내보내기 값은 getRoute를 실행하여 얻은 값이다.

require("babel-register")({
  presets: ("es2015", "react"),
});

const router = require("./sitemapRoutes").default; // 좀 전에 만든 sitemapRoutes 파일이 있는 경로입니다.
const Sitemap = require("react-router-sitemap").default; function generateSitemap() { return router.then((route) => { return new Sitemap(route) .build("https://your_domain_name") // 여러분의 도메인 이름으로 변경해주세요. .save("./public/sitemap.xml"); // sitemap.xml 파일이 생성될 위치입니다.
}); } generateSitemap();

그런 다음 다음과 같이 generateSitemap 함수를 수정하면 동적으로 할당된 URL에 대한 사이트맵을 생성할 수 있습니다.

라우터 자체가 비동기식이므로 직접 액세스는 약속에 액세스합니다.

따라서 then()에 의해 반환된 경로에 액세스하여 사이트맵의 인수로 전달합니다.


사이트맵을 만들 때 주의할 점

사이트맵을 만들 때 관리자 페이지나 로그인 후 볼 수 있는 콘텐츠는 제외하는 것이 좋습니다.
(어쨌든 크롤러가 액세스할 수 없기 때문에)

예를 들어, 로그인해야만 볼 수 있는 마이페이지 화면이나 사용자가 만든 콘텐츠를 변경해야 하는 변경 페이지 등이 있습니다.

크롤러가 접근할 수 없고 404 상태코드를 반환하여 빠른 페이지 인덱스를 원하신다면 이 부분을 참고하여 라우트를 등록하시면 됩니다.