From 2293695270d1b0327625a77495cba9aeb1513661 Mon Sep 17 00:00:00 2001 From: achmad Date: Thu, 28 May 2026 22:33:50 +0700 Subject: [PATCH] feat: dynamic sitemap and robots.txt --- app/robots.ts | 10 ++++++++++ app/sitemap.ts | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 app/robots.ts create mode 100644 app/sitemap.ts diff --git a/app/robots.ts b/app/robots.ts new file mode 100644 index 0000000..e62e1d1 --- /dev/null +++ b/app/robots.ts @@ -0,0 +1,10 @@ +import type { MetadataRoute } from 'next' + +const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL ?? 'https://kotobane.achmad.dev' + +export default function robots(): MetadataRoute.Robots { + return { + rules: { userAgent: '*', allow: '/' }, + sitemap: `${BASE_URL}/sitemap.xml`, + } +} diff --git a/app/sitemap.ts b/app/sitemap.ts new file mode 100644 index 0000000..6c59968 --- /dev/null +++ b/app/sitemap.ts @@ -0,0 +1,39 @@ +import type { MetadataRoute } from 'next' +import { getAllCategories, getArticles } from '@/lib/directus' + +const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL ?? 'https://kotobane.achmad.dev' + +export default async function sitemap(): Promise { + let categories: import('@/lib/types').Category[] = [] + let articles: import('@/lib/types').Article[] = [] + + try { + const [cats, arts] = await Promise.all([ + getAllCategories(), + getArticles({ limit: 1000 }), + ]) + categories = cats + articles = arts + } catch { + // Directus not available — return homepage only + } + + const categoryUrls: MetadataRoute.Sitemap = categories.map((cat) => ({ + url: `${BASE_URL}/${cat.slug}`, + changeFrequency: 'daily', + priority: 0.8, + })) + + const articleUrls: MetadataRoute.Sitemap = articles.map((article) => ({ + url: `${BASE_URL}/${article.category.slug}/${article.slug}`, + lastModified: article.published_at ? new Date(article.published_at) : new Date(), + changeFrequency: 'weekly', + priority: 0.6, + })) + + return [ + { url: BASE_URL, changeFrequency: 'hourly', priority: 1.0 }, + ...categoryUrls, + ...articleUrls, + ] +}