Multi-locale markdown documentation viewer for Filament. Devs commit .md
files to git, panel users read them with a sidebar TOC, full-text search,
in-page locale switcher, and copy-to-clipboard code blocks.
This is prose docs (guides, how-tos, FAQs) — not auto-generated reference.
For schema-introspection docs, see wezlo/filament-auto-docs.
composer require wezlo/filament-docs
php artisan vendor:publish --tag=filament-docs-config
php artisan filament-docs:install # scaffolds resources/docs/{en,ar}/...
php artisan filament-docs:index --force # builds the search indexRegister the plugin on your panel:
use Wezlo\FilamentDocs\FilamentDocsPlugin;
$panel->plugins([
FilamentDocsPlugin::make()
->path('handbook') // panel-relative URL: /admin/handbook
->locales(['en', 'ar'])
->defaultLocale('en')
->navigationGroup('Help')
->navigationIcon('heroicon-o-book-open'),
]);The package's prose CSS and copy-button JS load automatically via
FilamentAsset::register() — nothing to wire up there. But the shipped
Blade views use Tailwind utility classes for layout (grid, spacing,
dark-mode), and if you use a custom Filament theme, Tailwind will purge those
classes unless the package's views are in your theme's @source paths.
Add this line to your panel's theme file:
/* resources/css/filament/{panel}/theme.css */
@source '../../../../vendor/wezlo/filament-docs/resources/views/**/*';Then rebuild:
npm run build # or: npm run devIf you're on the default Filament theme (no viteTheme(...) on the panel),
skip this step.
resources/docs/
├── _config.php # optional: section icons, ordering, hidden patterns
├── en/
│ ├── 01-getting-started.md
│ └── 02-orders/
│ ├── 01-create-order.md
│ └── _section.yml # optional: { title, icon }
└── ar/
└── 01-getting-started.md
- Numeric prefix (
01-,02-) controls order, stripped from titles. - Folders become sections in the sidebar.
- Optional YAML frontmatter (
title:,icon:). - Missing translations fall back to the default locale with a banner.
Folder names are English-by-convention (02-orders, site-panel,
workforce), so the sidebar and breadcrumbs need explicit translations for
each section. There are two ways:
Option 1 — single resources/docs/_config.php (recommended):
return [
'sections' => [
'orders' => [
'icon' => 'heroicon-o-shopping-cart',
'order' => 2,
'title' => [
'en' => 'Orders',
'ar' => 'الطلبات',
],
],
'site-panel' => [
'title' => ['en' => 'Site panel', 'ar' => 'لوحة الموقع'],
],
],
'hidden' => [],
];Option 2 — per-locale _section.yml (one per locale folder, useful
when content teams own translations independently):
# resources/docs/ar/02-orders/_section.yml
title: الطلبات
icon: heroicon-o-shopping-cartBoth title and icon accept either a plain string or a locale-keyed map.
Missing locales fall back to the default locale, then to
Str::headline(folderName).
Article titles are taken from the markdown's first # Heading (or
frontmatter title:) and so are localised automatically by writing the
markdown in each locale's tree.
- Sidebar TOC + breadcrumbs (auto-built from filesystem)
- Full-text search across all locales (toggle "Search all languages")
- In-page locale switcher with automatic RTL for
ar/he/fa/ur - GFM tables, task lists, fenced code, autolinks
- Heading anchors for deep-linking
- Copy-to-clipboard buttons on every code block
- File-mtime-keyed search cache (auto-invalidates on content changes)
Route /admin/{slug}/{path?}
↓
DocsPage (Livewire) — properties: $locale, $articleSlug, $search
↓ resolves locale (URL → app → config default)
↓ TreeBuilder walks resources/docs/{locale}, applies _config.php
↓ FilesystemDocSource->load() reads .md, falls back to default locale
↓ MarkdownRenderer (CommonMark + GFM + heading anchors) → HTML
↓ Searcher scores: title (×3) > heading (×2) > body (×1) + exact-phrase bonus
Implement Wezlo\FilamentDocs\Contracts\DocSource and bind in a service
provider — useful for DB-backed docs, S3-stored markdown, etc.
$this->app->bind(
Wezlo\FilamentDocs\Contracts\DocSource::class,
YourCustomSource::class,
);| Command | Purpose |
|---|---|
php artisan filament-docs:install |
Scaffold sample docs into resources/docs/. |
php artisan filament-docs:index [--force] |
Rebuild the search index. |
Published to config/filament-docs.php. Key options:
content_path,default_locale,locales,rtl_localesroute.slug,navigation.{group, icon, sort}search.{enabled, max_results, snippet_length, min_length}markdown.{gfm, heading_anchors}
cd packages/wezlo/filament-docs
composer install
vendor/bin/pest --compactMIT