schaefersoft/laravel-llms-txt
最新稳定版本:1.1.0
Composer 安装命令:
composer require schaefersoft/laravel-llms-txt
包简介
Automatically generate llms.txt and llms-full.txt for Laravel applications
README 文档
README
Automatically generate llms.txt and llms-full.txt files for your Laravel application — helping AI models understand your website, just like sitemap.xml helps search engines.
Built according to the llmstxt.org specification.
Requirements: PHP 8.2+ and Laravel 10, 11, 12, or 13.
Table of Contents
- Installation
- Quick Start
- Building Your Document
- Configuration
- Routes
- Localization
- Static File Generation
- llms-full.txt
- Caching
- Output Format
- Testing
- License
Installation
composer require schaefersoft/laravel-llms-txt
Publish the configuration file:
php artisan vendor:publish --tag=llms-txt-config
That's it. The package is auto-discovered by Laravel, and /llms.txt is available immediately.
Quick Start
The package works in two modes:
-
Zero-config — Without any setup,
/llms.txtis automatically generated from all registeredGETroutes in your application. Internal routes (Telescope, Horizon, Debugbar) and routes with URI parameters are excluded. -
Custom definition (recommended) — Register a configure callback to have full control over the output. It always takes precedence over auto-generation.
// app/Providers/AppServiceProvider.php use SchaeferSoft\LaravelLlmsTxt\LlmsTxt; public function boot(): void { LlmsTxt::configure(fn ($llms) => $llms ->title('My App') ->description('A short description of what this site offers.') ->section('Services', fn ($s) => $s ->entry('Web Development', 'https://example.com/web', 'Laravel & Vue.js') ->entry('Hosting', 'https://example.com/hosting', 'Managed hosting') ) ); }
This produces:
# My App > A short description of what this site offers. ## Services - [Web Development](https://example.com/web): Laravel & Vue.js - [Hosting](https://example.com/hosting): Managed hosting
Tip: For larger projects, consider a dedicated
LlmsTxtServiceProviderto keep yourAppServiceProviderclean.
Building Your Document
Title and Description
Every document starts with a title and an optional description:
LlmsTxt::make() ->title('My App') ->description('Short tagline for the site.');
Both methods accept a string or a Closure for lazy evaluation (useful for localization):
LlmsTxt::make() ->title(fn () => __('llms.title')) ->description(fn () => __('llms.description'));
Sections and Entries
Sections group related entries under a heading. Entries are links with a title, URL, and optional description.
Verbose style — useful when you need to store references to entries:
use SchaeferSoft\LaravelLlmsTxt\Entry; use SchaeferSoft\LaravelLlmsTxt\Section; $section = Section::create('Services') ->addEntry(Entry::create('Web Development', 'https://example.com/web', 'Laravel & Vue.js')) ->addEntry(Entry::create('Hosting', 'https://example.com/hosting')); LlmsTxt::make() ->title('My App') ->addSection($section);
Fluent Shorthand
For a more compact style, use section() and entry() directly on the builder:
LlmsTxt::make() ->title('My App') ->section('Services', fn ($s) => $s ->entry('Web Development', 'https://example.com/web', 'Laravel & Vue.js') ->entry('Hosting', 'https://example.com/hosting', 'Managed hosting') ) ->section('References', fn ($s) => $s ->entry('Projects', 'https://example.com/references', 'All client projects') );
create()andmake()are identical — use whichever you prefer.
Note: The
entry()shorthand returns theSection, not theEntry. To usewithDescription(), useEntry::create()directly or pass the description as the third argument toentry().
Model-Based Entries
Use entries() on a section to map a collection of models (or any iterable) into entries. The callback receives each item and must return an Entry instance.
LlmsTxt::configure(fn ($llms) => $llms ->title('My App') ->section('Services', fn ($s) => $s ->entries(Service::published()->get(), fn ($service) => Entry::create( $service->name, route('services.show', $service), $service->tagline, )) ) );
You can combine entry() and entries() freely in the same section:
->section('Blog', fn ($s) => $s ->entry('All Posts', route('blog.index')) ->entries(Post::featured()->get(), fn ($post) => Entry::create( $post->title, route('blog.show', $post), )) )
Conditional Content
Both LlmsTxt and Section support a when() method that mirrors Laravel's own when():
LlmsTxt::make() ->title('My App') ->section('Services', fn ($s) => $s ->entry('Web Development', 'https://example.com/web') ->when((bool) config('features.shop'), fn ($s) => $s ->entry('Shop', 'https://example.com/shop') ) ) ->when((bool) config('features.api'), fn ($llms) => $llms ->section('API', fn ($s) => $s ->entry('API Docs', 'https://example.com/api') ) );
You can also pass a Closure as the condition for lazy evaluation:
->when(fn () => Feature::active('shop'), fn ($s) => $s ->entry('Shop', 'https://example.com/shop') )
Configuration
After publishing, the config file is at config/llms-txt.php:
| Option | Default | Description |
|---|---|---|
route_enabled |
true |
Enable or disable the HTTP routes entirely. |
llms_txt_route |
'/llms.txt' |
URL path for the standard file. |
llms_full_txt_route |
'/llms-full.txt' |
URL path for the full file. |
register_routes |
true |
Auto-register routes. Set to false for manual registration. |
cache_enabled |
true |
Cache rendered output. |
cache_ttl |
3600 |
Cache lifetime in seconds. |
disk |
'public' |
Filesystem disk used by the Artisan command. |
locales |
[] |
List of supported locales (e.g. ['en', 'de']). |
localize_routes |
false |
Register locale-prefixed routes like /en/llms.txt. |
Routes
Automatic Route Registration
By default, the package registers two routes:
| Route | Description |
|---|---|
GET /llms.txt |
Serves the standard llms.txt output. |
GET /llms-full.txt |
Serves the llms-full.txt output (with fetched content). |
These are registered automatically when register_routes is true (the default).
Manual Route Registration
To apply custom middleware or headers, disable automatic registration and call LlmsTxt::routes() yourself:
// config/llms-txt.php 'register_routes' => false,
// routes/web.php use SchaeferSoft\LaravelLlmsTxt\LlmsTxt; Route::middleware(['web', 'cache.headers:public;max_age=3600']) ->group(function () { LlmsTxt::routes(); });
LlmsTxt::routes() is idempotent — it is safe to call more than once.
Localization
Translating Content
A single configure callback covers all locales. The package sets the application locale before invoking your callback, so __() and route() return the correct values automatically.
LlmsTxt::configure(fn ($llms) => $llms ->title(__('llms.title')) ->description(__('llms.description')) ->section(__('llms.sections.services'), fn ($s) => $s ->entry( __('llms.entries.web_dev'), route('services.web'), __('llms.entries.web_dev_desc'), ) ) );
Create your language files as usual:
// lang/en/llms.php return [ 'title' => 'My App', 'description' => 'Software agency', 'sections' => ['services' => 'Services'], 'entries' => [ 'web_dev' => 'Web Development', 'web_dev_desc' => 'Modern web applications with Laravel & Vue.js', ], ];
// lang/de/llms.php return [ 'title' => 'Meine App', 'description' => 'Software-Agentur', 'sections' => ['services' => 'Leistungen'], 'entries' => [ 'web_dev' => 'Webentwicklung', 'web_dev_desc' => 'Moderne Webanwendungen mit Laravel & Vue.js', ], ];
Locale-Prefixed Routes
Enable locale-prefixed routes to serve translated versions at /en/llms.txt, /de/llms.txt, etc.:
// config/llms-txt.php 'locales' => ['en', 'de'], 'localize_routes' => true,
Unknown locale segments return a 404 response.
Using mcamara/laravel-localization
If you use mcamara/laravel-localization, disable automatic registration and wrap the routes in a localized group:
// config/llms-txt.php 'register_routes' => false,
// routes/web.php Route::group( ['prefix' => LaravelLocalization::setLocale(), 'middleware' => ['localize']], function () { LlmsTxt::routes(); } );
Static File Generation
Artisan Command
Generate static files with the llms:generate command:
# Generate public/llms.txt php artisan llms:generate # Also generate public/llms-full.txt php artisan llms:generate --full # Generate for a specific locale (e.g. public/de/llms.txt) php artisan llms:generate --locale=de # Generate for all configured locales php artisan llms:generate --all-locales # Combine flags php artisan llms:generate --all-locales --full
Files are written to the filesystem disk configured via the disk option (default: public).
Programmatic Export
You can also write files to disk from code:
// Write to the default location LlmsTxt::make()->title('My App')->writeToDisk(); // Write to a custom path LlmsTxt::make()->title('My App')->writeToDisk('custom/path/llms.txt'); // Write with a locale prefix (writes to de/llms.txt) LlmsTxt::make()->title('My App')->locale('de')->writeToDisk(); // Write the full version LlmsTxt::make()->title('My App')->writeFullToDisk();
llms-full.txt
The full variant fetches the content of each entry URL and appends it below the entry. URLs that cannot be fetched are silently skipped.
// Render as a string $content = LlmsTxt::make() ->title('My App') ->section('Docs', fn ($s) => $s ->entry('API', 'https://example.com/api') ) ->renderFull(); // Write directly to disk LlmsTxt::make()->title('My App')->writeFullToDisk();
The route /llms-full.txt serves this output dynamically.
Caching
When cache_enabled is true (the default), rendered output is cached for the duration specified by cache_ttl.
// Use the default cache key ('llms-txt') $content = LlmsTxt::make()->title('My App')->getCached(); // Use a custom cache key $content = LlmsTxt::make()->title('My App')->getCached('my-custom-key'); // Flush the cache LlmsTxt::make()->flushCache(); // default key LlmsTxt::make()->flushCache('my-custom-key');
Output Format
llms.txt
# Site Title > Site description ## Section Name - [Entry Title](https://example.com): Entry description - [Another Entry](https://example.com/other)
llms-full.txt
Same structure as llms.txt, but with the fetched HTML/text content of each URL appended below its entry.
Testing
composer test
License
MIT — see LICENSE.
统计信息
- 总下载量: 270
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 3
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-03-26