An Agent Skill that teaches an agent to build a markdown-backed help center in a Next.js App Router app: category folders of frontmatter articles, statically rendered landing, category, tag and article pages, client-side search with ranking and keyboard navigation, locale-aware routing with default-locale fallback, tags with slug identity and their own pages, related articles, breadcrumbs, JSON-LD and sitemap entries, and a content validator for CI. Content lives in the repository; there is no CMS.
A help center is a small static site with one hard requirement: every article must be reachable, from the sidebar, from search, and from a locale that has not been translated yet. Every template is shaped around that requirement, and the build fails for the author before a reader finds a gap.
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.
One command, via the skills.sh CLI, which installs the skill into every skills-compatible agent it detects, including Claude Code, Codex CLI and Gemini CLI:
npx skills add timerise-ai/help-center-markdownName the agents instead with -a, for example npx skills add timerise-ai/help-center-markdown -a claude-code -a codex.
Nothing here is Claude-specific: the skill is a plain Agent Skills folder,
SKILL.md plus markdown references with no file that calls a model, so cloning it into an agent's skills
directory is all an install is. For Claude Code:
git clone https://github.com/timerise-ai/help-center-markdown.git ~/.claude/skills/help-center-markdownTo scope it to a single project instead, clone it into that project's .claude/skills/ directory. For another
agent, clone into that agent's skills directory, or symlink the Claude Code copy so one git pull updates
every agent:
mkdir -p ~/.agents/skills
ln -s ~/.claude/skills/help-center-markdown ~/.agents/skills/help-center-markdownUpdate the skill with git pull in its directory. The current release is 0.2.16. See
CHANGELOG.md. The skills index lists the other
Timerise Skills and how to install them all at once.
The skill activates automatically when a task matches its description: building or extending a help center,
knowledge base, docs section, support articles or FAQ hub from markdown in the repo, or adding article search,
tag pages and chips, translated articles with fallback, hreflang and canonical rules, related links or a
collapsible article sidebar. Invoke it explicitly with /help-center-markdown in Claude Code,
$help-center-markdown in Codex CLI, or from /skills in Gemini CLI.
Each host matches a task against the description its own way, so invoke the skill explicitly on a first run
rather than assuming it fired. Only SKILL.md is read up front; the references/ files load on demand, so
the skill stays cheap in context until a topic is actually needed.
| File | Contents |
|---|---|
SKILL.md |
Entry point: architecture, critical facts, hard rules, quick start, and the reference directory |
README.md |
This front door |
CHANGELOG.md |
Keep a Changelog, one section per release, newest first |
CLAUDE.md |
What this repository is and the conventions for editing the skill itself |
LICENSE |
MIT |
references/adaptation.md |
The seam contract with the host app: styling, i18n, routing, the category rename, the non-negotiables restated, order of work |
references/content-model.md |
Config, types, frontmatter fields, slugs, and the CI validator |
references/content-loader.md |
Reading files into the index: gray-matter, caching, locale fallback, sorting |
references/search.md |
Client-side search: tokenizing, ranking, combobox keyboard behavior, no-results |
references/tags.md |
Tag slug identity, tag pages, chips, tag cloud, tag validation |
references/i18n.md |
Locales, strings, dates, default-locale fallback, hreflang and canonicals |
references/routes.md |
Pages, generateStaticParams, metadata, JSON-LD, sitemap entries |
references/ui.md |
Shell, header, sidebar, mobile drawer |
references/ui-content.md |
Breadcrumbs, category cards, article lists, the markdown renderer, style hooks |
references/extensions.md |
Full-text/Pagefind, table of contents, feedback, git dates, MDX, CMS, redirects |
references/provenance.md |
The 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.yml |
Runs the agent evals on every published release through the index's reusable workflow; copied verbatim from the standard |
The filesystem is a seam, not a premise: one getHelpIndex(locale) builds the index every page, the search
box, the sitemap and the validator read from, and nothing else touches fs. Swapping in a CMS or a database
means implementing a source that returns articles for a locale, and the routes, search and tag pages do not
change. The module is public, read-only and file-backed: no auth, no tenancy, no database, no object storage.
The host app's styling, renderer and i18n stay the host app's; references/adaptation.md is where you wire
them in.
These travel with the module and are never optional. They are the hard rules in SKILL.md, in the same
order, and references/adaptation.md restates them.
- Summaries, never articles, cross to the client.
toSummary/toSearchDocare 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. hidden, not a height cap, on collapsible nav. A height cap clips whatever does not fit and reports nothing;hiddenrenders every link of every category or none, and the shell template uses only that.- 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.
- Validation runs in CI. The runtime is forgiving on purpose, dropping bad refs and sorting missing
orders last, and
validate:helpfails the build for the author; the validator tests cover unresolved refs, order ties and skipped files. - Sort by
order, then title, then slug. Ties left toreaddirorder differ between filesystems, so the same deploy could list articles differently on another build machine; the loader test orders byorderthen title, never by filename, and the validator warns on ties. - 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.
- 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. - 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.
Everything else is the host app's: styling, naming, renderer, i18n system.
| Not this | Use instead |
|---|---|
| A blog: dated, authored posts with covers and localized slugs | The sibling blog-markdown skill; a different content model |
| Docs generated from code (OpenAPI, TypeDoc) | Their generators; link to the output |
| A CMS-backed help site with editors publishing at runtime | The 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 markdown | The host's renderer; this module is the navigation, search and locale model around many articles |
Issues and pull requests are welcome here. Pure markdown, with no build or lint step, but the code blocks are
checked: every ```ts and ```tsx block starting with // file: <path> is copied into a scratch project
and type-checked under strict and noUncheckedIndexedAccess, with the *.test.ts blocks run. Claims in
this skill are meant to be verifiable: if you change a factual claim, say how you verified it, whether against
the Next.js, gray-matter or react-markdown documentation, the HTML and ARIA specifications, or a reproduction.
Adding, removing or renaming a file in references/ means updating the quick start and the reference
directory table in SKILL.md, the file table above, and any relative cross-links. Every odd-looking part of
the templates is there for a reason, and references/provenance.md is the ledger that must stay truthful:
read it before simplifying anything, and add an entry for anything you change. Commits follow Conventional
Commits and releases follow STANDARD.md in the
index; CLAUDE.md carries the full editing conventions.
This is one of the Timerise Skills: modules for Next.js App
Router apps written by our own senior engineers from the modules they have shipped, not synthetic, each
published as its own repository and indexed there. They share one layout, so an agent that has read one knows
how to read the next: a SKILL.md entry point, references/ loaded on demand, and a seam contract carrying
the module's non-negotiables.
Built and maintained by Timerise.
MIT. See LICENSE.