Next 기반에서 작업했지만 Next라는 게 딱히 중요하지는 않습니다.
robots.txt
공식문서(nextjs.org/docs/basic-features/static-file-serving)에 따르면 public 폴더 안에 두는 것이 좋다고 합니다.
관리자 페이지와 같이 크롤러가 접근하면 안되는 부분은 막아둬야겠죠.
robots.txt 구성방법은 naver 측에 잘 정리가 되어 있습니다.
searchadvisor.naver.com/guide/seo-basic-robots
사이트에 접근하는 특정 봇의 이름을 알고 싶다면 아래 포스트의 방식을 사용합시다.
searchadvisor.naver.com/guide/seo-basic-firewall
cf) 웹사이트/robots.txt를 입력하면 해당 웹사이트의 로봇 접근 정책을 확인할 수 있습니다.
https://www.google.com/robots.txt
https://www.naver.com/robots.txt
- 모든 로봇에 대해서(*) 모든 곳에 접근을 허용하지 않는다(/) : 네이버
User-agent: *
Disallow: /
- 모든 로봇에 대해서(*) 어떤 곳에는 접근을 허용하나 다른 곳에는 허용하지 않는다. : 구글
User-agent: *
Disallow: /search
Allow: /search/about
Allow: /search/static
Allow: /search/howsearchworks
...(중략)
- 로봇 별로 다른 권한을 준다 : 위키피디아는 각 로봇의 특성을 따져 각기 다른 권한을 주고 있습니다.
# Some bots are known to be trouble, particularly those designed to copy
# entire sites. Please obey robots.txt.
User-agent: sitecheck.internetseer.com
Disallow: /
User-agent: Zealbot
Disallow: /
...(중략)
cf) CRA(create-react-app)를 통해서 React.js 프로젝트를 시작하면 public 폴더 내에 robots.txt가 있음을 볼 수 있습니다. 적절하게 설정해줍시다.
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
* 서브 도메인은 서브 도메인을 적용하지 않은 사이트와 동일한 웹사이트로 취급된다.
예를 들어 현재 내 티스토리는 (https://darrengwon.tistory.com)이다. darrengwon의 sub domain과 관계없이 https://tistory.com으로 인식되기 때문에 티스토리를 비롯한 각종 블로그들은 검색어 순위에서 상위에 노출되기가 사실상 불가능하다. 즉, 개인 서비스를 런칭하기 위해서는 개인 도메인을 사용해야 한다는 결론을 내릴 수 있다.
그래서 현재는 기타 크롤러를 막고, googlebot, naver만 허용하기 위해 아래와 같이 작성해두었습니다.
추가로, Sitemap을 크롤러가 찾을 수 있도록 Sitemap을 설정해두었습니다.
그러나 robots.txt를 참고하도록 봇을 설계하는 건 설계자의 선택이기 때문에 robots.txt가 모든 크롤러에게 적용될 것이라고 기대하지는 않는 것이 좋습니다.
User-agent: *
Disallow: /
# Google Search
User-agent: Googlebot
Allow : /
Disallow: /api*/
Disallow: /oauth*/
Disallow: /userprofile*/
# Naver Search
User-agent: Yeti
Allow: /
Disallow: /api*/
Disallow: /oauth*/
Disallow: /userprofile*/
Sitemap: https://www.cineps.net/sitemap.xml
만약 robots.txt를 사용할 수 없는 환경(예를 들어 티스토리 html 편집과 같은)에서 크롤러를 막고 싶다면 다음과 같은 meta 태그를 사용합시다.
<meta name="robots" content="noindex, nofollow"/>
sitemap.xml
우선 sitemap.xml이 어떤 형태로 생겼는지 살펴보자
xml을 감싸고 있는 태그는 고정이므로 생략하고, 내부에 반복되는 태그에 대한 기능은 다음과 같습니다.
<url> (필수) - 각 URL 항목의 상위태그, 즉 내 사이트 한 페이지를 규정하기 위한 시작 태그입니다.
<loc> (필수) - 페이지의 URL, 2048자 미만으로 작성되어야 하며, http와 같은 프로토콜로 시작해야 합니다. 단순하게 말해서 내 글의 주소입니다.
<lastmod> (선택옵션) - 파일을 마지막으로 수정한 날입니다.
<changefreq> (선택옵션) - 페이지가 변경되는 빈도입니다. 이 값은 보통 검색엔진에 제공되는 정보입니다. always부터 never까지 다양한 빈도를 선택할 수 있습니다. 하지만, 검색로봇에 내리는 명령어가 아니라 힌트입니다. 선택은 검색로봇이 하는 것이죠
<priority> (선택옵션) - 해당 사이트의 기타 URL에 대한 특정 URL의 상대적 우선순위. 유효값은 0.0~1.0 사이값입니다. 예를 들어, 블로그 주소를 의미하는 곳에 priority가 1.0으로 나타나 있어 전체 URL 중 가장 우선이 된다는 것을 의미합니다. 단, 구글에서는 공식가이드북에서 우선순위를 지정하더라도 검색결과에는 영향을 미치지 않는다고 합니다.
출처: memomee.tistory.com/427
우리는 아래 형식에서 <url> 태그 안에 <loc>과 <lastmod> 정도만 구현한 웹의 페이지에 맞게 바꿔주면 된다.
<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
>
<url>
<loc>https://website.com/</loc>
<lastmod>2020-04-03T08:19:25.691Z</lastmod>
</url>
<url>
<loc>https://website.com/about</loc>
<lastmod>2020-04-03T08:19:25.691Z</lastmod>
</url>
...
</urlset>
이러한 작업을 자동으로 해주기 위해 코드를 짜보도록하자.
const fs = require("fs");
const prettier = require("prettier");
const SitemapGeneratedDate = new Date().toISOString();
const CINEPS_BOARD_DOMAIN = "https://www.cineps.net/board";
const formatting = (target) => prettier.format(target, { parser: "html" });
let pages = ["/best", "talk", "/citic", "/campus", "/notice"];
pages = pages.map((page) => CINEPS_BOARD_DOMAIN + page);
// 웹의 페이지에 따라 반복적으로 넣을 loc, loastmod
const pageSitemap = pages
.map(
(page) => `
<url>
<loc>${page}</loc>
<lastmod>${SitemapGeneratedDate}</lastmod>
</url>
`
)
.join(""); // 배열이니 join으로 전부 합쳐주자
// 생성된 pageSitemap을 그 밖의 xml 태그 내부에 넣어주자
const geneateSitemap = `
<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
${pageSitemap}
</urlset>`;
const formattedSitemap = formatting(geneateSitemap);
fs.writeFileSync("./public/sitemap.xml", formattedSitemap, "utf8");
결과적으로 생성된 xml은 아래와 같다. 이런 레벨이면 손수 직접 넣어주어도 되겠지만, 날짜라던가 이후에 동적인 sitemap을 넣기 위해 수작업을 진행하는 것이 번거로우므로 script로 자동 생성하는 것이 좋다.
<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
>
<url>
<loc>https://www.cineps.net/board/best</loc>
<lastmod>2020-11-05T22:09:22.334Z</lastmod>
</url>
<url>
<loc>https://www.cineps.net/boardtalk</loc>
<lastmod>2020-11-05T22:09:22.334Z</lastmod>
</url>
<url>
<loc>https://www.cineps.net/board/citic</loc>
<lastmod>2020-11-05T22:09:22.334Z</lastmod>
</url>
<url>
<loc>https://www.cineps.net/board/campus</loc>
<lastmod>2020-11-05T22:09:22.334Z</lastmod>
</url>
<url>
<loc>https://www.cineps.net/board/notice</loc>
<lastmod>2020-11-05T22:09:22.334Z</lastmod>
</url>
</urlset>
이렇게 생생된 sitemap을 등록하기 위해서는 도메인/sitemap.xml으로 접근 가능해야 하므로 우선 배포를 하자.
배포가 끝난 후 에서는 도메인/robots.txt와 도메인/sitemap.xml으로 접근이 가능한지 확인해보자.
아주 멋있게 접근이 된다 :)
이제 만든 sitemap을 google search console에 등록해보자.
search.google.com/search-console/about
우선 도메인을 공급하는 업체에 DNS인증을 위해 txt 레코드를 적어줍시다.
aws route 53은 다음과 같이
cloudflare는 다음과 같이
구글 서치 콘솔 네이버 서치어드바이져 등 검색 포털에 sitemap.xml을 제출한 후 반영이 되어야 sitemap이 구성된 모습을 확인할 수 있습니다.
참고로 처음 등록하면 사이트맵을 찾을 수 없다고 뜨지만 기다려봅시다. 최장 15분 정도 걸립니다만 저는 3분 정도 기다리니 '성공'을 받았습니다.
일단 반영은 되었습니다. 이제 추가적으로 색인을 달아서 검색 결과시 예쁘게 보이도록 만들어주면 되겠습니다.
구글 크롤링 봇이 우리 사이트를 쓸고 가는 데에는 시간이 소요 되니 구글 서치 콘솔 창에서 색인을 생성하기 위한 정보가 생길 때 까지 기다립니다. (얼마가 걸린지는 모르겠습니다. 일주일 간격으로 구글 크롤링 봇이 돈다고는 하니 일주일은 기다려봐야할 것 같습니다.)
futhermore
동적인 sitemap을 만들기 + github action으로 자동화하기
'웹 전반, 브라우저 > 🔎 SEO' 카테고리의 다른 글
TTFB(Time to First Byte)란 무엇인가? (0) | 2020.11.12 |
---|---|
Lighthouse 사용법 SEO 체크 및 LCP, CLS (0) | 2020.11.12 |
SEO의 첫걸음 : meta tag + og meta (0) | 2020.04.10 |