How to write a topic page

1. Overview

This is a draft tutorial about an unpublished feature on Charmhub!

In this tutorial, you will learn how to write content for topic pages.

We will start by looking at general guidelines, the structure of a topic page and go through the publication and review process.

What you’ll learn

  • How to create and structure a topic page from a single Markdown file
  • How to use the additional Markdown features specific to the engine
  • How to render it locally to see what your readers will see
  • How to get it ready for review by the Charmhub team

What you’ll need

Depending on the topic and your level of experience, writing a topic page can be a very easy task, but following these guidelines is important to keep the whole set of published topic pages consistent. Let’s get started!

2. General guidelines

Mission of topic pages

Topic pages are a single source on how to make the most of our Charmhub packages, and provide an overview on how users can deploy ecosystems.

A good topic page should:

  • Be focused on one topic or a very small group of related topics. Keep it simple and on point.
  • Produce a tangible result. The topic is demonstrated with a small practical project and not only a theoretical or “hello world” example.


The tone of your topic page should be friendly. Try to make the reader feel that they’re building and learning something together with you.

All topics should have the same tone, regardless of the subject. This is why you should be familiar with the existing topics before writing your first one.

And now, let’s see the first required step!

3. Your topic page

Each topic page is built using at least one Discourse topic, under the category topic-pages. Optionally a topic page on Charmhub can have side navigation linking to different content pages, for each content page a Discourse topic will be needed.

Creating the navigation and cover page

  • Add a title for your topic page.
  • The body of this topic contains the cover page and if you want your navigation with a full list of all the pages for your topic page. Each page has to be a topic in Discourse. Here is an example snippet you can start with as an outline. Cut it from here and paste it into your Discourse topic:
The cover page of your docs. This should be some introductory text
which will be displayed on the front page of the Charmhub topic. All the content above the 'Navigation' heading below is part of the cover page.

Optionally, you can include a navigation table with other pages:

# Navigation

| Level | Path | Navlink |
| -- | -- | -- |
| 1 |  | [Overview](/t/topic-title/<ID>) |
| 1 | install | [install](/t/topic-title/<ID>) |
| 2 | Subtopic | [Subtopic](/t/topic-title/<ID>) |
| 2 | Subtopic | [Subtopic](/t/topic-title/<ID>) |
| 1 | topic | [install](/t/topic-title/<ID>) |
| 2 | Subtopic | [Subtopic](/t/topic-title/<ID>) |

If you want to see a big example, this same system is used to make the documentation and the corresponding Discourse topic (which defines that cover page) is linked from the bottom of that page, or you can go straight there.

Let’s go through each section in detail.

Front page content

The text that is above the # Navigation section will appear on the cover page of your docs at<Your topic>/.

You can use formatting here, including headings, images, and lists. It is common to have an outline of the topic treated, or any limitations such as requiring a particular cloud or hardware.

Essentially you can make a whole page. Just don’t use # Navigation as a heading until you want to make your navigation, which is the next section.

Defining the left-hand navigation structure

# Navigation

| Level | Path | Navlink |
| -- | -- | -- |
| 1 | / | [Overview](/t/topic-title/<ID>) |

This is the navigation on the left side of the docs tab.

To add a new navigation item:

  • Create a Markdown table and add a row per item
  • Set a level value, you can start with 1
  • Set the path for this topic
  • Add a markdown link: [Title displayed on the navigation](link to any other discourse topic)

Here is an explanation of the different columns:


We use this value to generate a tree structure in the navigation, a level 1 means a top-level item in the navigation.


The value will be used to transform any discourse URL to a path in your Charmhub topic, as an example:

# Navigation

| Level | Path | Navlink |
| -- | -- | -- |
| 1 | about-kubeflow | [Kubeflow](/t/topic-title/123) |

Will create a path like


In this column, you need to specify the link to the discourse topic.

For example:

# Navigation

| Level | Path | Navlink |
| -- | -- | -- |
| 1 | install | [Install](/t/example-docs-install/9999) |
| 1 | configure | [Configure](/t/example-docs-configure/9998) |

Note that in Markdown a link is [text](url) so each of those is actually a link straight to the Discourse topic page. If you get this right, you can click the navigation links in your cover page # Navigation section and jump straight to the relevant Discourse topics which define those pages.

The important thing in a Discourse topic path is the number at the end, which uniquely identifies a topic, even if the title is edited later. So if the topic link is /t/foo-bar-docs/1234 and later you rename the topic to /t/fixed-up-docs/1234 then the old links to /t/foo-bar-docs/1234 will still work because 1234 never changes.

