Blog

Uses the same content pipeline as the documentation. Enabled by default with test posts, ready to publish once you replace the content.

The Saavo template includes blog listing and article pages, using Content Collections to manage content alongside the documentation system. The blog is enabled by default, and articles are available through /blog.

If your product needs a blog, replace the test posts and add your own content for the supported languages. Content is managed in files, without a separate CMS or a visual editor in the dashboard.

Available features

Blog routes are enabled by default after template initialization:

FeatureDefaultDescription
Switchenabled: trueconfig/deploy.ts → content.blog
Route/blogListing, with articles at /blog/:slug
Content directory/content/blogSubdirectories by language
Draft statusstatus: 'draft'Excluded from the listing and sitemap, but still accessible with the URL

Enabling the blog registers these routes:

/blog
/blog/:slug

Blog paths depend on the current language. The default language uses /blog, while other languages use /{code}/blog. Published articles are automatically added to the sitemap when the blog is enabled.

The template includes a 000_test-post.mdx in each of content/blog/en, content/blog/zh-Hans, and content/blog/zh-Hant to test the listing and detail pages. You should replace or remove these test posts before publishing.

Try the blog first

After starting the development server, open /blog. You should see the default language's test post and be able to open its detail page.

Switch to Simplified or Traditional Chinese to check the corresponding test posts. If you do not need a blog, set content.blog.enabled to false. After restarting, /blog is no longer registered.

Blog listing

Configure the blog

Configuration is in config/deploy.ts:

content: {
    blog: {
        enabled: true,
        baseUrl: '/blog',
        contentDir: '/content/blog',
    },
}

If you need a blog:

  1. Keep enabled: true.
  2. Replace test posts in content/blog/{locale}/. Create a corresponding directory when adding a language.
  3. Write your MDX and maintain the corresponding meta.json.
  4. Preview with npm run dev, and run npm run gen:collections if needed.

Frontmatter is similar to the documentation. Common fields include title, description, and optional date, dateModified, imageUrl, tags, categories, and author. status can be draft, published, archived, or featured.

The current listing handles only draft and featured specially: draft is filtered out, featured appears in the featured section, and all other statuses appear in the regular article list. This means archived currently does not hide an article. To take content offline, remove the article or change the filtering logic for the listing and detail pages.

Article URLs have a single slug segment. Nested paths such as /blog/category/post are not supported. Ordering prefixes follow the same rules as the documentation. See Documentation.

Disable the blog if you do not need it. Do not leave an empty listing online just because you might write something later.

Publish and manage articles

The blog uses content-driven pages. There is no separate business service to call from your APIs.

Managing blog content means writing MDX. The listing skips draft posts and displays featured posts in the featured section. Featured and regular articles are sorted separately by date, newest first. To link to an article from a product page, use its generated /blog/:slug URL.

Do not hard-code product release notes into React components and present them as a blog. The changelog has its own module. The blog is suited to standalone articles.

Pre-launch checks

Blog content is public. Before launch, we recommend checking at least the following:

  • If no blog is needed, enabled is set to false, and /blog is inaccessible.
  • If the blog is needed, every enabled language has content, or you accept missing pages.
  • The listing opens, and published articles are directly accessible by slug.
  • Drafts are absent from the listing and sitemap, and their URLs have not been made public.
  • archived has not been used to hide articles, as the current implementation still displays them.
  • Article titles, descriptions, and cover images use your brand instead of placeholder content.

Rebuild after changing enabled, because collections read configuration at build time.

Frequently asked questions

Next steps

Choose further reading based on what you need to build:

If you have no content plans yet, you can disable the blog for now.

Enable it once you have articles, so the launched site does not have an empty blog.