PHPackages                             laragear/poke - 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. [Security](/categories/security)
4. /
5. laragear/poke

ActiveLibrary[Security](/categories/security)

laragear/poke
=============

Keep your forms alive, avoid TokenMismatchException by gently poking your Laravel app

v5.1.0(3mo ago)2112.7k↓14.7%6MITPHPPHP ^8.3CI passing

Since Feb 16Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/Laragear/Poke)[ Packagist](https://packagist.org/packages/laragear/poke)[ Fund](https://github.com/sponsors/DarkGhostHunter)[ Fund](https://paypal.me/darkghosthunter)[ RSS](/packages/laragear-poke/feed)WikiDiscussions 5.x Synced 4d ago

READMEChangelog (10)Dependencies (16)Versions (21)Used By (0)

Poke
====

[](#poke)

[![Latest Version on Packagist](https://camo.githubusercontent.com/7187d38c4456041ef12b55b16715a27955c088e7b2ba9e13370098dd9821738d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c617261676561722f706f6b652e737667)](https://packagist.org/packages/laragear/poke)[![Latest stable test run](https://github.com/Laragear/Poke/workflows/Tests/badge.svg)](https://github.com/Laragear/Poke/actions)[![Codecov coverage](https://camo.githubusercontent.com/64d5da142c7249841e42f3e60172c93e14614ddab0cf87cc51a9fa3f78c896c1/68747470733a2f2f636f6465636f762e696f2f67682f4c617261676561722f506f6b652f67726170682f62616467652e7376673f746f6b656e3d30454c4a52355839304a)](https://codecov.io/gh/Laragear/Poke)[![Maintainability](https://camo.githubusercontent.com/cfec46c50e112ff5f86a034aaa351eadcbc7e3d75f0b9e6ae309838e25dd9ad3/68747470733a2f2f716c74792e73682f6261646765732f30303535653264322d373034342d346564362d393937632d6330636335666634393536372f6d61696e7461696e6162696c6974792e737667)](https://qlty.sh/gh/Laragear/projects/Poke)[![Sonarcloud Status](https://camo.githubusercontent.com/226649e7f48cd1f697478aa581246e51037701ac6394b30468880aecfb57fb77/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d4c617261676561725f506f6b65266d65747269633d616c6572745f737461747573)](https://sonarcloud.io/dashboard?id=Laragear_Poke)[![Laravel Octane Compatibility](https://camo.githubusercontent.com/70359a356da237cd29561bc5d0bb80baae775b5ff62f288ed324755382858342/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2532304f6374616e652d436f6d70617469626c652d737563636573733f7374796c653d666c6174266c6f676f3d6c61726176656c)](https://laravel.com/docs/13.x/octane#introduction)

Keep your forms alive, avoid `TokenMismatchException` by gently poking your Laravel app.

Become a sponsor
----------------

[](#become-a-sponsor)

[![](.github/assets/support.png)](https://github.com/sponsors/DarkGhostHunter)

Your support allows me to keep this package free, up-to-date and maintainable. Alternatively, you can **spread the word on social media!**

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

[](#requirements)

- PHP 8.3 or later
- Laravel 12 or later

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

[](#installation)

Require this package into your project using Composer:

```
composer require laragear/poke
```

How does it work?
-----------------

[](#how-does-it-work)

This package pokes your App with an HTTP `HEAD` request to the `/poke` route at given intervals. In return, while your application renews the session lifetime, it returns an `HTTP 204` status code, which is an OK Response without body.

This amounts to **barely 0.8 KB sent!**

### Automatic Reloading on CSRF token expiration

[](#automatic-reloading-on-csrf-token-expiration)

The Poke script will detect if the CSRF session token is expired based on the last successful poke, and forcefully reload the page if there is Internet connection.

This is done by detecting [when the browser or tab becomes active](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API), or [when the device user becomes online again](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine).

This is handy in situations when the user laptop is put to sleep, or the phone loses signal. Because the session may expire during these moments, the page is reloaded to get the new CSRF token when the browser wakes up or the phone becomes online.

Usage
-----

[](#usage)

There are three ways to turn on Poke in your app.

- `auto` (easy hands-off default)
- `middleware`
- `blade` (best performance)

You can change the default mode using your environment file:

```
POKE_MODE=auto
```

### `auto`

[](#auto)

Just install this package and *look at it go*. This will append a middleware in [the `web` group](https://laravel.com/docs/middleware#middleware-groups) that will look into all your Responses content where:

- the request accepts HTML, and
- an input with `csrf` token is present.

If there is any match, this will inject the Poke script in charge to keep the forms alive just before the `` tag.

This mode won't inject the script on error responses or redirections.

Note

It's recommended to use the other modes if your application has many routes or Responses with a lot of text.

### `middleware`

[](#middleware)

This mode does not push the middleware to the `web` group. Instead, it allows you to use the `poke` middleware only in the routes you decide.

```
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Auth\RegisterController;

Route::get('register', RegisterController::class)->middleware('poke');
```

This will inject the script into the route response if there is an input with a CSRF token. You can also apply this to a [route group](https://laravel.com/docs/routing#route-groups).

You may want to use the `force` option to forcefully inject the script at the end of the `` tag, regardless of the CSRF token input presence. This may be handy when you expect to dynamically load forms on a view after its loaded, or SPA.

```
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\StatusController;

Route::get('status', StatusController::class)->middleware('poke:force');
```

As with [`auto` mode](#auto), this mode won't inject the script on errors or redirections.

### `blade`

[](#blade)

The `blade` mode disables middleware injection, so you can use the `` component freely to inject the script anywhere in your view, preferably before the closing `` tag.

```

    Try to Login:

        @csrf

        Log me in!

```

This may be useful if you have large responses, like blog posts, articles or galleries, since the framework won't spend resources inspecting the response, but just rendering the component.

Tip

Don't worry if you have duplicate Poke components in your view. The script is rendered only once, and even if not, the script only runs once.

Livewire Trait
--------------

[](#livewire-trait)

Tip

To use the Livewire Trait, it's recommended to [use the Blade mode](#blade).

If you're using Livewire, you can use the `Laragear\Poke\Livewire\InteractsWithPoke` trait in your components to *dispatch* an even on your page. The only thing required is to [use the Blade](#blade) mode, or add [force](#blade) with the `force` attribute.

```

```

In your component, if the trait is used, the `poke:renew` will be dispatched to the frontend, renewing the poke when the component is rendered.

```
use Laragear\Poke\Livewire\InteractsWithPoke;
use Livewire\Component as LivewireComponent;

class MyCustomForm extends LivewireComponent
{
    use InteractsWithPoke;

    // ...
}
```

Filament PHP
------------

[](#filament-php)

Tip

To use the Poke script with Filament, it's recommended to [use the Blade mode](#blade).

If you're using Filament PHP, you don't need to worry. When you render a Resource with a form, or a page that implements the `HasForms` contract, the script will be automatically injected before the body end tag.

If you're using a custom Page, you will need to use the [Livewire Trait](#livewire-trait).

```
use Filament\Pages\Page;
use Laragear\Poke\Livewire\InteractsWithPoke;

class Onboarding extends Page
{
    use InteractsWithPoke;

    // ...
}
```

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

[](#configuration)

For fine-tuning, you can publish the `poke.php` config file.

```
php artisan vendor:publish --provider="Laragear\Poke\PokeServiceProvider" --tag="config"
```

Let's examine the configuration array:

```
return [
    'mode' => env('POKE_MODE', 'auto'),
    'times' => 4,
    'poking' => [
        'route' => 'poke',
        'name' => 'poke',
        'domain' => null,
        'middleware' => 'web',
    ]
];
```

### Times (Interval)

[](#times-interval)

How many times the poking will be done relative to the global session lifetime. The more times, the shorter the poking interval. The default `4` should be fine for any normal application.

For example, if our session lifetime is the default of 120 minutes:

- 3 times will poke the application each 40 minutes,
- 4 times will poke the application each 30 minutes,
- 5 times will poke the application each 24 minutes,
- 6 times will poke the application each 20 minutes, and so on...

In other words, `session lifetime / times = poking interval`.

- 🔺 Raise the intervals if you expect users idling in your site for several minutes, even hours.
- 🔻 Lower the intervals if you expect users with a lot of activity.

### Poking

[](#poking)

This is the array of settings for the poking route which receives the Poke script request.

```
return [
    'poking' => [
        'route' => 'poke',
        'name' => 'poke',
        'domain' => null,
        'middleware' => ['web'],
    ]
];
```

#### Route

[](#route)

The route (relative to the root URL of your application) that will be using to receive the pokes.

```
return [
    'poking' => [
        'route' => '/dont-sleep'
    ],
];
```

Note

The poke routes are registered at boot time.

#### Name

[](#name)

Name of the route, to find the poke route in your app for whatever reason.

```
return [
    'poking' => [
        'name' => 'my-custom-poking-route'
    ],
];
```

#### Domain

[](#domain)

The Poke route is available on all domains. Setting a given domain will scope the route to that domain.

In case you are using a domain or domain pattern, it may be convenient to put the Poke route under a certain one. A classic example is to make the poking available at `http://user.myapp.com/poke` but no `http://api.myapp.com/poke`.

```
return [
    'poking' => [
        'domain' => '{user}.myapp.com'
    ],
];
```

#### Middleware

[](#middleware-1)

The default Poke route uses [the `web` middleware group](https://laravel.com/docs/middleware#middleware-groups) to function properly, as this group handles session, cookies and CSRF tokens.

You can add your own middleware here if you need to.

```
return [
    'poking' => [
        'middleware' => ['web', 'validates-ip', 'my-custom-middleware']
    ],
];
```

You can also use the "bare minimum" middleware if you feel like it, thus it may be problematic if you don't know what you're doing.

```
return [
    'poking' => [
        'middleware' => [
            \Illuminate\Cookie\Middleware\EncryptCookies::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
        ],
    ]
]
```

Script View
-----------

[](#script-view)

Poke injects the script as a [Blade component](https://laravel.com/docs/blade#components) at all times.

You can override the script by publishing it under the `views` tag:

```
php artisan vendor:publish --provider="Laragear\Poke\PokeServiceProvider" --tag="views"
```

Some people may want to change the script to use a custom Javascript HTTP library, minify the response, make it compatible for older browsers, or even [create a custom Event](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) when CSRF token expires.

The view receives three variables:

- `$route`: The relative route where the poking will be done.
- `$interval`: The interval in milliseconds the poking should be done.
- `$lifetime`: The session lifetime in milliseconds.

Laravel Octane compatibility
----------------------------

[](#laravel-octane-compatibility)

- Only the `InjectsScript` middleware is bound as a singleton, and it saves the mode, which will persist across all the process lifetime. The mode is not intended to change request-by-request.

There should be no problems using this package with Laravel Octane.

Security
--------

[](#security)

If you discover any security-related issues, please [use the online form](https://github.com/Laragear/Poke/security).

License
=======

[](#license)

This specific package version is licensed under the terms of the [MIT License](LICENSE.md), at the time of publishing.

[Laravel](https://laravel.com) is a Trademark of [Taylor Otwell](https://github.com/TaylorOtwell/). Copyright © 2011–2026 Laravel LLC.

###  Health Score

54

—

FairBetter than 96% of packages

Maintenance78

Regular maintenance activity

Popularity36

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity74

Established project with proven stability

 Bus Factor1

Top contributor holds 87.5% 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 ~99 days

Recently: every ~88 days

Total

16

Last Release

114d ago

Major Versions

v1.0.4 → v2.0.02023-02-18

2.x-dev → v3.0.02024-03-06

v3.0.1 → 4.x-dev2025-03-27

v4.0.0 → v5.0.02026-03-08

PHP version history (5 changes)v1.0.0PHP &gt;=8.0.2

v2.0.0PHP ^8.1

v2.0.1PHP 8.\*

4.x-devPHP ^8.2

v5.0.0PHP ^8.3

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/5141911?v=4)[Italo](/maintainers/DarkGhostHunter)[@DarkGhostHunter](https://github.com/DarkGhostHunter)

---

Top Contributors

[![DarkGhostHunter](https://avatars.githubusercontent.com/u/5141911?v=4)](https://github.com/DarkGhostHunter "DarkGhostHunter (70 commits)")[![StyleCIBot](https://avatars.githubusercontent.com/u/11048387?v=4)](https://github.com/StyleCIBot "StyleCIBot (9 commits)")[![ndossche](https://avatars.githubusercontent.com/u/7771979?v=4)](https://github.com/ndossche "ndossche (1 commits)")

---

Tags

csrflaravelphpxsrflaravelcsrfFormsxsrfpoketoken-mismatch

### Embed Badge

![Health badge](/badges/laragear-poke/health.svg)

```
[![Health](https://phpackages.com/badges/laragear-poke/health.svg)](https://phpackages.com/packages/laragear-poke)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.6k30.0M148](/packages/laravel-cashier)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k15.1M132](/packages/laravel-pulse)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9762.4M131](/packages/roots-acorn)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

77022.3M151](/packages/laravel-mcp)[api-platform/laravel

API Platform support for Laravel

58171.8k14](/packages/api-platform-laravel)

PHPackages © 2026

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