Of course, in order to have topics to link to, you need to create those topics! And we are now just creating the placeholder navigation, so leave it empty. Later you can fill it in with all the actual pages you want.

4. Add a new page

As mentioned in the step before, feel free to create topics in discourse for your topic page. Don’t forget to jump back into your index topic to add the correct URLs to display them in the navigation.

In these Discourse topics, you don’t need to add the navigation table since they are already handled by your index topic.

5. Dos and Don’ts

In addition to the previous advice on what a topic page should be and what is mandatory, you should pay special attention to the following points:

Topic pages should be concise, but not too short

Be wary of a topic’s length.

If too long, prefer dividing the topic page

If your topic page is too long, consider breaking it up into several pieces.

Command line snippets

Inline commands are styled with single backticks:

For example:

`foo/something --bar`

Which renders as foo/something --bar.

For longer example code we expect people to type in, we do not use the command prompt at the beginning of each line, and we separate the command from the output. This makes the command and outputs clearer and also easier to copy and paste.

6. Syntax tips

The syntax used is by and large regular Markdown syntax, but there are some specificities:

Line breaks and empty lines

  • Paragraphs are delimited by empty lines
  • Line breaks will create a new line

In the context of an admonition or a survey widget, using an empty line will close it and go back to text.


You can display any Charmhub operator by linking the URL in a Markdown table. Example:


The Markdown syntax to display the previous example is the following:

| Packages |
| -- |
| |
| |


Images can be hosted locally (relatively linked to the markdown source) or remotely. The engine will fetch remote images and cache them locally.

In Markdown the syntax for an image is the following:

![image title](image-path-or-link)


Admonitions are coloured blocks that enclose special information, they can be a info tip or a warning message. To create an admonition, begin the next line with a greater than sign, a space and the message on the same line.

An info admonition should contain informative information like best practices and time-saving tips.

> ⓘ **Eat your vegetables!**
> This is a positive message.

Which renders as:

Eat your vegetables! This is a positive message.

A warning admonition should contain an important message such as warnings and API usage restrictions.

> ⚠️ **Eat your vegetables!**
> This is a warning.
> It can be multi-lines like this.

Which renders as:

Eat your vegetables! This is a warning. It can be multi-lines like this.

Fenced code and language hints

Code blocks are declared by placing them between two lines containing three backticks. The engine will attempt to perform syntax highlighting on code blocks, but it is not always effective at guessing the language to highlight in.

Put the name of the coding language after the first fence to explicitly specify which highlighting plan to use, like this:


This block is highlighted as Go source code.


Which renders as:

This block is highlighted as Go source code.

These additions to standard Markdown are easy to master and play with, but in case you face unexpected behaviours in the rendering, feel free to reach out in the Discourse category charmhub-requests.

7. Local rendering

When writing a topic page, it’s extremely useful to see how it will render. Discourse provides a very useful way of rendering the markdown when writing a new topic. Make sure that the page is well rendered.

Once you can have seen your page in its final form, it’s time to share it with the world.

8. Review and publishing process

The topic pages category is managed by the Charmhub team. A review process is in place to ensure new topics are being looked at by writers, engineers and documentation experts.

To get a new topic reviewed and published, please finish your topic page in Discourse and then email: The email should contain the following:

  • Link: the desired link to the new topic page
  • Summary: a description of the topic page (just 10 to 20 words) that will be displayed on the frontpage of the site.
  • Categories: suggest categories that users can use to filter to find topic pages. Use any of these preset options; ai-ml, big-data, cloud, containers, databases, logging-tracing, monitoring, networking, security, storage.
  • Author: the name and email address between brackets of the author of the topic. If you don’t intend to maintain this topic after publication, please use Canonical Web team <>

Once they get to it, they will review the content and open a discussion with you on the discourse topic directly. At the end of this process, they will either include your changes into the project or request additional changes.

9. That’s all folks!

Congrats, you made it! You are now fully equipped to write a compelling topic page and take your future readers to new heights!

Now you know how to:

  • Create a welcoming and informative topic page
  • Structure your markdown source file
  • Render topic pages locally and submit them for publication

There are a lot of topics to write about and if you are looking for ideas, just think about what you master and frequently do, something that’s useful to you, even if it’s an arcane topic or a very simple set of tips you think people would benefit from.

Next steps

  • Write your first topic page of choice and propose it for publication!
  • Read other topic pages and help us improve them by commenting on Discourse