Markdown help center

A help center served from markdown files in your repository: category, tag and article pages, ranked search, locale fallback, JSON-LD and sitemap. No CMS.

Released
October 7, 2026
npx skills add timerise-ai/help-center-markdown
Current release
v0.2.16
Reference docs
11
Non-negotiables
8
License
MIT

What problem does Markdown help center solve?

Every product needs a place where customers find answers without writing to support. A help center is the simplest one: articles in categories, a search box, links between them.

The usual way to get one is a CMS or a hosted knowledge base. That means another login, another monthly fee, and content that lives outside your repository, out of step with the product.

This skill builds the help center from markdown files in the repository. An article is a file with a short header. The build renders the landing, category, tag and article pages. Search ranks results and forgives a trailing space or a missing accent. The build fails when an article is unreachable or a link points nowhere. A language without a translation falls back to the default instead of an empty page.

What does the skill build?

An agent with this skill builds one module for a Next.js App Router app, on your stack. For Markdown help center that module consists of:

  • 1. Category, tag and article pages
  • 2. Ranked client-side search
  • 3. Locale fallback
  • 4. JSON-LD
  • 5. Sitemap
  • 6. CI content validator

Where do the rules come from?

This skill was written by the engineer who has shipped this module; the earlier implementation it was audited against was a marketing-site help center. The templates hold the requirement as verified properties: the sidebar shows every article of every category, the parser reads every frontmatter shape the corpus uses and the validator fails the build on the ones it cannot, tags group by slug so one label reaches one page however it is spelled, and search ranks a query however it is typed, trailing space and diacritics included. The loader, search and tag suites cover each of those; references/provenance.md carries the record.

Written by the engineer who has shipped this module. The earlier implementation it was audited against, a marketing-site help center, ran a few dozen markdown articles in category folders, English content served under several locale prefixes, client-side search, a collapsible sidebar and a mobile drawer, JSON-LD and sitemap integration. The architecture is that module's; the templates carry the changes the audit below records.

The ledger separates what the audit changed, what was kept on purpose, and what has not run in production yet.

  1. Fixed in the templates

    • The sidebar hid half of the biggest category The desktop sidebar animated category collapse with max-h-[600px] + overflow-hidden. The largest category's list was more than twice the height of the cap, so more than half of its links were unreachable from the sidebar. The mobile drawer used a much larger cap and was fine, so nobody testing on a phone saw it, and on desktop the list simply looked complete.
    • Search that missed what people typed Substring match on title and description only. Consequences, each verified in the code:
    • Order ties resolved by filesystem order Articles sorted by order only, and several pairs of articles shared an order. JavaScript's sort is stable, so ties kept readdir order, which is alphabetical on APFS, creation order on some Linux filesystems, and not guaranteed anywhere. The same deploy could list two articles in a different order on a different build machine.
    • Related links that vanish silently related entries were resolved by slug across every category, and unresolved ones were dropped without a warning anywhere. Renaming an article broke every inbound related reference invisibly. Slugs were also only unique per folder, so a bare reference could resolve to the wrong category's article.
    • The corpus re-parsed several times per page Six loader functions each walked the tree. One article render called them from the layout, the page, generateMetadata and the related resolver: around four full parses of every file per page, and again per locale in generateStaticParams.
    Show 9 more
    • "Popular articles" that were not The landing page showed getAllHelpArticles().slice(0, 6) under the heading Popular articles: the first six files of the first folder, by order.
    • English chrome on a three-locale site The site rendered Polish and German everywhere except the help center, whose header, sidebar, buttons, category labels and "Updated {en-US date}" were literals, in an app with a working i18n dictionary that the same component tree used for its footer.
    • order: 0 sorted last (frontMatter.order as number) || 999: zero is falsy. Minor, but the kind of thing that wastes an afternoon.
    • Invalid structured data when a date was missing dateModified: article.updatedAt emitted "" for articles without a date. JSON-LD was also interpolated unescaped; a </script> in a title would have ended the block.
    • Dead code A HelpSearchBar component rendering a disabled input labelled "Soon", and a getHelpArticlesByTag function, both exported, neither imported anywhere.
    • Frontmatter that lied without consequence slug and category in frontmatter were ignored by the loader (filename and folder win). Nothing detected a mismatch. The corpus had none, but the next copy-pasted file would.
    • A frontmatter parser that dropped multi-line values The earlier implementation parsed frontmatter line by line: key: value, JSON-parse anything in [...]. Prettier wraps arrays past 100 columns onto several lines, and every such value read as empty, silently. Found in the earlier implementation hours after the audit, when a new article's related list came out blank: roughly a quarter of the content files across every markdown content type sharing the parser had an empty list field in production, related and tags among them, including cards that had rendering code and had never once rendered.
    • Tags keyed by spelling The earlier implementation's only tag lookup, getHelpArticlesByTag, matched the exact string (tags.includes(tag)), and nothing ever normalised a tag for a URL. Run over the corpus, the 0.2.0 validator found, invisible on the site:
    • What validation found in the real corpus Running the shipped validator over the earlier implementation's content on audit day: order ties, no unresolved references, no slug mismatches, and more than half of the updatedAt values identical (the import date). None of these were visible on the site. The date problem is a content problem; deriving dates from git is in extensions.md.
