> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Session

> How to persist data across requests using Laravel's HTTP session

## What is a session

HTTP is a stateless protocol. That is, HTTP itself has no mechanism for retaining user information across requests.
Laravel's session feature provides a way to persist user data across multiple requests.

Save data you want to persist across requests—login state, items in a cart, form input in progress—in the session.

## Session driver configuration

Session configuration lives in `config/session.php`.
You can switch drivers via the `SESSION_DRIVER` environment variable (in your `.env` file).

```ini theme={null}
SESSION_DRIVER=database
```

Laravel supports these drivers out of the box:

| Driver     | Overview                                                                  |
| ---------- | ------------------------------------------------------------------------- |
| `file`     | Stored as files in `storage/framework/sessions` (default in older setups) |
| `cookie`   | Stored as an encrypted cookie in the browser                              |
| `database` | Stored in a database table                                                |
| `redis`    | Stored in Redis (fast)                                                    |
| `array`    | Stored in a PHP array (for testing; not persisted across requests)        |

<Info>
  In Laravel's default project setup, the `database` driver is configured. Using the `database` driver requires a `sessions` table, but it's included in the default migrations, so it works out of the box.
</Info>

## Accessing the session

There are two ways to access the session: using methods on the `Request` instance, or using the global `session()` helper.

### Using the Request instance

Type-hint `Request` on your controller method, then access the session via `$request->session()`.

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\View\View;

class DashboardController extends Controller
{
    public function index(Request $request): View
    {
        $username = $request->session()->get('username');

        return view('dashboard', ['username' => $username]);
    }
}
```

### Using the global `session()` helper

The `session()` helper function can be called from anywhere—controllers, views, and so on.

```php theme={null}
// Get a value
$value = session('key');

// Get a value with a default
$value = session('key', 'default value');

// Store a value
session(['key' => 'value']);
```

<Tip>
  Both approaches can be verified via `assertSessionHas` in tests. Inside a controller, using `$request->session()` makes the dependency explicit and clearer.
</Tip>

## Manipulating the session

### Retrieving data

```php theme={null}
// Retrieve by key
$value = $request->session()->get('key');

// Specify a default value
$value = $request->session()->get('key', 'default');

// Specify a default via a closure
$value = $request->session()->get('key', function () {
    return 'default';
});

// Retrieve all session data
$data = $request->session()->all();
```

### Checking whether data exists

```php theme={null}
// True if the value exists and is not null
if ($request->session()->has('user_id')) {
    // ...
}

// True even if null, as long as the key exists
if ($request->session()->exists('user_id')) {
    // ...
}

// True if the key does not exist
if ($request->session()->missing('user_id')) {
    // ...
}
```

Note the difference between `has` and `exists`.

| Method   | If value is `null` |
| -------- | ------------------ |
| `has`    | Returns `false`    |
| `exists` | Returns `true`     |

### Storing data

```php theme={null}
// Via the Request instance
$request->session()->put('user_name', 'Tanaka');

// Via the global helper
session(['user_name' => 'Tanaka']);

// Push into an array
$request->session()->push('cart.items', ['id' => 1, 'name' => 'Product A']);
```

### Removing data

```php theme={null}
// Remove a specific key
$request->session()->forget('user_name');

// Remove multiple keys at once
$request->session()->forget(['user_name', 'cart']);

// Remove all session data
$request->session()->flush();
```

## Flash data

Flash data is session data that is only available **for the next request**.
Use it for information you want to display just once, like form submission success messages or error messages.

### Storing data with `flash()`

```php theme={null}
$request->session()->flash('status', 'Post saved.');
```

This data is available on the next request but is automatically deleted afterward.

### Extending flash data

```php theme={null}
// Extend all flash data by one more request
$request->session()->reflash();

// Extend only specific keys
$request->session()->keep(['status', 'message']);
```

### Displaying flash messages in Blade

```blade theme={null}
{{-- resources/views/layouts/app.blade.php --}}

@if (session('success'))
    <div class="alert alert-success">
        {{ session('success') }}
    </div>
@endif

@if (session('error'))
    <div class="alert alert-danger">
        {{ session('error') }}
    </div>
