spatie/laravel-export
Export your Laravel app as a static site bundle. Crawls your routes to generate HTML for discovered URLs and includes the public directory for assets. Ideal for blogs/sites built with Laravel, then deployed to Netlify or any static host.
Installation:
composer require spatie/laravel-export
Publish the config (optional):
php artisan vendor:publish --provider="Spatie\Export\ExportServiceProvider"
First Export:
php artisan export
Outputs static HTML files to storage/app/export (default) with all routes and the public directory.
posts routes).php artisan export
export folder to Netlify/Vercel for hosting.php artisan export.
// config/export.php
'crawl' => true,
'paths' => [
'/',
'/blog/{post}',
'/about',
],
Or dynamically via Exporter class:
$exporter->paths(Post::all()->pluck('slug'));
'include_files' => [
'public' => '',
'storage/app/docs' => 'docs',
],
'exclude_file_patterns' => [
'/\.php$/',
'/mix-manifest\.json$/',
],
'before' => [
'build' => 'npm run build',
],
'after' => [
'deploy' => 'netlify deploy --prod',
],
Skip hooks with flags:
php artisan export --skip-deploy
Exporter class in a service provider:
public function boot(Exporter $exporter) {
if ($this->app->environment('production')) {
$exporter->crawl(false)->paths(['/']);
}
}
Route::post('/export', function () {
Artisan::call('export');
return response()->json(['status' => 'exported']);
});
// config/filesystems.php
'disks' => [
'export' => [
'driver' => 's3',
'bucket' => 'my-static-site',
],
],
Circular Redirects:
paths to whitelist safe routes.Asset Paths:
public/ paths in HTML break static exports.asset() helper or configure APP_URL in .env:
APP_URL=https://your-static-site.com
Dynamic Content:
Auth::user()).now()).if (request()->header('X-Laravel-Export')) {
return response()->view('static-version');
}
Memory Limits:
'use_streaming' => true,
Symlinks:
exclude_file_patterns or resolve symlinks manually.php artisan export --dry-run
php artisan export --verbose
exclude_file_patterns isn’t blocking critical assets.Custom Crawlers:
Extend Spatie\Crawler\Crawler to handle custom routes (e.g., API-generated pages).
Post-Processing:
Modify exported HTML with a after hook:
'after' => [
'optimize' => 'htmlmin export/*.html',
],
Middleware for Exports: Add a middleware to modify responses for static exports:
public function handle($request, Closure $next) {
if ($request->header('X-Laravel-Export')) {
// Serve static version
}
return $next($request);
}
$exporter->paths(array_diff($newRoutes, $cachedRoutes));
paths for dev/staging/prod:
$exporter->paths(config('export.paths.' . config('app.env')));
- name: Export static site
run: php artisan export
- name: Deploy
uses: netlify/actions/deploy@v1
with:
directory: storage/app/export
How can I help you explore Laravel packages today?