Read the full record in provenance.md ›

What are the 8 rules the module never breaks?

Every module built from this skill holds these, whoever builds it. The same list is in the skill's README and SKILL.md, so the agent reads it before it writes a line.

  1. Summaries, never articles, cross to the client.

    toSummary / toSearchDoc are the only shapes client components accept, so a page carries about a kilobyte per article rather than the whole corpus; the type signatures enforce it.

  2. hidden, not a height cap, on collapsible nav.

    A height cap clips whatever does not fit and reports nothing; hidden renders every link of every category or none, and the shell template uses only that.

  3. Untranslated pages canonicalise to the default locale

    and stay out of hreflang and the sitemap, so a fallback page is never indexed as a duplicate; the loader test flags the fallback and the routes read that flag.

  4. Validation runs in CI.

    The runtime is forgiving on purpose, dropping bad refs and sorting missing orders last, and validate:help fails the build for the author; the validator tests cover unresolved refs, order ties and skipped files.

  5. Sort by order, then title, then slug.

    Ties left to readdir order differ between filesystems, so the same deploy could list articles differently on another build machine; the loader test orders by order then title, never by filename, and the validator warns on ties.

  6. Search trims, tokenises and folds diacritics, over tags and headings as well as title and description, ranked by field.

    A query is matched however it is typed, trailing space and accents included; the search tests cover each of those and the title-over-description ranking.

  7. Every chrome string goes through HelpStrings.

    The header, footer and notices switch locale together with the host; the components take their text only from the strings table, and the i18n checklist greps for literals left in JSX.

  8. Tags are keyed by tagSlug, never by spelling.

    Case, hyphens and plurals drift across authors, so every variant lands on one page; the tag tests merge spellings under one slug and the validator warns on variants and plural pairs.

When should you use it, and when not?

Use it for

  • Building or extending a help center, docs section or knowledge base whose articles are markdown files in the repository, on Next.js App Router, with or without multiple locales.

Not for

  • A blog: dated, authored posts with covers and localized slugsInsteadThe sibling `blog-markdown` skill; a different content model
  • Docs generated from code (OpenAPI, TypeDoc)InsteadTheir generators; link to the output
  • A CMS-backed help site with editors publishing at runtimeInsteadThe index contract still applies, but the loader, static params and validation change; see the CMS note in references/extensions.md
  • Marketing pages that happen to be markdownInsteadThe host's renderer; this module is the navigation, search and locale model around many articles

How do I install it?

One command. The skills.sh CLI installs the skill into every skills-compatible agent it finds.

$ npx skills add timerise-ai/help-center-markdown

Claude Code

Invoke with /help-center-markdown

Codex CLI

Invoke with $help-center-markdown

Gemini CLI

Invoke with /skills

Name the agents instead with -a, for example npx skills add timerise-ai/help-center-markdown -a claude-code -a codex. Or clone the repository into your agent's skills folder. Nothing in it is agent-specific.

What is inside the repository (18 entries)
  • SKILL.mdEntry point: architecture, critical facts, hard rules, quick start, and the reference directory
  • README.mdThis front door
  • CHANGELOG.mdKeep a Changelog, one section per release, newest first
  • CLAUDE.mdWhat this repository is and the conventions for editing the skill itself
  • LICENSEMIT
  • references/adaptation.mdThe seam contract with the host app: styling, i18n, routing, the category rename, the non-negotiables restated, order of work
  • references/content-model.mdConfig, types, frontmatter fields, slugs, and the CI validator
  • references/content-loader.mdReading files into the index: gray-matter, caching, locale fallback, sorting
  • references/search.mdClient-side search: tokenizing, ranking, combobox keyboard behavior, no-results
  • references/tags.mdTag slug identity, tag pages, chips, tag cloud, tag validation
  • references/i18n.mdLocales, strings, dates, default-locale fallback, hreflang and canonicals
  • references/routes.mdPages, generateStaticParams, metadata, JSON-LD, sitemap entries
  • references/ui.mdShell, header, sidebar, mobile drawer
  • references/ui-content.mdBreadcrumbs, category cards, article lists, the markdown renderer, style hooks
  • references/extensions.mdFull-text/Pagefind, table of contents, feedback, git dates, MDX, CMS, redirects
  • references/provenance.mdThe engineering ledger: what the audit of the earlier implementation changed and how the templates verify it, what was kept on purpose, what is new
  • evals/The prompts an operator types after installing (prompts.md) and one file per agent eval: the skill installed into an empty Next.js app, one prompt, no help, then type-checked, built and tested
  • .github/workflows/agent-eval.ymlRuns the agent evals on every published release through the index's reusable workflow; copied verbatim from the standard

