{topic}
+{description}
+ { + guides.length === 0 ? ( +No guides for this topic
+ ) : ( +-
+ {guides.map((guide) => (
+
- + {guide.data.title} + + ))} +
diff --git a/apps/kb/src/components/Nav.tsx b/apps/kb/src/components/Nav.tsx index d28f765a059..16ff6977028 100644 --- a/apps/kb/src/components/Nav.tsx +++ b/apps/kb/src/components/Nav.tsx @@ -9,15 +9,16 @@ import { navigationMenuTriggerStyle, } from 'ui' +import { TOPICS, topicToSlug } from '../lib/topics' + +const topics = TOPICS.map((topic) => ({ + label: topic.name, + href: `${import.meta.env.BASE_URL}/topics/${topicToSlug(topic.name)}`, +})) + /** * Hard-codding links in here for now until we have actual content. Might be worth putting these arrays in their on data file too. */ -const topics = [ - { label: 'Troubleshooting', href: '#' }, - { label: 'Migrations', href: '#' }, - { label: 'Comparisons', href: '#' }, -] - const resources = [ { label: 'Status', href: 'https://status.supabase.com' }, { label: 'Changelog', href: 'https://supabase.com/changelog' }, diff --git a/apps/kb/src/content.config.ts b/apps/kb/src/content.config.ts index 92612a16b79..fec50c46fb6 100644 --- a/apps/kb/src/content.config.ts +++ b/apps/kb/src/content.config.ts @@ -2,6 +2,8 @@ import { defineCollection } from 'astro:content' import { glob } from 'astro/loaders' import { z } from 'astro/zod' +import { TOPIC_NAMES } from './lib/topics' + // Every entry here is rendered through GuideLayout by // src/pages/guides/[...slug].astro — dropping a new file in // src/content/guides doesn't need any per-file layout wiring. @@ -9,8 +11,10 @@ const guides = defineCollection({ loader: glob({ pattern: '**/*.md', base: './src/content/guides' }), schema: z.object({ title: z.string(), - description: z.string().optional(), - topics: z.array(z.string()).optional(), + description: z.string(), + // 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)), 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 6a69b4987bc..f1af5d55b00 100644 --- a/apps/kb/src/content/guides/sample-guide.md +++ b/apps/kb/src/content/guides/sample-guide.md @@ -1,7 +1,7 @@ --- title: 'Markdown elements sample' description: 'A lorem ipsum sample guide exercising every base Markdown element supported by the guide layout.' -topics: ['example', 'markdown'] +topics: ['Tutorial', 'Database'] github_url: 'https://github.com/supabase/supabase/discussions/0000000' --- diff --git a/apps/kb/src/layouts/GuideLayout.astro b/apps/kb/src/layouts/GuideLayout.astro index 49b82d04b1c..0362e842cfa 100644 --- a/apps/kb/src/layouts/GuideLayout.astro +++ b/apps/kb/src/layouts/GuideLayout.astro @@ -3,11 +3,12 @@ import { Github } from 'lucide-react' import { Badge } from 'ui' import Layout from './Layout.astro' +import { getTopicDescription, type Topic, topicToSlug } from '../lib/topics' interface Props { title: string description?: string - topics?: string[] + topics?: Topic[] github_url?: string } @@ -21,7 +22,14 @@ const { title, description, topics = [], github_url } = Astro.props { topics.length > 0 && (
{description}
+ { + guides.length === 0 ? ( +No guides for this topic
+ ) : ( +