From ff4d81607db4e389bd59315087f65a93701f730d Mon Sep 17 00:00:00 2001 From: 1ilsang <1ilsang@naver.com> Date: Sun, 25 Aug 2024 00:44:23 +0900 Subject: [PATCH] feat: add sitemap and robots.txt --- src/app/robots.ts | 13 +++++++ src/app/sitemap.ts | 60 +++++++++++++++++++++++++++++ src/app/tags/[tag]/page.tsx | 12 ++---- src/app/tags/page.tsx | 11 +----- src/features/shared/helpers/post.ts | 6 +++ 5 files changed, 84 insertions(+), 18 deletions(-) create mode 100644 src/app/robots.ts create mode 100644 src/app/sitemap.ts diff --git a/src/app/robots.ts b/src/app/robots.ts new file mode 100644 index 00000000..547a9a49 --- /dev/null +++ b/src/app/robots.ts @@ -0,0 +1,13 @@ +import type { MetadataRoute } from 'next'; +import { MyProfile } from '~/about/headline/data/profile'; + +export default function robots(): MetadataRoute.Robots { + return { + rules: { + userAgent: '*', + allow: '/', + disallow: ['/favicon', '/fonts', '/images', '/open.mp4'], + }, + sitemap: `${MyProfile.blog.href}/sitemap.xml`, + }; +} diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts new file mode 100644 index 00000000..6224e7b4 --- /dev/null +++ b/src/app/sitemap.ts @@ -0,0 +1,60 @@ +import type { MetadataRoute } from 'next'; +import { MyProfile } from '~/about/headline/data/profile'; +import { getAllPosts, getAllTags } from '~/shared/helpers/post'; + +export default function sitemap(): MetadataRoute.Sitemap { + const DOMAIN = MyProfile.blog.href; + const PRIORITY = { + VERY_HIGH: 1, + HIGH: 0.8, + MID: 0.5, + }; + + const posts = getAllPosts(['tags']); + const tags = getAllTags(); + + const postUrls: MetadataRoute.Sitemap = posts.map((post) => ({ + url: `${DOMAIN}/posts/${post.url}`, + lastModified: new Date(post.updatedAt ?? post.date), + changeFrequency: 'daily', + priority: PRIORITY.VERY_HIGH, + })); + const tagUrls: MetadataRoute.Sitemap = tags.map((tag) => { + const post = posts.find((post) => post.tags.includes(tag))!; + return { + url: `${DOMAIN}/tags/${tag}`, + lastModified: new Date(post.date ?? post.updatedAt), + changeFrequency: 'weekly', + priority: PRIORITY.MID, + }; + }); + + return [ + { + url: DOMAIN, + lastModified: new Date(), + changeFrequency: 'monthly', + priority: PRIORITY.MID, + }, + { + url: `${DOMAIN}/about`, + lastModified: new Date(), + changeFrequency: 'weekly', + priority: PRIORITY.VERY_HIGH, + }, + { + url: `${DOMAIN}/posts`, + lastModified: new Date(), + changeFrequency: 'weekly', + priority: PRIORITY.HIGH, + }, + { + url: `${DOMAIN}/tags`, + lastModified: new Date(), + changeFrequency: 'weekly', + priority: PRIORITY.MID, + }, + ...postUrls, + ...tagUrls, + ]; +} diff --git a/src/app/tags/[tag]/page.tsx b/src/app/tags/[tag]/page.tsx index f010b61a..c17c4af7 100644 --- a/src/app/tags/[tag]/page.tsx +++ b/src/app/tags/[tag]/page.tsx @@ -2,7 +2,7 @@ import type { NextPage } from 'next'; import Navbar from '~/shared/components/nav/Navbar'; import { Footer } from '~/shared/components/Footer'; -import { getAllPosts } from '~/shared/helpers/post'; +import { getAllPosts, getAllTags } from '~/shared/helpers/post'; import TagDetailContainer from '~/tags/detail/Container'; import { MainLayout } from '~/shared/components/MainLayout'; @@ -34,14 +34,8 @@ const Tags: NextPage = ({ params: { tag } }) => { export default Tags; export async function generateStaticParams(): Promise<{ tag: string }[]> { - const allTags = getAllPosts(['tags']) - .map((item) => item.tags) - .flatMap((tags) => tags); - const tags = [...new Set(allTags)]; - const paths = tags.map((tag) => { - return { tag }; - }); - + const tags = getAllTags(); + const paths = tags.map((tag) => ({ tag })); return paths; } diff --git a/src/app/tags/page.tsx b/src/app/tags/page.tsx index 275a6951..d20fa591 100644 --- a/src/app/tags/page.tsx +++ b/src/app/tags/page.tsx @@ -3,18 +3,11 @@ import { type NextPage } from 'next'; import { Footer } from '~/shared/components/Footer'; import { MainLayout } from '~/shared/components/MainLayout'; import Navbar from '~/shared/components/nav/Navbar'; -import { getAllPosts, getPostBySlug } from '~/shared/helpers/post'; +import { getAllTags } from '~/shared/helpers/post'; import TagListContainer from '~/tags/tagList/Container'; const Tags: NextPage = () => { - const rawPosts = getAllPosts(['slug']); - const allTags = rawPosts - .map((rawPost) => { - const data = getPostBySlug(rawPost.slug, ['tags']); - return data.tags; - }) - .flatMap((tagList) => tagList); - const tags = [...new Set(allTags)]; + const tags = getAllTags(); return ( diff --git a/src/features/shared/helpers/post.ts b/src/features/shared/helpers/post.ts index 9fbf4bdf..85b4ccec 100644 --- a/src/features/shared/helpers/post.ts +++ b/src/features/shared/helpers/post.ts @@ -101,6 +101,12 @@ export const getAllPosts = (fields: (keyof PostType)[] = []) => { return posts; }; +export const getAllTags = () => { + const posts = getAllPosts(['tags']); + const tags = [...new Set(posts.map((post) => post.tags).flat())]; + return tags; +}; + export const getPost = async (url: PostType['url']): Promise => { if (!urlToSlugMap[url]) { // NOTE: It will set urlToSlugMap