Recent releases

  1. v0.2.16October 7, 2026

    Fix release, from scoring the prompt-1 agent eval runs against 0.2.15. The templates are unchanged.

  2. v0.2.15October 7, 2026

    Fix release, from scoring the prompt-1 agent eval runs against 0.2.14. The templates are unchanged.

  3. v0.2.14October 7, 2026

    Fix release, from scoring the prompt-1 agent eval runs against 0.2.13. One template defect was fixed; the shipped suite grows from 23 to 27 tests in five files.

What do I tell my agent?

Say what you need in your own words; the skill supplies the how. These are starting points, and the ones we tested say how it went.

  1. Add a help center to this Next.js app from markdown files in content/help: category pages, article pages, search, and a sitemap entry for every article.

  2. Our docs are markdown files in English and German. Build /help with a locale fallback, so an article missing in German shows the English one instead of a 404.

    Repository files
  3. Audit our help center: search misses articles, categories sort inconsistently and some tags are spelled two ways.

How does it do in each agent?

We install the skill into an empty Next.js app, give the agent one of the prompts above and no further help, then type-check, build and run the tests it left behind. Nothing is fixed by hand before the checks, and a failing run is published like a passing one. The procedure and every result are public, and the first prompt runs again before each release.

  • Codex CLIcodex-cli 0.161.0

    gpt-6.1-sol

    Built, checks pass
    Add a help center to this Next.js app from markdown files in content/help: category pages, article pages, search, and a sitemap entry for every article.
    Typecheck: passBuild: passTests: pass
    Time
    2 min
    Changed
    46 files, +6,245 lines
    Stack
    Repository files
    Skill
    v0.2.16
    Run
    Oct 7, 2026

    Result file ›Agent log ›

    What we saw

    Rubric 7/8. Scored from the commands in the log. Code blocks extracted verbatim, packages from npm, the five test files unmodified under vitest (27 tests), prebuild wired, siteUrl a literal, and a final message naming the category ids with redirects on a rename, the sample articles, siteUrl to set before deploying, the validator and the analytics hook. Item 2 failed: it added data-help-article-list to the <ol> in HelpArticleList.tsx so its stylesheet could reset the list numbering. The gap is real: ui.md says every component emits data-help-* hooks, and the list root has none, so a host without Tailwind cannot style it from a hook. Left as open work when the loop stopped on this round.

  • Gemini CLI0.63.0

    gemini-3.8-flash

    Built, checks pass
    Add a help center to this Next.js app from markdown files in content/help: category pages, article pages, search, and a sitemap entry for every article.
    Typecheck: passBuild: passTests: pass
    Time
    11 min
    Changed
    47 files, +6,477 lines
    Stack
    Repository files
    Skill
    v0.2.16
    Run
    Oct 7, 2026

    Result file ›Agent log ›

    What we saw

    Rubric 8/8. Scored from the summary; no local rerun. Templates as shipped, the five test files unmodified under vitest (27 tests), prebuild wired, layout utilities in app/globals.css, and the loader unchanged with the Turbopack warning named as expected. The handover now says the siteUrl placeholder "must be updated" before deploying, lists the placeholder articles, the category ids with redirects on a rename, the validator and the analytics hook to wire.

  • Claude Code2.1.293

    claude-opus-5-5

    Built, checks pass
    Add a help center to this Next.js app from markdown files in content/help: category pages, article pages, search, and a sitemap entry for every article.
    Typecheck: passBuild: passTests: pass
    Time
    2 min
    Changed
    48 files, +6,311 lines
    Stack
    Repository files
    Skill
    v0.2.16
    Run
    Oct 7, 2026

    Result file ›Agent log ›

    What we saw

    Rubric 8/8. Scored from the summary. Packages from npm, the five test files unmodified under vitest (27 tests), prebuild wired, layout utilities in app/globals.css, the loader left as shipped, and a "Before you deploy" section that hands over siteUrl to set, each placeholder article by name, the category ids with redirects on a rename and how to rename one, and reportHelpSearchMiss to connect.

How long does it take, and what does it cost?

We quote this module per project. The price depends on what it has to connect to. The path to a number is short and free:

  1. Step 1

    Brief

    Tell us what the module must connect to. Takes minutes, in a chat.

  2. Step 2

    Prototype in 48 hours

    A clickable prototype of your system and a quote, at no cost.

  3. Step 3

    Build and handoff

    One project price. Source code, documentation and IP are yours.

Two ways to get Markdown help center

Build it yourself

Install the skill. Your own agent builds the module.

  • MIT licensed, no strings
  • Runs in Claude Code, Codex CLI and Gemini CLI
  • The same rules our engineers build by
$ npx skills add timerise-ai/help-center-markdown

Build it with Timerise

Send a brief. We build Markdown help center into a system you own.

  • Clickable prototype and a quote within 48 hours, free
  • One project price, no subscription, no commission
  • Source code, documentation and IP handed over
3 years of support included.

Generated from the skill's own files at commit 0877cf6. Every rule above links to where the repository says it. All skills