PHPackages                             vormkracht10/laravel-static - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. vormkracht10/laravel-static

Abandoned → [backstage/laravel-static](/?search=backstage%2Flaravel-static)Library[Caching](/categories/caching)

vormkracht10/laravel-static
===========================

Serving your Laravel app with speed using static caching

v0.2.4(1y ago)5302MITPHPPHP ^8.1CI failing

Since Oct 2Pushed 3mo ago2 watchersCompare

[ Source](https://github.com/backstagephp/laravel-static)[ Packagist](https://packagist.org/packages/vormkracht10/laravel-static)[ Docs](https://github.com/backstagephp/laravel-static)[ GitHub Sponsors](https://github.com/backstagephp)[ RSS](/packages/vormkracht10-laravel-static/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (13)Versions (12)Used By (0)

Laravel Static
==============

[](#laravel-static)

[![Total Downloads](https://camo.githubusercontent.com/8e415d6cd037c46a97925fbeb5b6068921e3c4eef221e6c70af3218af4a7c72f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6261636b73746167652f6c61726176656c2d7374617469632e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/backstage/laravel-static)[![Tests](https://github.com/backstagephp/laravel-static/actions/workflows/run-tests.yml/badge.svg?branch=main)](https://github.com/backstagephp/laravel-static/actions/workflows/run-tests.yml)[![PHPStan](https://github.com/backstagephp/laravel-static/actions/workflows/phpstan.yml/badge.svg?branch=main)](https://github.com/backstagephp/laravel-static/actions/workflows/phpstan.yml)[![GitHub release (latest by date)](https://camo.githubusercontent.com/725bff39b26a96a1ce232fa64509ed13205daede29eb20c06a9e09a0efc31386/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6261636b73746167657068702f6c61726176656c2d737461746963)](https://camo.githubusercontent.com/725bff39b26a96a1ce232fa64509ed13205daede29eb20c06a9e09a0efc31386/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6261636b73746167657068702f6c61726176656c2d737461746963)[![Packagist PHP Version Support](https://camo.githubusercontent.com/8f27a9e24e83bcc125604c052f39c15be110fdeb5f33c44a91db7598efe5b63f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6261636b73746167652f6c61726176656c2d737461746963)](https://camo.githubusercontent.com/8f27a9e24e83bcc125604c052f39c15be110fdeb5f33c44a91db7598efe5b63f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6261636b73746167652f6c61726176656c2d737461746963)[![Latest Version on Packagist](https://camo.githubusercontent.com/82dddb0d5aff5394cd31b98fa8ec3a7be2a86c7d4b2b8880c93c70bc2f54ea17/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6261636b73746167652f6c61726176656c2d7374617469632e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/backstage/laravel-static)

**Supercharge your Laravel application with static file caching.** Laravel Static converts your dynamic Laravel responses into static HTML files, dramatically improving performance and reducing server load.

Why Laravel Static?
-------------------

[](#why-laravel-static)

Traditional Laravel applications generate HTML on every request, hitting your database and executing PHP code repeatedly. Laravel Static solves this by:

- **Converting dynamic responses to static HTML files** — Serve pre-generated HTML instead of executing PHP on every request
- **Reducing server load** — Let your web server (Nginx, Apache) serve static files directly
- **Improving response times** — Static files are served in milliseconds, not hundreds of milliseconds
- **Supporting multiple caching strategies** — Choose between route-based caching or automatic web crawling
- **Handling complex scenarios** — Multi-domain support, query string handling, and HTML minification

Requirements
------------

[](#requirements)

- PHP 8.1 or higher
- Laravel 11.0 or higher

Installation
------------

[](#installation)

Install the package via Composer:

```
composer require backstage/laravel-static
```

Publish the configuration file:

```
php artisan vendor:publish --tag="laravel-static-config"
```

Optionally, publish the migrations if you need database-backed features:

```
php artisan vendor:publish --tag="laravel-static-migrations"
php artisan migrate
```

Quick Start
-----------

[](#quick-start)

### 1. Enable Static Caching

[](#1-enable-static-caching)

Add the `STATIC_ENABLED=true` environment variable to your `.env` file:

```
STATIC_ENABLED=true
```

### 2. Add Middleware to Routes

[](#2-add-middleware-to-routes)

Apply the `StaticResponse` middleware to routes you want to cache:

```
use Backstage\LaravelStatic\Middleware\StaticResponse;

Route::get('/', function () {
    return view('welcome');
})->middleware(StaticResponse::class);

// Or apply to route groups
Route::middleware([StaticResponse::class])->group(function () {
    Route::get('/about', [PageController::class, 'about']);
    Route::get('/contact', [PageController::class, 'contact']);
    Route::get('/blog', [BlogController::class, 'index']);
});
```

### 3. Build the Static Cache

[](#3-build-the-static-cache)

Generate your static files:

```
php artisan static:build
```

That's it! Your routes are now served as static HTML files.

Configuration
-------------

[](#configuration)

The configuration file is located at `config/static.php`. Here's a breakdown of all available options:

### Caching Driver

[](#caching-driver)

```
'driver' => 'crawler', // Options: 'crawler' or 'routes'
```

DriverDescription`crawler`Uses Spatie Crawler to automatically discover and cache all internal URLs starting from your homepage. Best for sites with many interconnected pages.`routes`Only caches routes that have the `StaticResponse` middleware explicitly applied. Best for selective caching.### Enable/Disable

[](#enabledisable)

```
'enabled' => env('STATIC_ENABLED', true),
```

Toggle static caching on or off. Useful for disabling in development while keeping it enabled in production.

### Build Settings

[](#build-settings)

```
'build' => [
    'clear_before_start' => true,    // Clear existing cache before rebuilding
    'concurrency' => 5,               // Number of concurrent HTTP requests
    'accept_no_follow' => true,       // Follow nofollow links when crawling
    'default_scheme' => 'https',      // URL scheme for crawler requests
    'crawl_observer' => \Backstage\LaravelStatic\Crawler\StaticCrawlObserver::class,
    'crawl_profile' => \Spatie\Crawler\CrawlProfiles\CrawlInternalUrls::class,
    'bypass_header' => [
        'name' => 'X-Laravel-Static',
        'value' => 'off',
    ],
],
```

### File Storage

[](#file-storage)

```
'files' => [
    'disk' => env('STATIC_DISK', 'public'),  // Laravel filesystem disk
    'include_domain' => true,                 // Create separate caches per domain
    'include_query_string' => true,           // Include query strings in cache keys
    'filepath_max_length' => 4096,            // Maximum file path length
    'filename_max_length' => 255,             // Maximum filename length
],
```

### Additional Options

[](#additional-options)

```
'options' => [
    'on_termination' => false,  // Save cache after response sent (async)
    'minify_html' => false,     // Minify HTML before caching
],
```

Commands
--------

[](#commands)

### Build Static Cache

[](#build-static-cache)

Generate static files for all configured routes:

```
php artisan static:build
```

When using the `routes` driver, only routes with the `StaticResponse` middleware are cached. When using the `crawler` driver, the crawler starts from your homepage and discovers all internal links.

### Clear Static Cache

[](#clear-static-cache)

Clear all cached static files:

```
php artisan static:clear
```

Clear specific URIs:

```
php artisan static:clear --uri=/about --uri=/contact
```

Clear by route names:

```
php artisan static:clear --routes=home --routes=about --routes=blog.index
```

Clear by domain (useful for multi-tenant applications):

```
php artisan static:clear --domain=example.com
php artisan static:clear --domain=subdomain.example.com
```

Advanced Usage
--------------

[](#advanced-usage)

### Multi-Domain Support

[](#multi-domain-support)

Laravel Static supports multi-domain setups out of the box. When `include_domain` is enabled (default), each domain gets its own cache directory:

```
storage/app/public/
├── example.com/
│   ├── GET/
│   │   ├── index.html
│   │   └── about.html
├── subdomain.example.com/
│   ├── GET/
│   │   └── index.html

```

### Query String Handling

[](#query-string-handling)

When `include_query_string` is enabled, different query strings create separate cache files:

```
/products?page=1  → products/page=1.html
/products?page=2  → products/page=2.html
/search?q=laravel → search/q=laravel.html

```

### HTML Minification

[](#html-minification)

Enable HTML minification to reduce file sizes:

```
// config/static.php
'options' => [
    'minify_html' => true,
],
```

This removes unnecessary whitespace, comments, and optimizes the HTML output using the [voku/html-min](https://github.com/voku/HtmlMin) library.

### Bypass Header

[](#bypass-header)

During development or testing, you may want to bypass the static cache. The package includes a bypass header mechanism:

```
curl -H "X-Laravel-Static: off" https://example.com/
```

This header tells the middleware to skip the static cache and generate a fresh response.

### Programmatic Cache Clearing

[](#programmatic-cache-clearing)

Use the `StaticCache` facade to clear cache programmatically:

```
use Backstage\LaravelStatic\Facades\StaticCache;

// Clear all cache
StaticCache::clear();

// Clear specific paths
StaticCache::clear(['/about', '/contact']);
```

### Custom Crawl Observer

[](#custom-crawl-observer)

Create a custom crawl observer to customize the crawling behavior:

```
namespace App\Crawlers;

use Backstage\LaravelStatic\Crawler\StaticCrawlObserver;
use Psr\Http\Message\UriInterface;
use Psr\Http\Message\ResponseInterface;

class CustomCrawlObserver extends StaticCrawlObserver
{
    public function crawled(UriInterface $url, ResponseInterface $response, ?UriInterface $foundOnUrl = null): void
    {
        // Add custom logic before caching
        logger()->info("Caching: {$url}");

        parent::crawled($url, $response, $foundOnUrl);
    }
}
```

Update your configuration:

```
'build' => [
    'crawl_observer' => \App\Crawlers\CustomCrawlObserver::class,
],
```

### Custom Crawl Profile

[](#custom-crawl-profile)

Control which URLs get crawled by creating a custom crawl profile:

```
namespace App\Crawlers;

use Psr\Http\Message\UriInterface;
use Spatie\Crawler\CrawlProfiles\CrawlProfile;

class CustomCrawlProfile extends CrawlProfile
{
    public function shouldCrawl(UriInterface $url): bool
    {
        $path = $url->getPath();

        // Skip admin routes
        if (str_starts_with($path, '/admin')) {
            return false;
        }

        // Skip API routes
        if (str_starts_with($path, '/api')) {
            return false;
        }

        return true;
    }
}
```

### Excluding Routes from Caching

[](#excluding-routes-from-caching)

Routes with parameters cannot be automatically cached (they require specific values). You can also explicitly exclude routes by not applying the middleware:

```
// These routes will be cached
Route::middleware([StaticResponse::class])->group(function () {
    Route::get('/', [HomeController::class, 'index']);
    Route::get('/about', [PageController::class, 'about']);
});

// These routes will NOT be cached (no middleware)
Route::get('/dashboard', [DashboardController::class, 'index']);
Route::get('/user/{id}', [UserController::class, 'show']); // Has parameters
```

### Async Cache Generation

[](#async-cache-generation)

Enable `on_termination` to generate cache files after the response is sent to the user:

```
'options' => [
    'on_termination' => true,
],
```

This improves perceived performance as users don't wait for the cache file to be written.

Web Server Configuration
------------------------

[](#web-server-configuration)

For optimal performance, configure your web server to serve static files directly without hitting PHP.

### Nginx

[](#nginx)

```
server {
    listen 80;
    server_name example.com;
    root /var/www/html/public;

    # Try static cache first, then Laravel
    location / {
        # Check for static cache file
        set $cache_path /storage/example.com/GET$uri;

        # Handle index files
        if (-f $document_root$cache_path/index.html) {
            rewrite ^ $cache_path/index.html last;
        }

        # Handle direct files
        if (-f $document_root$cache_path.html) {
            rewrite ^ $cache_path.html last;
        }

        # Fall back to Laravel
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
```

### Apache

[](#apache)

```

    RewriteEngine On

    # Check for static cache
    RewriteCond %{DOCUMENT_ROOT}/storage/%{HTTP_HOST}/GET%{REQUEST_URI}.html -f
    RewriteRule ^(.*)$ /storage/%{HTTP_HOST}/GET/$1.html [L]

    RewriteCond %{DOCUMENT_ROOT}/storage/%{HTTP_HOST}/GET%{REQUEST_URI}/index.html -f
    RewriteRule ^(.*)$ /storage/%{HTTP_HOST}/GET/$1/index.html [L]

    # Laravel fallback
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php [L]

```

Cache Invalidation Strategies
-----------------------------

[](#cache-invalidation-strategies)

### Event-Based Invalidation

[](#event-based-invalidation)

Clear cache when content changes using model events:

```
use Backstage\LaravelStatic\Facades\StaticCache;

class Post extends Model
{
    protected static function booted()
    {
        static::saved(function (Post $post) {
            StaticCache::clear([
                "/blog/{$post->slug}",
                '/blog',
            ]);
        });

        static::deleted(function (Post $post) {
            StaticCache::clear([
                "/blog/{$post->slug}",
                '/blog',
            ]);
        });
    }
}
```

### Scheduled Rebuilds

[](#scheduled-rebuilds)

Add a scheduled task to rebuild your cache periodically:

```
// app/Console/Kernel.php or bootstrap/app.php (Laravel 11+)
Schedule::command('static:build')->daily();
```

### Deploy Hook

[](#deploy-hook)

Clear and rebuild cache during deployments:

```
#!/bin/bash
# deploy.sh

php artisan static:clear
php artisan static:build
```

Comparison: Routes vs Crawler Driver
------------------------------------

[](#comparison-routes-vs-crawler-driver)

FeatureRoutes DriverCrawler DriverSetup complexityManual (add middleware to each route)Automatic (discovers all pages)ControlFine-grainedLess controlSpeedFaster (only caches specified routes)Slower (crawls entire site)DiscoveryManualAutomaticBest forSelective caching, large appsContent sites, blogsHow It Works
------------

[](#how-it-works)

1. **Request Interception**: The `StaticResponse` middleware intercepts outgoing responses
2. **Eligibility Check**: Only `GET`/`HEAD` requests with `200 OK` status are cached
3. **File Generation**: HTML content is saved to the configured storage disk
4. **Optional Minification**: If enabled, HTML is minified before saving
5. **Directory Structure**: Files are organized by domain, HTTP method, and URI path

The `PreventStaticResponseMiddleware` (automatically registered) handles bypass headers and ensures proper behavior during cache building.

Troubleshooting
---------------

[](#troubleshooting)

### Cache Not Being Generated

[](#cache-not-being-generated)

1. Ensure `STATIC_ENABLED=true` is set in your `.env`
2. Verify the `StaticResponse` middleware is applied to your routes
3. Check that the storage disk is writable
4. Routes with parameters cannot be cached automatically
5. Only `200 OK` responses are cached

### Cache Not Being Served

[](#cache-not-being-served)

1. Verify static files exist in your storage directory
2. Check web server configuration
3. Ensure the bypass header is not being sent accidentally

### Crawler Not Finding Pages

[](#crawler-not-finding-pages)

1. Check if pages are linked from the homepage
2. Verify `accept_no_follow` setting if using `rel="nofollow"` links
3. Review your crawl profile configuration
4. Note: JavaScript-rendered content is not supported

### File Path Too Long

[](#file-path-too-long)

If you encounter file path length errors:

1. Check the `filepath_max_length` and `filename_max_length` settings
2. Consider using shorter URLs or disabling query string caching
3. The package will skip files that exceed the configured limits

Testing
-------

[](#testing)

Run the test suite:

```
composer test
```

Run tests with coverage:

```
composer test-coverage
```

Run static analysis:

```
composer analyse
```

Format code:

```
composer format
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Mark van Eijk](https://github.com/backstagephp)
- [All Contributors](../../contributors)

Built with [Spatie Crawler](https://github.com/spatie/crawler) and [voku/HtmlMin](https://github.com/voku/HtmlMin).

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance64

Regular maintenance activity

Popularity16

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 84.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~97 days

Recently: every ~0 days

Total

10

Last Release

440d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/7c6a425dc8645907a118a007438172d58c2016773f54ab3a834beff172632f13?d=identicon)[ux](/maintainers/ux)

---

Top Contributors

[![markvaneijk](https://avatars.githubusercontent.com/u/1925388?v=4)](https://github.com/markvaneijk "markvaneijk (64 commits)")[![david-d-h](https://avatars.githubusercontent.com/u/75451291?v=4)](https://github.com/david-d-h "david-d-h (10 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")

---

Tags

backstagecachefilamentlaravelphpstaticlaravelvormkracht10laravel-static

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/vormkracht10-laravel-static/health.svg)

```
[![Health](https://phpackages.com/badges/vormkracht10-laravel-static/health.svg)](https://phpackages.com/packages/vormkracht10-laravel-static)
```

###  Alternatives

[spatie/laravel-responsecache

Speed up a Laravel application by caching the entire response

2.8k8.2M51](/packages/spatie-laravel-responsecache)[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

24149.7k](/packages/vormkracht10-laravel-mails)[ryangjchandler/blade-cache-directive

Cache chunks of your Blade markup with ease.

202200.8k2](/packages/ryangjchandler-blade-cache-directive)[spatie/laravel-site-search

A site search engine

300129.1k](/packages/spatie-laravel-site-search)[backstage/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

24157.5k5](/packages/backstage-laravel-mails)[innoge/laravel-policy-soft-cache

This package helps prevent performance problems with frequent Policy calls within your application lifecycle.

2356.9k](/packages/innoge-laravel-policy-soft-cache)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
