| name | docsmith-development |
| description | Use for tasks involving mrpunyapal/docsmith: building static documentation sites from Markdown, the Docsmith::build()/make() API, the vendor/bin/docsmith CLI, frontmatter keys, versioned docs, docs hubs, remote source syncing, llms.txt export, media publishing, and Open Graph images. Do not use for general static site generators unrelated to Docsmith. |
| license | MIT |
| metadata | {"author":"mrpunyapal"} |
Docsmith Development
Docsmith turns a directory of Markdown into a self-contained static documentation site (sidebar navigation, search, dark mode, code copy). Requires PHP 8.3+. It is framework-agnostic; there is no Laravel or Illuminate dependency.
Install
composer require --dev mrpunyapal/docsmith
Three entry points, one option model
Docsmith::build(source: __DIR__.'/md', output: __DIR__.'/docs', title: 'Docs');
Docsmith::make()
->source(__DIR__.'/md')
->output(__DIR__.'/docs')
->title('Project Docs')
->accentColor('#1d4ed8')
->repositoryUrl('https://github.com/acme/project')
->siteUrl('https://acme.github.io/project')
->rightSidebar()
->build();
vendor/bin/docsmith build --source=md --output=docs --title="Project Docs"
Common options: output (default docs), description, accentColor, accentColorDark, customCss, baseUrl, repositoryUrl, siteUrl, editBranch, editPrefix, favicon, showDocsmithBadge(false), navigationOrder([...]).
Output model
md/index.md becomes index.html; md/installation.md becomes installation/index.html.
- Missing
index.md: a landing page is generated automatically.
- Every build generates
search-index.json, sitemap.xml, and .nojekyll.
- LLM export is on by default:
llms.txt, llms-full.txt, export/docs.md (->llmsExport(false) to disable). siteUrl() is required for correct absolute URLs in these exports.
- Body links to Markdown files (
[text](other-page.md)) are rewritten to built page URLs at render time, including relative paths and fragments. Unmatched .md links are left untouched.
- Media files (images, video, audio, PDF) in the source tree are published into the output with the same relative path, and relative references are rewritten per page so they resolve from the built URL. Remote URLs, root-relative paths, data URIs, and unpublished files are left untouched.
->publishMedia(false) disables copying and rewriting.
Frontmatter keys
title, description, slug, order, sidebar_label, hidden: true (excludes the page from nav, search index, and pagination but keeps the URL live), plus OG overrides og_image, og_title, og_description.
Versions and hubs
- Versions:
->versions([['slug'=>'v2','label'=>'v2.0','default'=>true], ...]). Versioned builds require ->source(); each version reads {source}/{slug} unless it sets its own source. The default version owns the site root, others nest under {slug}/.
- Hub (multiple independent doc sets with a sidebar dropdown):
->hub(['pkg' => ['label' => ..., 'source' => ..., 'navigation' => [...], 'versions' => [...]]]). Entries mount under their slug; / forwards to the first entry.
Remote sources (git sync without the git binary)
Declare sources in docsmith.sources.php, then sync and build:
return [
['repository' => 'https://github.com/acme/pkg.git', 'ref' => 'main', 'path' => 'docs', 'target' => 'pkg'],
];
php bin/docsmith sync
php bin/docsmith build --sync
Commit docsmith.sources.lock.json so repeat syncs are incremental; delete it to force a full refresh. Sync failures exit non-zero, which is CI-safe.
Private repositories: add 'token' => '${ACME_PAT}' (resolved from the environment; a missing variable is a config error naming it) and optional 'username'. Without a token key, fallbacks apply: DOCSMITH_TOKEN works for any host; GITHUB_TOKEN / GH_TOKEN are used only for github.com hosts and never sent elsewhere. Tokens may also live in a .env file next to docsmith.sources.php; real environment variables always take precedence. Never commit real tokens.
Open Graph images
->ogGeneratedAll() for one shared card, ->ogGeneratedPerPage() for per-page cards. Needs npm i -D playwright capturist@^0.1.3 plus npx playwright install chromium; Docsmith writes the capturist config.
->ogLink(url) points at an existing image.
- Always set
siteUrl() so crawlers get absolute og:image URLs.
- Capture is incremental through the capturist cache;
->forceOg() recaptures everything.
Developing inside this repository
composer test
composer test:lint
composer test:types
composer test:unit
composer docs:build
Pipeline: Docsmith (API) -> Builder/BuildConfig (config validation) -> SourceScanner -> CommonMarkRenderer -> SiteBuilder (pages, hub dropdown, version pills, media reference rewriting) -> AssetPublisher (search index, sitemap, llms export) -> MediaPublisher (copies media files from source). Remote syncing lives in src/RemoteSources/*.
Gotchas
- PHP 8.3 minimum. No Laravel required, so never add Illuminate imports when fixing issues.
- Prefer hex colors for accents; named colors break variant derivation.
- Versioned builds without
->source() fail. Pages that exist only in a non-default version are NOT duplicated to the root.
- Hub entries with
versions: the primary version mounts at the entry slug, siblings nest under {entry}/{version}/.