### Install via Composer Source: https://github.com/jeffersongoncalves/laravel-github-readme/blob/master/README.md Installs the package via Composer. ```bash composer require jeffersongoncalves/laravel-github-readme ``` -------------------------------- ### Install and migrate laravel-github-readme Source: https://github.com/jeffersongoncalves/laravel-github-readme/blob/master/resources/boost/skills/github-readme-development/SKILL.md Install the package, publish its migration, and run the migration. Requires PHP 8.2+, Laravel 11/12/13, spatie/laravel-package-tools ^1.14, and league/commonmark ^2.4. ```bash composer require jeffersongoncalves/laravel-github-readme php artisan vendor:publish --tag="laravel-github-readme-migrations" php artisan migrate ``` -------------------------------- ### Configure laravel-github-readme options Source: https://github.com/jeffersongoncalves/laravel-github-readme/blob/master/README.md Default configuration for the laravel-github-readme package. Set the disk, check interval, token, user agent, timeout, and optional custom renderer. The renderer defaults to null, using the internal League\CommonMark renderer with GFM and heading permalinks. ```php return [ // The filesystem disk used to store rendered README HTML files. 'disk' => env('GITHUB_README_DISK', 'local'), // Minutes a freshly verified README is served without contacting GitHub. 'check_interval_minutes' => (int) env('GITHUB_README_CHECK_INTERVAL', 10), // Optional GitHub token (falls back to config('services.github.token')). 'token' => env('GITHUB_TOKEN', env('GITHUB_README_TOKEN')), // User-Agent header sent on every GitHub API request. 'user_agent' => env('GITHUB_README_USER_AGENT', 'laravel-github-readme'), // Request timeout in seconds. 'timeout' => (int) env('GITHUB_README_TIMEOUT', 8), // Optional renderer callable: fn (string $markdown): string. // Null uses the internal League\CommonMark renderer (GFM + heading permalinks). 'renderer' => null, ]; ``` -------------------------------- ### Run tests, coverage, PHPStan, and Pint Source: https://github.com/jeffersongoncalves/laravel-github-readme/blob/master/resources/boost/skills/github-readme-development/SKILL.md Commands to run the test suite, generate coverage, run static analysis with PHPStan, and format code with Pint. ```bash vendor/bin/pest # run tests vendor/bin/pest --coverage vendor/bin/phpstan analyse vendor/bin/pint ``` -------------------------------- ### Publish and Run Migration Source: https://github.com/jeffersongoncalves/laravel-github-readme/blob/master/README.md Publishes and runs the migration that creates the `github_readme_cache` table. ```bash php artisan vendor:publish --tag="laravel-github-readme-migrations" php artisan migrate ``` -------------------------------- ### Configuration keys for laravel-github-readme Source: https://github.com/jeffersongoncalves/laravel-github-readme/blob/master/resources/boost/skills/github-readme-development/SKILL.md Configuration keys for the package. The token falls back to `config('services.github.token')` when the package key is null. ```php 'disk' => env('GITHUB_README_DISK', 'local'), 'check_interval_minutes' => (int) env('GITHUB_README_CHECK_INTERVAL', 10), 'token' => env('GITHUB_TOKEN', env('GITHUB_README_TOKEN')), 'user_agent' => env('GITHUB_README_USER_AGENT', 'laravel-github-readme'), 'timeout' => (int) env('GITHUB_README_TIMEOUT', 8), 'renderer' => null, ``` -------------------------------- ### Publish Config File Source: https://github.com/jeffersongoncalves/laravel-github-readme/blob/master/README.md Optionally publishes the config file. ```bash php artisan vendor:publish --tag="laravel-github-readme-config" ``` -------------------------------- ### Use a dedicated disk for cached READMEs Source: https://github.com/jeffersongoncalves/laravel-github-readme/blob/master/README.md Define a dedicated 'github' disk in config/filesystems.php and set the GITHUB_README_DISK environment variable to 'github' to isolate cached READMEs from the default local disk. ```php // config/filesystems.php 'disks' => [ 'github' => [ 'driver' => 'local', 'root' => storage_path('app/github'), 'throw' => false, ], ], ``` ```dotenv GITHUB_README_DISK=github ``` -------------------------------- ### Configure Laravel package with Spatie PackageServiceProvider Source: https://github.com/jeffersongoncalves/laravel-github-readme/blob/master/resources/boost/skills/github-readme-development/SKILL.md Registers the package with Spatie's PackageServiceProvider. The hasMigration call publishes the migration stub under the 'laravel-github-readme-migrations' tag. ```php public function configurePackage(Package $package): void { $package ->name('laravel-github-readme') ->hasConfigFile() ->hasMigration('create_github_readme_cache_table'); } ``` -------------------------------- ### Fetch and Sanitize README HTML Source: https://github.com/jeffersongoncalves/laravel-github-readme/blob/master/README.md Fetches a repository README as HTML, optionally for a specific branch/tag/ref, and sanitizes it before display. The HTML is untrusted and must always be sanitized. ```php use JeffersonGoncalves\GitHubReadme\GitHubReadme; use JeffersonGoncalves\HtmlSanitizer\Facades\HtmlSanitizer; // example sanitizer // Fetch the default-branch README, rendered to HTML and cached on disk. $html = GitHubReadme::fetchHtml('https://github.com/owner/repo'); // Fetch a specific branch/tag/ref. $html = GitHubReadme::fetchHtml('https://github.com/owner/repo', '2.x'); // ALWAYS sanitize before display — the HTML is untrusted. echo HtmlSanitizer::clean($html); ``` -------------------------------- ### Run tests with composer test Source: https://github.com/jeffersongoncalves/laravel-github-readme/blob/master/README.md Runs the test suite for the package using Composer. ```bash composer test ``` -------------------------------- ### Post-process HTML with Helpers Source: https://github.com/jeffersongoncalves/laravel-github-readme/blob/master/README.md Post-processing helpers to decorate the rendered HTML: mark external links, lazy-load images, and wrap wide tables. All are pure and safe to chain. ```php // Open off-site links in a new tab with rel="nofollow noopener". $html = GitHubReadme::markExternalLinks($html, 'mysite.test'); // Lazy-load every image except the first (kept eager as the LCP candidate). $html = GitHubReadme::lazyloadImages($html); // Wrap wide tables in a horizontally-scrollable container. $html = GitHubReadme::wrapTables($html); ``` -------------------------------- ### Pest tests for GitHubReadme fetch and cache behavior Source: https://github.com/jeffersongoncalves/laravel-github-readme/blob/master/resources/boost/skills/github-readme-development/SKILL.md Pest tests for the GitHubReadme package. The first test verifies that a fresh fetch renders the README and stores a cache entry. The second test travels 11 minutes past the freshness window to force a conditional request and asserts the cached HTML is reused on a 304 response. ```php use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Storage; use JeffersonGoncalves\GitHubReadme\GitHubReadme; use JeffersonGoncalves\GitHubReadme\Models\ReadmeCache; it('renders and stores on first fetch', function () { Storage::fake('local'); Http::fake([ 'api.github.com/repos/owner/repo/readme*' => Http::response('# Hi', 200, ['ETag' => '"e1"']), ]); $html = GitHubReadme::fetchHtml('https://github.com/owner/repo', 'main'); expect($html)->toContain('Hi'); expect(ReadmeCache::where('repo', 'owner/repo')->exists())->toBeTrue(); Http::assertSentCount(1); }); it('reuses the cache on a 304', function () { Storage::fake('local'); Http::fakeSequence('api.github.com/*') ->push('# Hi', 200, ['ETag' => '"e1"']) ->push('', 304); $first = GitHubReadme::fetchHtml('https://github.com/owner/repo', 'main'); $this->travel(11)->minutes(); $second = GitHubReadme::fetchHtml('https://github.com/owner/repo', 'main'); expect($second)->toBe($first); Http::assertSentCount(2); }); ``` -------------------------------- ### Custom markdown renderer with heading permalinks Source: https://github.com/jeffersongoncalves/laravel-github-readme/blob/master/README.md Set a custom markdown renderer callable. The built-in renderer strips raw HTML; if your custom renderer allows raw HTML, you must sanitize the output before it reaches a browser. ```php 'renderer' => fn (string $markdown): string => \JeffersonGoncalves\Markdown\Markdown::render($markdown, headingPermalinks: true), ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.