@endif
```

<Tip>
  Placing flash message display in a layout file (like `layouts/app.blade.php`) shows them consistently across every page.
</Tip>

## Practical example: showing a message after form submission

After submitting a form, saving a success message to the session, redirecting, and displaying it on the next page is a classic web-application pattern.

<Steps>
  <Step title="Define routes">
    ```php theme={null}
    use App\Http\Controllers\PostController;

    Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
    Route::get('/posts/create', [PostController::class, 'create'])->name('posts.create');
    Route::post('/posts', [PostController::class, 'store'])->name('posts.store');
    ```
  </Step>

  <Step title="Implement the controller">
    In the `store` method that receives form submissions, redirect with a success message after saving.

    ```php theme={null}
    <?php

    namespace App\Http\Controllers;

    use App\Models\Post;
    use Illuminate\Http\RedirectResponse;
    use Illuminate\Http\Request;
    use Illuminate\View\View;

    class PostController extends Controller
    {
        public function index(): View
        {
            $posts = Post::latest()->get();

            return view('posts.index', ['posts' => $posts]);
        }

        public function create(): View
        {
            return view('posts.create');
        }

        public function store(Request $request): RedirectResponse
        {
            $validated = $request->validate([
                'title' => 'required|string|max:255',
                'body'  => 'required|string',
            ]);

            Post::create($validated);

            return redirect()
                ->route('posts.index')
                ->with('success', 'Post created.');
        }
    }
    ```

    `redirect()->with('success', '...')` is a shortcut for passing flash data to the redirect target.
  </Step>

  <Step title="Display the message in the layout">
    Add flash message display to `resources/views/layouts/app.blade.php`.

    ```blade theme={null}
    <!DOCTYPE html>
    <html>
    <head>
        <title>My App</title>
    </head>
    <body>
        {{-- Flash messages --}}
        @if (session('success'))
            <div class="alert alert-success">
                {{ session('success') }}
            </div>
        @endif

        @if (session('error'))
            <div class="alert alert-danger">
                {{ session('error') }}
            </div>
        @endif

        @yield('content')
    </body>
    </html>
    ```
  </Step>

  <Step title="Create the index view">
    ```blade theme={null}
    {{-- resources/views/posts/index.blade.php --}}

    @extends('layouts.app')

    @section('content')
    <h1>Post list</h1>

    @foreach ($posts as $post)
        <div>
            <h2>{{ $post->title }}</h2>
            <p>{{ $post->body }}</p>
        </div>
    @endforeach
    @endsection
    ```

    After the post is saved and the user is redirected, the "Post created." message will appear once at the top of this index page.
  </Step>
</Steps>

### Pattern combined with validation errors

On validation failure, combine with `back()->withErrors()`.
Laravel automatically flashes validation errors, so you can use the `$errors` variable in Blade.

```php theme={null}
public function store(Request $request): RedirectResponse
{
    $validated = $request->validate([
        'title' => 'required|string|max:255',
        'body'  => 'required|string',
    ]);

    Post::create($validated);

    // On success: redirect with flash message
    return redirect()
        ->route('posts.index')
        ->with('success', 'Post created.');

    // On validation failure, Laravel automatically performs back()->withErrors()->withInput()
}
```

```blade theme={null}
{{-- Form page --}}

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

<form method="POST" action="{{ route('posts.store') }}">
    @csrf

    <div>
        <label for="title">Title</label>
        <input
            id="title"
            type="text"
            name="title"
            value="{{ old('title') }}"
        />
        @error('title')
            <span>{{ $message }}</span>
        @enderror
    </div>

    <div>
        <label for="body">Body</label>
        <textarea id="body" name="body">{{ old('body') }}</textarea>
        @error('body')
            <span>{{ $message }}</span>
        @enderror
    </div>

    <button type="submit">Submit</button>
</form>
```

<Warning>
  `flush()` deletes all data in the session. Login state and everything else is lost as well, so when you only want to remove specific user data, use `forget()` with the specific keys.
</Warning>

## Next steps

<Card title="Validation" icon="check-circle" href="/en/validation">
  Learn how to validate form input data.
</Card>


## Related topics

- [Resume session](/en/packages/laravel-copilot-sdk/resume.md)
- [Remote Sessions](/en/packages/laravel-copilot-sdk/remote-sessions.md)
- [Session hooks](/en/packages/laravel-copilot-sdk/hooks.md)
- [Cloud Sessions](/en/packages/laravel-copilot-sdk/cloud-sessions.md)
- [Session lifecycle events](/en/packages/laravel-copilot-sdk/session-lifecycle-event.md)
