4702614896
Мобилка: - Header: hide-on-scroll, мобильный burger-menu, тонкая адаптация - Hero: текст и кнопки оптимизированы под узкие экраны (full-width buttons) - ArticleCard featured: на мобилке в столбик, картинка сверху - Stats: компактная сетка 2x2 с уменьшенным шрифтом - Глобально: scroll-behavior smooth, safe-area-inset, tap targets 40px+ - prefers-reduced-motion respected Страница статьи: - ReadingProgress: прогресс-бар сверху при скролле - ScrollToTop: круглая кнопка наверху после 800px скролла - ShareButton: Web Share API на мобилках, копирование URL на десктопе - Related articles: подбираем по пересечению тегов (max 3) - Мобильная типографика: prose-base sm:prose-lg, leading-relaxed SEO/инфра: - /api/search: простой поиск по title/excerpt/tags с подсветкой и скорингом - SearchBox: оверлей с / хоткеем, дебаунс 250ms, мобиле-friendly - /rss.xml: полноценный RSS-фид - sitemap.xml: динамический через next sitemap() - robots.txt: динамический - viewport metadata + theme-color для светлой/тёмной темы - alternates rel=alternate type=application/rss+xml
32 lines
938 B
JavaScript
32 lines
938 B
JavaScript
import { listArticles, listTags } from '@/lib/engine';
|
|
|
|
const SITE = 'https://zeropost.ru';
|
|
|
|
export default async function sitemap() {
|
|
const [articles, tags] = await Promise.all([
|
|
listArticles({ limit: 200 }).catch(() => []),
|
|
listTags().catch(() => []),
|
|
]);
|
|
|
|
const staticPages = [
|
|
{ url: `${SITE}/`, lastModified: new Date(), changeFrequency: 'daily', priority: 1 },
|
|
{ url: `${SITE}/about`, lastModified: new Date(), changeFrequency: 'monthly', priority: 0.5 },
|
|
];
|
|
|
|
const articlePages = articles.map(a => ({
|
|
url: `${SITE}/blog/${a.slug}`,
|
|
lastModified: a.published_at ? new Date(a.published_at) : new Date(),
|
|
changeFrequency: 'monthly',
|
|
priority: 0.8,
|
|
}));
|
|
|
|
const tagPages = tags.map(t => ({
|
|
url: `${SITE}/tag/${encodeURIComponent(t.tag)}`,
|
|
lastModified: new Date(),
|
|
changeFrequency: 'weekly',
|
|
priority: 0.6,
|
|
}));
|
|
|
|
return [...staticPages, ...articlePages, ...tagPages];
|
|
}
|