diff --git a/site/astro.config.mjs b/site/astro.config.mjs
index fc94e64..25e65d9 100644
--- a/site/astro.config.mjs
+++ b/site/astro.config.mjs
@@ -67,10 +67,15 @@ const base = '/awesome-prometheus-alerts';
export default defineConfig({
site: 'https://samber.github.io',
base,
- redirects: buildRedirects(base),
+ redirects: { ...buildRedirects(base) },
output: 'static',
integrations: [
sitemap({
+ /** Exclude redirect source URLs from the sitemap.
+ * Astro generates static HTML redirect files for every entry in `redirects`, and the
+ * sitemap plugin naively picks them up. We must explicitly filter them out so that Google
+ * only indexes canonical destinations, not the redirect intermediaries. */
+ filter: (page) => !page.includes('.html'),
serialize(item) {
const path = new URL(item.url).pathname;
const segments = path.replace(/^\/|\/$/g, '').split('/').filter(Boolean);
@@ -78,22 +83,22 @@ export default defineConfig({
if (segments.length <= 1) {
// Homepage
- return { ...item, changefreq: 'weekly', priority: 1.0, lastmod: new Date() };
+ return { ...item, changefreq: 'weekly', priority: 1.0 };
}
if (segments.length === 2 && segments[1] === 'rules') {
// /rules/ index
- return { ...item, changefreq: 'weekly', priority: 0.9, lastmod: new Date() };
+ return { ...item, changefreq: 'weekly', priority: 0.9 };
}
if (segments.length === 3 && segments[1] === 'rules') {
// /rules/[group]/ index
- return { ...item, changefreq: 'monthly', priority: 0.7, lastmod: new Date() };
+ return { ...item, changefreq: 'monthly', priority: 0.7 };
}
if (segments.length === 4 && segments[1] === 'rules') {
// /rules/[group]/[service]/ — main content pages
- return { ...item, changefreq: 'monthly', priority: 0.8, lastmod: new Date() };
+ return { ...item, changefreq: 'monthly', priority: 0.8 };
}
// Guide pages and others
- return { ...item, changefreq: 'yearly', priority: 0.6, lastmod: new Date() };
+ return { ...item, changefreq: 'yearly', priority: 0.6 };
},
}),
icon(),
diff --git a/site/src/pages/rules/[group]/[service].astro b/site/src/pages/rules/[group]/[service].astro
index d73baea..9ecdb9c 100644
--- a/site/src/pages/rules/[group]/[service].astro
+++ b/site/src/pages/rules/[group]/[service].astro
@@ -22,12 +22,10 @@ const ruleCount = getRuleCount(service);
const groupIndex = data.groups.findIndex((g) => getGroupSlug(g) === groupSlug) + 1;
const serviceIndex = group.services.findIndex((s) => getServiceSlug(s) === serviceSlug) + 1;
-// Build exporters summary for meta description
+// Build exporters summary for keywords (kept for but removed from description)
const exporterNames = service.exporters.map((e) => e.name).filter(Boolean).join(', ');
-const metaDescBase = `${ruleCount} ready-to-use Prometheus alert rules for ${service.name}${exporterNames ? ` (${exporterNames})` : ''}. Copy-paste YAML for critical and warning alerts.`;
-const metaDesc = metaDescBase.length > 160
- ? `${ruleCount} ready-to-use Prometheus alert rules for ${service.name}. Copy-paste YAML for critical and warning alerts.`
- : metaDescBase;
+// Description: lead with count + service + format signals. Exporter names go in keywords, not here.
+const metaDesc = `${ruleCount} ready-to-use Prometheus alert rules for ${service.name}. Critical and warning YAML snippets — copy-paste into your Prometheus config or wget download.`;
// FAQ JSON-LD for GEO (AI search engines)
const faqItems = service.exporters.flatMap((exp) =>
@@ -55,7 +53,7 @@ const jsonLd = {
{
'@type': 'TechArticle',
'@id': `${pageUrl}#article`,
- headline: `${service.name} Prometheus Alert Rules`,
+ headline: `${service.name} Prometheus Alert Rules (${ruleCount})`,
description: metaDesc,
about: `Prometheus monitoring for ${service.name}`,
url: pageUrl,
@@ -76,7 +74,7 @@ const jsonLd = {
---