Skip to main content

Topic page

Starter for a new Smol Gardens topic. A topic is two things: an entry in docs/topics/_configs.ts and a folder next to it. Do both and the topic appears on /topics — card, tag chips, sidebar entry, and detail route — with no edit to any component or router.

1. Add the config entry​

docs/topics/_configs.ts is the single source of truth. id must match the folder name you create in step 2.

MyNewTopic: {
id: 'my-new-topic',
title: 'My New Topic',
description: 'One or two sentences. This is what shows on the topic card.',
tags: ['accountability', 'community'],
},

Reusing an existing tag adds the topic to that filter. A brand-new tag creates a new filter chip automatically — ALL_TAGS is derived from the config.

2. Create the folder​

docs/topics/my-new-topic/
├─ my-new-topic.mdx the page shell (below)
├─ _summary.mdx the content partial
└─ assets/
└─ my-new-topic.jpg the topic's image

Each topic owns its image in its own assets/ folder rather than sharing one out of static/, so a topic folder is self-contained: copy it, rename it, swap the picture. Webpack fingerprints imported assets, so they cache better than files served straight from static/ too.

Files starting with _ are partials: Docusaurus does not give them their own route, so they only ever render where you import them.

my-new-topic.mdx​

The shell holds no copy of its own — it reads everything from the config, so the card and the page can never drift apart. <Banner> renders the green header; the three tabs match the project-page template in Figma.

---
id: topics-my-new-topic
title: ''
sidebar_label: My New Topic
hide_table_of_contents: true
---

import Banner from '@site/src/components/Banner'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'

import configs from '../_configs.ts'
import Summary from './_summary.mdx'

<Banner
title={configs.MyNewTopic.title}
subtitle={configs.MyNewTopic.description}
/>

<Tabs>
<TabItem value="summary" label="Summary" default>
<Summary
title={configs.MyNewTopic.title}
description={configs.MyNewTopic.description}
tags={configs.MyNewTopic.tags}
/>
</TabItem>
<TabItem value="resources" label="Related Resources">
Links and reading for this topic.
</TabItem>
<TabItem value="projects" label="Projects">
Projects that put this topic into practice.
</TabItem>
</Tabs>

Keep title: '' in the frontmatter — <Banner> supplies the page heading, so a frontmatter title would render a second one above it.

_summary.mdx​

Receives whatever the shell passes as props. Write the long-form content here.

<ContentWithMedia> is the two-column row from the project-page template — copy on the left, a circle-cropped image on the right. Leave src off and it renders a dashed placeholder circle, so the layout holds before the artwork exists. Because the crop is circular, pick artwork whose subject sits near the centre; the corners are always clipped.

import ContentWithMedia from '@site/src/components/ContentWithMedia'
import topicImage from './assets/my-new-topic.jpg'

<ContentWithMedia src={topicImage} alt="Describe the image here">

## {props.title}

<p>{props.description}</p>

</ContentWithMedia>

## Why it matters

Your content.

Import the image rather than writing a path string — webpack then resolves and fingerprints it, and the build fails loudly if the file is missing instead of shipping a broken <img>.

Before the artwork exists, drop both props and pass a label instead. The component renders a dashed placeholder circle of the same size, so the layout is already correct:

<ContentWithMedia label="Topic image">

Blank lines around the Markdown inside the component are required — without them MDX treats the block as raw JSX and stops parsing the headings.

3. Add more partials as the page grows​

The Related Resources and Projects tabs start as inline placeholder text. Once either has real content, move it into its own partial and import it — same shape as _summary.mdx:

import RelatedResources from './_related-resources.mdx'

<TabItem value="resources" label="Related Resources">
<RelatedResources />
</TabItem>

Design reference​

The green header, tab row, and content block come from the PAGE - Project Page template section in the Smol Gardens Figma (node 2213:2590). Key values are already wired into src/css/custom.css as tokens — --color-bg-banner, --color-content-default, --radius-medium — so use those rather than new hex literals.

Checklist​

  • Entry added to docs/topics/_configs.ts
  • Folder name matches the entry's id
  • sidebar_label set (the shell's title stays empty — <Banner> supplies the heading)
  • npm run build passes with no broken links