aaronfrancis / docsync
Sync documentation from GitHub repositories and serve them in your Laravel application
Installs: 36
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/aaronfrancis/docsync
Requires
- php: ^8.2
- illuminate/console: ^11.0|^12.24
- illuminate/contracts: ^11.0|^12.24
- illuminate/database: ^11.0|^12.24
- illuminate/filesystem: ^11.0|^12.24
- illuminate/process: ^11.0|^12.24
- illuminate/support: ^11.0|^12.24
- league/commonmark: ^2.0
- torchlight/torchlight-commonmark: ^0.6
Requires (Dev)
- orchestra/testbench: ^9.6|^10.5
- pestphp/pest: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
Suggests
- filament/filament: Required for the admin panel integration (^3.0)
README
Sync documentation from GitHub repositories and serve them in your Laravel application.
Features
- Git sparse checkout - Efficiently clones only the docs folder from repositories
- Markdown parsing - CommonMark + GFM with Torchlight syntax highlighting
- Navigation generation - Builds navigation trees from
_meta.jsonfiles - Table of contents - Automatically extracts headings for TOC
- Pagination - Previous/next page navigation
- Caching - Built-in caching for production performance
- Filament integration - Optional admin panel for managing documentation projects
Requirements
- PHP 8.2+
- Laravel 11 or 12
- Torchlight account (for syntax highlighting)
Installation
composer require aaronfrancis/docsync
Publish the configuration and migration:
php artisan vendor:publish --tag=docsync-config php artisan vendor:publish --tag=docsync-migrations php artisan migrate
Configuration
// config/docsync.php return [ // Where synced docs are stored 'storage_path' => storage_path('app/docs'), // Config key for GitHub token (for private repos) 'github_token_key' => 'services.github.token', // Cache settings 'cache' => [ 'enabled' => true, 'ttl' => 3600, // 1 hour ], ];
Set your GitHub token in config/services.php:
'github' => [ 'token' => env('GITHUB_TOKEN'), ],
Usage
Creating Documentation Projects
Projects are stored in the database. Create them however you prefer:
use AaronFrancis\DocSync\Models\DocumentationProject; DocumentationProject::create([ 'slug' => 'my-package', 'name' => 'My Package', 'description' => 'Documentation for my package', 'repository_url' => 'https://github.com/org/repo', 'branch' => 'main', 'docs_path' => 'docs', 'sort_order' => 0, 'is_active' => true, ]);
Syncing Documentation
Sync all active projects:
php artisan docs:sync
Sync a specific project:
php artisan docs:sync --project=my-package
Scheduling Syncs
Add to your routes/console.php:
use Illuminate\Support\Facades\Schedule; Schedule::command('docs:sync') ->hourly() ->withoutOverlapping() ->runInBackground();
Using the Service
use AaronFrancis\DocSync\Facades\DocSync; // or inject: AaronFrancis\DocSync\Services\DocumentationService // Get all packages $packages = DocSync::getPackages(); // Get a single package $package = DocSync::getPackage('my-package'); // Get navigation tree $navigation = DocSync::getNavigation('my-package'); // Get a page $page = DocSync::getPage('my-package', 'getting-started'); // Get table of contents from HTML $toc = DocSync::getTableOfContents($page['content']); // Get pagination (previous/next) $pagination = DocSync::getPagination('my-package', 'getting-started'); // Get next steps (upcoming pages with descriptions) $nextSteps = DocSync::getNextSteps('my-package', 'getting-started', 3); // Clear cache DocSync::clearCache(); // all DocSync::clearCache('my-package'); // specific package
Documentation Structure
Your repository should have a docs folder (or whatever you configure) with:
docs/
├── _meta.json # Navigation structure
├── index.md # Landing page
├── getting-started.md
└── advanced/
└── configuration.md
The _meta.json defines navigation:
{
"pages": [
{ "slug": "index", "title": "Introduction" },
{ "slug": "getting-started", "title": "Getting Started" },
{
"slug": "advanced",
"title": "Advanced",
"children": [
{ "slug": "configuration", "title": "Configuration" }
]
}
]
}
Markdown files support frontmatter:
--- title: Getting Started description: Learn how to get started with the package --- # Getting Started Your content here...
Filament Integration
If you're using Filament, register the resource in your panel provider:
use AaronFrancis\DocSync\Filament\Resources\DocumentationProjectResource; public function panel(Panel $panel): Panel { return $panel // ... ->resources([ DocumentationProjectResource::class, ]); }
This provides a full CRUD interface for managing documentation projects with sync actions.
Building Your Frontend
This package handles syncing and parsing—you build the frontend. Here's a basic controller example:
use AaronFrancis\DocSync\Facades\DocSync; class DocsController extends Controller { public function index() { return view('docs.index', [ 'packages' => DocSync::getPackages(), ]); } public function show(string $package, ?string $slug = null) { $currentPackage = DocSync::getPackage($package); abort_unless($currentPackage, 404); $page = DocSync::getPage($package, $slug); abort_unless($page, 404); return view('docs.show', [ 'page' => $page, 'navigation' => DocSync::getNavigation($package), 'toc' => DocSync::getTableOfContents($page['content']), 'pagination' => DocSync::getPagination($package, $slug), 'packages' => DocSync::getPackages(), 'currentPackage' => $currentPackage, ]); } }
Testing
composer test
Code Style
composer format
License
MIT License. See LICENSE for details.