feat: dynamic sitemap and robots.txt

This commit is contained in:
achmad
2026-05-28 22:33:50 +07:00
parent e45faa201f
commit 2293695270
2 changed files with 49 additions and 0 deletions
+10
View File
@@ -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`,
}
}
+39
View File
@@ -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<MetadataRoute.Sitemap> {
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,
]
}