Next js에서 sitemap 만들기

강보석·2021년 8월 6일
2

✨소개

자신의 웹사이트를 배포하셨다면 이제는 구글에 검색을 했을 때 검색한 결과에 자신의 웹사이트가 있다면 사람들이 방문하기에 더 용이하겠죠? 그러기 위해서는 사람들이 많이 방문해서 검색기록에 올리는 경우도 있겠지만 힘든 방법입니다. 그렇기 때문에 우리는 수동으로 제 웹사이트를 구글봇이 크롤링하도록 요청을 해야합니다.

그래서 google search console에 여러분의 도메인을 등록하시길 바랍니다. 이제는 그 다음부터가 문제인데 해당 도메인만 구글에 뜨고 작성한 게시글이 안 올라올 때가 있습니다. 그 때는 구글봇에게 직접 안내를 시켜줘야 하는데 이 때 필요한 게 sitemap.xml입니다.

✨sitemap 만들기

준비사항은 prettier와 globby와 node-fetch를 npm을 통해 받아주시는 것입니다.

과정에 대해 간단히 설명해드리자면 사이트맵 파일들을 만들고 그 파일들을 압축하고 하나로 뭉칠겁니다. 그리고 그 뭉친 파일을 구글에 제출할겁니다.

코드는 이 분의 글을 참고했습니다. 참고

🎐정적페이지 sitemap 만들기

이제 sitemap을 만들텐데 정적 페이지와 동적 페이지에 따라 코드가 갈립니다. 먼저 정적 페이지의 경우부터 보여드리겠습니다. root파일이 있는 곳에 scripts라는 폴더를 만들어서 파일을 만들어 이 코드를 적습니다.

const fs = require('fs');
const globby = require('globby');
const prettier = require('prettier');

const getDate = new Date().toISOString();
const MY_DOMAIN = "https://kihat.ga";
const formatted = sitemap => prettier.format(sitemap, { parser: "html" });

(async () => {
    const pages = await globby([
        "../pages/*.tsx",
        "!../pages/_*.tsx",
        "!../pages/newpost.tsx",
        "!../pages/categorysetting.tsx",
        //!가 들어가면 반영이 되지 않음
    ]);  
  
    const pagesSitemap = `
        ${pages.map(page => {
            const path = page.replace('../pages/', '').replace('.tsx', '').replace(/\/index/g, '');
            const routePath = path === 'index' ? '' : path;
            return `
                <url>
                    <loc>${MY_DOMAIN}/${routePath}</loc>
                    <lastmod>${getDate}</lastmod>
                </url>
            `;
        }).join('')}
    `;
    
    const generatedSitemap = `
        <?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.9http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
        >
        ${pagesSitemap}
        </urlset>
    `;
  
    const formattedSitemap = [formatted(generatedSitemap)];
  
    fs.writeFileSync('../public/sitemap/sitemap-common.xml', formattedSitemap, "utf8");
})();

🎐동적페이지 sitemap 만들기

그리고 동적 페이지인 경우를 보겠습니다. 같은 곳에 파일을 만들고 이 코드를 적어주세요.

const fs = require('fs');
const fetch = require('node-fetch');
const prettier = require('prettier');

const getDate = new Date().toISOString();

const fetchUrl = 'https://kihat.ga/posts';
const MY_DOMAIN = 'https://kihat.ga';

const formatted = sitemap => prettier.format(sitemap, { parser: 'html' });
(async () => {
    const fetchPosts = await fetch(fetchUrl)
        .then(res => res.json())
        .catch(err => console.log(err));
    const postList = [];
    
    fetchPosts.forEach(post => postList.push(post.uuid));
    const postListSitemap = `
        ${postList.map(uuid => {
            return `
                <url>
                    <loc>${`${MY_DOMAIN}/post/${uuid}`}</loc>
                    <lastmod>${getDate}</lastmod>
                </url>
            `;
        }).join('')}
    `;
    
    const generateSitemap = `
        <?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"
        >
            ${postListSitemap}
        </urlset>
    `;
    const formattedSitemap = [formatted(generateSitemap)];
    
    fs.writeFileSync('../public/sitemap/sitemap-posts.xml', formattedSitemap, 'utf8');
})();

도메인이나 ajax 요청으로 데이터를 가져오는 경우는 알아서 상황에 따라 설정해주시면 됩니다.
이 파일들을 터미널에서 node로 실행시켜주시면 알아서 파일들이 만들어집니다.

🎐sitemap 압축하기

그 다음은 만들어진 사이트맵을 압축을 할겁니다. 마찬가지로 같은 폴더에 js파일을 만들어주시고 이 코드를 써주세요.

const fs = require("fs");
const zlib = require("zlib");
var dirs = ["../public/sitemap"];
dirs.forEach((dir) => {
    fs.readdirSync(dir).forEach((file) => {
        if (file.endsWith(".xml")) {
        // gzip
        const fileContents = fs.createReadStream(dir + "/" + file);
        const writeStream = fs.createWriteStream(dir + "/" + file + ".gz");
        const zip = zlib.createGzip();
        
        fileContents
            .pipe(zip)
            .on("error", (err) => console.error(err))
            .pipe(writeStream)
            .on("error", (err) => console.error(err));
        }
    });
});

마찬가지로 node로 실행시켜주시면 알아서 gz 파일들이 만들어집니다.

🎐압축한 파일 뭉치기

마지막으로 gz 파일들을 하나로 뭉칠겁니다.

const fs = require('fs');
const globby = require('globby');
const prettier = require('prettier');

const getDate = new Date().toISOString();

const webrootDomain = 'https://kihat.ga';
const formatted = sitemap => prettier.format(sitemap, { parser: 'html' });

(async () => {
    const pages = await globby(['../public/sitemap/*.gz']);
    
    const sitemapIndex = `
        ${pages.map(page => {
            const path = page.replace('../public/', '');
            
            return `
                <sitemap>
                    <loc>${`${webrootDomain}/${path}`}</loc>
                    <lastmod>${getDate}</lastmod>
                </sitemap>
            `;
        }).join('')}
    `;
    
    const sitemap = `
        <?xml version="1.0" encoding="UTF-8"?>
        <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
            ${sitemapIndex}
        </sitemapindex>
    `;
    
    const formattedSitemap = [formatted(sitemap)];
    
    fs.writeFileSync('../public/sitemap.xml', formattedSitemap, 'utf8');
})();

✨제출하기

이 파일을 마친가지로 node로 실행시키면 public 폴더에 sitemap.xml이 생성될겁니다. 그러면 이제 배포를 하시고 ${사이트주소}/sitemap.xml같은 경로를 구글 사이트맵 생성에 올리시면 됩니다. 혹은

curl http://google.com/ping?sitemap=${사이트주소}/sitemap.xml

명령어를 터미널에 입력하셔도 되고요.

여기까지 사이트맵을 제출하는 법이었습니다.

profile
안녕하세요. 컴퓨터를 공부하는 학생입니다.

0개의 댓글