diff --git a/apps/kb/src/components/Card.astro b/apps/kb/src/components/Card.astro new file mode 100644 index 00000000000..8784427734e --- /dev/null +++ b/apps/kb/src/components/Card.astro @@ -0,0 +1,45 @@ +--- +// Small "glass panel" card, adapted from apps/docs' GlassPanel +// (packages/ui-patterns/src/GlassPanel/index.tsx) — same surface treatment +// (bg-surface-75, hover:border-strong), trimmed to what kb needs: no +// logo/icon-picker machinery, which pulled in next/image and next-themes +// that don't apply to a plain Astro app. +// +// Unlike GlassPanel (always a plain
{description}
} + { + topics.length > 0 && ( +
diff --git a/apps/kb/src/content.config.ts b/apps/kb/src/content.config.ts
index fec50c46fb6..245e1163529 100644
--- a/apps/kb/src/content.config.ts
+++ b/apps/kb/src/content.config.ts
@@ -15,6 +15,8 @@ const guides = defineCollection({
// z.enum (not z.string) so a guide referencing a topic outside TOPICS
// fails content validation instead of silently rendering an orphaned tag.
topics: z.array(z.enum(TOPIC_NAMES)),
+ // Surfaces the guide in the homepage's "Featured Guides" section.
+ pinned: z.boolean().default(false),
github_url: z.string().optional(),
}),
})
diff --git a/apps/kb/src/content/guides/sample-guide.md b/apps/kb/src/content/guides/sample-guide.md
index f1af5d55b00..7aa9a1f9a8c 100644
--- a/apps/kb/src/content/guides/sample-guide.md
+++ b/apps/kb/src/content/guides/sample-guide.md
@@ -2,6 +2,7 @@
title: 'Markdown elements sample'
description: 'A lorem ipsum sample guide exercising every base Markdown element supported by the guide layout.'
topics: ['Tutorial', 'Database']
+pinned: true
github_url: 'https://github.com/supabase/supabase/discussions/0000000'
---
diff --git a/apps/kb/src/lib/topics.ts b/apps/kb/src/lib/topics.ts
index c0725d4a303..ecfe5e9c764 100644
--- a/apps/kb/src/lib/topics.ts
+++ b/apps/kb/src/lib/topics.ts
@@ -1,18 +1,42 @@
// Canonical list of guide topics. Single source of truth for the `topics`
// field in src/content.config.ts (so a guide with an unsupported topic fails
// content validation), the "Topics" nav menu, and the /topics/[topic] pages.
+//
+// `pinned` topics surface as cards on the homepage (see src/pages/index.astro)
+// — keep this to a handful so that section stays a highlights row, not a
+// second copy of the full topic list.
export const TOPICS = [
- { name: 'Migration', description: 'Moving data, schemas, or projects onto Supabase' },
- { name: 'Comparison', description: 'How Supabase compares to other databases and platforms' },
- { name: 'Troubleshooting', description: 'Common errors and how to resolve them' },
- { name: 'Tutorial', description: 'Step-by-step walkthroughs for building with Supabase' },
- { name: 'Storage', description: 'Uploading, managing, and serving files' },
- { name: 'Auth', description: 'Authentication, authorization, and user management' },
- { name: 'Database', description: 'Postgres schemas, queries, and performance' },
- { name: 'Edge Functions', description: 'Deploying and running serverless functions' },
- { name: 'Queues', description: 'Background jobs and message processing' },
- { name: 'Realtime', description: 'Broadcast, presence, and database changes' },
- { name: 'Supabase Platform', description: 'Project settings, billing, and infrastructure' },
+ {
+ name: 'Migration',
+ description: 'Moving data, schemas, or projects onto Supabase',
+ pinned: false,
+ },
+ {
+ name: 'Comparison',
+ description: 'How Supabase compares to other databases and platforms',
+ pinned: false,
+ },
+ { name: 'Troubleshooting', description: 'Common errors and how to resolve them', pinned: false },
+ {
+ name: 'Tutorial',
+ description: 'Step-by-step walkthroughs for building with Supabase',
+ pinned: true,
+ },
+ { name: 'Storage', description: 'Uploading, managing, and serving files', pinned: false },
+ { name: 'Auth', description: 'Authentication, authorization, and user management', pinned: true },
+ { name: 'Database', description: 'Postgres schemas, queries, and performance', pinned: true },
+ {
+ name: 'Edge Functions',
+ description: 'Deploying and running serverless functions',
+ pinned: false,
+ },
+ { name: 'Queues', description: 'Background jobs and message processing', pinned: false },
+ { name: 'Realtime', description: 'Broadcast, presence, and database changes', pinned: false },
+ {
+ name: 'Supabase Platform',
+ description: 'Project settings, billing, and infrastructure',
+ pinned: false,
+ },
] as const
export type Topic = (typeof TOPICS)[number]['name']
diff --git a/apps/kb/src/pages/index.astro b/apps/kb/src/pages/index.astro
index fe909f38c65..0ad77523149 100644
--- a/apps/kb/src/pages/index.astro
+++ b/apps/kb/src/pages/index.astro
@@ -1,8 +1,79 @@
---
+import { getCollection } from 'astro:content'
+
+import Card from '../components/Card.astro'
import { Hero } from '../components/Hero'
import Layout from '../layouts/Layout.astro'
+import { TOPICS, topicToSlug } from '../lib/topics'
+
+const guides = await getCollection('guides')
+const pinnedTopics = TOPICS.filter((topic) => topic.pinned)
+const featuredGuides = guides.filter((guide) => guide.data.pinned)
---
Featured Guides
+ All Guides
+
+ {guides.map((guide) => (
+
+ All Topics
+
+ {TOPICS.map((topic) => (
+
+