# Search Results

## Migrations Indexes Foreign Key Constraints Toggling Foreign Key Constraints
Migrations | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/migrations.md

#### Toggling Foreign Key Constraints

You may enable or disable foreign key constraints within your migrations by using the following methods:

```php
Schema::enableForeignKeyConstraints();

Schema::disableForeignKeyConstraints();

Schema::withoutForeignKeyConstraints(function () {
    // Constraints disabled within this closure...
});
```

> [!WARNING]
> SQLite disables foreign key constraints by default. When using SQLite, make sure to [enable foreign key support](/docs/{{version}}/database#configuration) in your database configuration before attempting to create them in your migrations.

---

## Authorization Introduction
Authorization | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/authorization.md

## Introduction

In addition to providing built-in [authentication](/docs/{{version}}/authentication) services, Laravel also provides a simple way to authorize user actions against a given resource. For example, even though a user is authenticated, they may not be authorized to update or delete certain Eloquent models or database records managed by your application. Laravel's authorization features provide an easy, organized way of managing these types of authorization checks.

Laravel provides two primary ways of authorizing actions: [gates](#gates) and [policies](#creating-policies). Think of gates and policies like routes and controllers. Gates provide a simple, closure-based approach to authorization while policies, like controllers, group logic around a particular model or resource. In this documentation, we'll explore gates first and then examine policies.

You do not need to choose between exclusively using gates or exclusively using policies when building an application. Most applications will most likely contain some mixture of gates and policies, and that is perfectly fine! Gates are most applicable to actions that are not related to any model or resource, such as viewing an administrator dashboard. In contrast, policies should be used when you wish to authorize an action for a particular model or resource.

---

## Redirecting Redirecting to full-page components
Redirecting | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/redirecting

## Redirecting to full-page components

Because Livewire uses Laravel's built-in redirection feature, you can use all of the redirection methods available to you in a typical Laravel application.

For example, if you are using a Livewire component as a full-page component for a route like so:

```php
Route::livewire('/posts', 'pages::show-posts');
```

You can redirect to it simply by using the route path:

```php
public function save()
{
    // ...

    $this->redirect('/posts');
}
```

---

## Pest V4 Is Here Now With Browser Testing
Pest V4 Is Here Now With Browser Testing | pestphp/pest@4.x | Source: https://github.com/pestphp/docs/blob/4.x/pest-v4-is-here-now-with-browser-testing.md

---
title: Pest v4 Is Here — Now with Browser Testing
description: Today, we're thrilled to announce Pest v4 — our biggest release yet, featuring powerful new browser testing with parallel support and full Laravel integration.
---

> To get started with Pest v4's new features including browser testing, please refer to the upgrade guide: [Upgrade Guide →](/docs/upgrade-guide).

- [Browser Testing](#content-pest-v4-is-here-now-with-browser-testing)
- [Smoke Testing](#content-smoke-testing)
- [Visual Regression Testing](#content-visual-regression-testing)
- [Test Sharding](#content-test-sharding)
- [Type Coverage Is Much Faster](#content-type-coverage-is-much-faster)
- [Profanity Checking](#content-profanity-checking)
- [On Top of PHPUnit 12](#content-on-top-of-phpunit-12)

# Pest v4 Is Here — Now with Browser Testing

Today, we're thrilled to announce the release of **Pest v4**, bringing the biggest testing upgrade yet: powerful **[Browser Testing](/docs/browser-testing)**. Pest's new browser testing features let you run elegant, maintainable browser tests — with first-class support for Laravel's testing API and the ability to run tests in parallel. For the first time, this is browser testing that feels as good as writing unit tests.

Here is the creator of Pest, [Nuno Maduro](https://twitter.com/enunomaduro), demoing the new browser testing features in Pest v4 at Laracon US:

[![Pest v4](/assets/pest4_play.png)](https://youtu.be/f5gAgwwwwOI?si=LtPpySZe3tf8qMjz&t=52)

Here is an example of Browser Testing using [Laravel](https://laravel.com):

```php
it('may reset the password', function () {
    // access any laravel testing helpers...
    Notification::fake();

    // access to the database — using the RefreshDatabase trait (even sqlite in memory...)
    $this->actingAs(User::factory()->create());

    $page = visit('/sign-in') // visit on a real browser...
        ->on()->mobile() // or ->desktop(), ->tablet(), etc...
        ->inDarkMode(); // or ->inLightMode()

    $page->assertSee('Sign In')
         ->click('Forgot Password?')
         ->type('email', 'nuno@laravel.com')
         ->press('Send Reset Link')
         ->assertSee('We have emailed your password reset link!')
         ->assertNoJavascriptErrors(); // or ->assertNoConsoleLogs()

    Notification::assertSent(ResetPassword::class);
});
```

With Pest v4's browser testing, you can:
- Seamlessly use **Laravel features** like `Event::fake()`, `assertAuthenticated()`, and model factories
- Use `RefreshDatabase`, even with SQLite in-memory databases, to ensure a clean state for each test
- Test on **multiple browsers** (Chrome, Firefox, Safari)
- Test on **different devices** and viewports (like iPhone 14 Pro, tablets, or custom breakpoints)
- Switch **color schemes** (light/dark mode)
- Interact with the page (click, type, scroll, select, submit, drag-and-drop, touch gestures, etc.)
- Run **parallel browser tests** for dramatically faster suites
- Take **screenshots** or pause tests for debugging
- …all with the elegance of Pest syntax
- **Playwright-based** — modern, fast, and reliable

To get started with browser testing in Pest, you need to install the Pest Browser Plugin:

```bash
composer require pestphp/pest-plugin-browser --dev

npm install playwright@latest
npx playwright install
```

After, you may use the `visit()` function anywhere. Finally, running this test is as simple as executing `./vendor/bin/pest` in your terminal. Pest will handle the rest, launching a browser, navigating to the page, and performing the actions you specified.

## Smoke Testing

Smoke testing your application in real browsers has never been easier. With Pest v4, you can literally visit all your application pages, and ensure they don't throw any JavaScript errors, and they don't log any console errors.

```php
$routes = ['/', '/about', '/contact'];

visit($routes)->assertNoSmoke();

// assertNoSmoke() is a shorthand for:
// - assertNoJavascriptErrors()
// - assertNoConsoleLogs()
```

## Visual Regression Testing

Want to ensure your pages look exactly as expected over time? Pest v4 introduces visual regression testing with the `assertScreenshotMatches()` assertion. This allows you to take screenshots of your pages and compare them against baseline images, ensuring that your UI remains consistent across changes.

```php
$pages = visit(['/', '/about', '/contact']);

$pages->assertScreenshotMatches();
```

This is just a glimpse of what Browser Testing in Pest v4 can do. Find out more about the new features below, and check out the [Browser Testing documentation](/docs/browser-testing) for a complete guide on how to get started.

## Test Sharding

Pest v4 introduces **Test Sharding**, allowing you to split your test suite into smaller, manageable chunks. This is particularly useful for large applications (or when running browser tests) where running all tests at once can be time-consuming.

This feature is particularly useful on CI platforms, where on things like GitHub actions you can no longer scale vertical, but rather horizontally. This means you can run your tests in parallel across multiple machines, significantly speeding up your test suite execution.

To get started with Test Sharding, you can use the `--shard` option when running Pest:

```bash
# GitHub Workflow One
./vendor/bin/pest --shard=1/4

# GitHub Workflow Two
./vendor/bin/pest --shard=2/4

# GitHub Workflow Three
./vendor/bin/pest --shard=3/4

# GitHub Workflow Four
./vendor/bin/pest --shard=4/4
```

You may combine this with the `--parallel` option to run your tests in parallel, and this way trully maximize your test suite execution speed:

```bash
./vendor/bin/pest --shard=1/4 --parallel
```

Finally, to easily set up sharding your CI configuration, you just have to ensure each job in your CI configuration runs a different shard of your test suite. For example, in GitHub Actions, you can use the `matrix` strategy to define multiple jobs that run different shards:

```yaml
strategy:
  matrix:
    shard: [1, 2, 3, 4]

name: Tests (Shard ${{ matrix.shard }}/4)

steps:
  - name: Run tests
    run: pest --parallel --shard ${{ matrix.shard }}/4
```

## Type Coverage Is Much Faster

Remember the days when you had to wait for your type coverage to run? Not anymore! Pest v4 introduces a new type coverage engine that is significantly faster than previous versions.

Type coverage is 2x faster on the first run and instant on subsequent runs. This means you can quickly check your type coverage without waiting for long periods, making your development workflow much more efficient.

In addition, Type Coverage now supports **Sharding**. This means you can run type coverage with the `--shard` option, just like you do with your tests.

## Profanity Checking

Pest v4 introduces a new feature that allows you to check for profanity in your test code. This is particularly useful for maintaining a clean and professional codebase, especially in collaborative environments.

You can enable profanity checking by adding the `--profanity` option when running Pest:

```bash
./vendor/bin/pest --profanity
```

To start using Pest's Profanity plugin, you need to require the plugin via Composer.

```bash
composer require pestphp/pest-plugin-profanity --dev
```

After requiring the plugin, you may utilize the `--profanity` option to generate a report of your profanity.

```bash
./vendor/bin/pest --profanity
```

If any of your files contain profanity, they will be highlighted in red and displayed using their respective line
numbers and the profane word(s) that have been found.

As an example, `pr31(f*ck)` means that the word "fuck" was found on line 31.

To learn more about the Profanity plugin and how to configure it, check out the [Profanity documentation](/docs/profanity).

### Skip Locally or On CI

Pest v4 introduces the ability to conditionally skip tests based on the environment. You can use `skipLocally()` to skip tests when running locally, or `skipOnCi` to skip tests when running on a CI server.

```php
it('does not run locally', function () {
    // This test will be skipped when running locally
})->skipLocally();

it('does not run on CI', function () {
    // This test will be skipped when running on a CI server
})->skipOnCi();
```

### Miscellaneous Improvements

- You may now use `skipLocally()` or `skipOnCi` to conditionally skip tests based on the environment.
- The `not->toHaveSuspiciousCharacters()` arch expectation has been added to help you identify potential suspicious characters in your code. This arch expectation is now enabled by default on the `php` arch preset. This expectation requires the `intl` PHP extension.
- The expectation `toBeSlug` has been added to help you validate that a string is a valid slug.

### On Top of PHPUnit 12

Pest v4 is built on top of PHPUnit 12, which means you get all the latest features and improvements from PHPUnit. As such, be sure to check out the [PHPUnit 12 release announcement](https://phpunit.de/announcements/phpunit-12.html).

### Thanks To You, Pest v4 Is Here!

There's never been a better time to dive into testing and start using Pest. If you're ready to get started with Pest v4 right away, check out our [installation guide](/docs/installation) for step-by-step instructions. And if you're currently using an earlier version of Pest, we've got you covered with detailed upgrade instructions in our [upgrade guide](/docs/upgrade-guide).

Thank you for your continued support and feedback. We can't wait to see what you build with Pest v4!

---

Thank you for reading about Pest v4's new features! Want to get started with Pest? You can find the installation guide in the next section of the documentation: [Installation →](/docs/installation)

---

## Passport SPA Authentication
Passport | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/passport.md

## SPA Authentication

When building an API, it can be extremely useful to be able to consume your own API from your JavaScript application. This approach to API development allows your own application to consume the same API that you are sharing with the world. The same API may be consumed by your web application, mobile applications, third-party applications, and any SDKs that you may publish on various package managers.

Typically, if you want to consume your API from your JavaScript application, you would need to manually send an access token to the application and pass it with each request to your application. However, Passport includes a middleware that can handle this for you. All you need to do is append the `CreateFreshApiToken` middleware to the `web` middleware group in your application's `bootstrap/app.php` file:

```php
use Laravel\Passport\Http\Middleware\CreateFreshApiToken;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->web(append: [
        CreateFreshApiToken::class,
    ]);
})
```

> [!WARNING]
> You should ensure that the `CreateFreshApiToken` middleware is the last middleware listed in your middleware stack.

This middleware will attach a `laravel_token` cookie to your outgoing responses. This cookie contains an encrypted JWT that Passport will use to authenticate API requests from your JavaScript application. The JWT has a lifetime equal to your `session.lifetime` configuration value. Now, since the browser will automatically send the cookie with all subsequent requests, you may make requests to your application's API without explicitly passing an access token:

```js
axios.get('/api/user')
    .then(response => {
        console.log(response.data);
    });
```

---

## Wire Transition Customizing animations with CSS
Wire Transition | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/wire-transition

## Customizing animations with CSS

View Transitions are controlled entirely through CSS. You can customize the animation by targeting the view-transition pseudo-elements:

```css
/* Customize the transition for a specific element */
::view-transition-old(sidebar) {
    animation: 300ms ease-out both slide-out;
}

::view-transition-new(sidebar) {
    animation: 300ms ease-in both slide-in;
}

@keyframes slide-out {
    to { transform: translateX(-100%); }
}

@keyframes slide-in {
    from { transform: translateX(100%); }
}
```

The View Transitions API provides three pseudo-elements you can style:
- `::view-transition-old(name)` — The outgoing element's snapshot
- `::view-transition-new(name)` — The incoming element's snapshot
- `::view-transition-group(name)` — Container for both snapshots

---

## Middleware Registering Middleware Middleware Groups
Middleware | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/middleware.md

### Middleware Groups

Sometimes you may want to group several middleware under a single key to make them easier to assign to routes. You may accomplish this using the `appendToGroup` method within your application's `bootstrap/app.php` file:

```php
use App\Http\Middleware\First;
use App\Http\Middleware\Second;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->appendToGroup('group-name', [
        First::class,
        Second::class,
    ]);

    $middleware->prependToGroup('group-name', [
        First::class,
        Second::class,
    ]);
})
```

Middleware groups may be assigned to routes and controller actions using the same syntax as individual middleware:

```php
Route::get('/', function () {
    // ...
})->middleware('group-name');

Route::middleware(['group-name'])->group(function () {
    // ...
});
```

---

## Attribute Title Only for full-page components
Attribute Title | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/attribute-title

## Only for full-page components

> [!info] Full-page components only
> The `#[Title]` attribute only works for full-page components accessed via routes. Regular components rendered within other views don't use titles—they inherit the parent page's title.

---

## Database Testing Model Factories
Database Testing | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/database-testing.md

## Model Factories

When testing, you may need to insert a few records into your database before executing your test. Instead of manually specifying the value of each column when you create this test data, Laravel allows you to define a set of default attributes for each of your [Eloquent models](/docs/{{version}}/eloquent) using [model factories](/docs/{{version}}/eloquent-factories).

To learn more about creating and utilizing model factories to create models, please consult the complete [model factory documentation](/docs/{{version}}/eloquent-factories). Once you have defined a model factory, you may utilize the factory within your test to create models:

```php tab=Pest
use App\Models\User;

test('models can be instantiated', function () {
    $user = User::factory()->create();

    // ...
});
```

```php tab=PHPUnit
use App\Models\User;

public function test_models_can_be_instantiated(): void
{
    $user = User::factory()->create();

    // ...
}
```

---

## Lazy Full-page lazy loading
Lazy | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/lazy

## Full-page lazy loading

You can lazy load or defer full-page Livewire components using route methods.

### Lazy loading full pages

Use `->lazy()` to load the component when it enters the viewport:

```php
Route::livewire('/dashboard', 'pages::dashboard')->lazy();
```

### Deferring full pages

Use `->defer()` to load the component immediately after the page loads:

```php
Route::livewire('/dashboard', 'pages::dashboard')->defer();
```

### Disabling lazy/defer loading

If a component is lazy or deferred by default (via the `#[Lazy]` or `#[Defer]` attribute), you can opt-out using `enabled: false`:

```php
Route::livewire('/dashboard', 'pages::dashboard')->lazy(enabled: false);
Route::livewire('/dashboard', 'pages::dashboard')->defer(enabled: false);
```

---

## Database Testing Introduction
Database Testing | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/database-testing.md

## Introduction

Laravel provides a variety of helpful tools and assertions to make it easier to test your database driven applications. In addition, Laravel model factories and seeders make it painless to create test database records using your application's Eloquent models and relationships. We'll discuss all of these powerful features in the following documentation.

---

## Authorization
Authorization | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/authorization.md

# Authorization

- [Introduction](#introduction)
- [Gates](#gates)
    - [Writing Gates](#writing-gates)
    - [Authorizing Actions](#authorizing-actions-via-gates)
    - [Gate Responses](#gate-responses)
    - [Intercepting Gate Checks](#intercepting-gate-checks)
    - [Inline Authorization](#inline-authorization)
- [Creating Policies](#creating-policies)
    - [Generating Policies](#generating-policies)
    - [Registering Policies](#registering-policies)
- [Writing Policies](#writing-policies)
    - [Policy Methods](#policy-methods)
    - [Policy Responses](#policy-responses)
    - [Methods Without Models](#methods-without-models)
    - [Guest Users](#guest-users)
    - [Policy Filters](#policy-filters)
- [Authorizing Actions Using Policies](#authorizing-actions-using-policies)
    - [Via the User Model](#via-the-user-model)
    - [Via the Gate Facade](#via-the-gate-facade)
    - [Via Middleware](#via-middleware)
    - [Via Blade Templates](#via-blade-templates)
    - [Supplying Additional Context](#supplying-additional-context)
- [Authorization & Inertia](#authorization-and-inertia)

---

## Authorization Authorizing Actions Using Policies Via the User Model
Authorization | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/authorization.md

### Via the User Model

The `App\Models\User` model that is included with your Laravel application includes two helpful methods for authorizing actions: `can` and `cannot`. The `can` and `cannot` methods receive the name of the action you wish to authorize and the relevant model. For example, let's determine if a user is authorized to update a given `App\Models\Post` model. Typically, this will be done within a controller method:

```php
<?php

namespace App\Http\Controllers;

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

class PostController extends Controller
{
    /**
     * Update the given post.
     */
    public function update(Request $request, Post $post): RedirectResponse
    {
        if ($request->user()->cannot('update', $post)) {
            abort(403);
        }

        // Update the post...

        return redirect('/posts');
    }
}
```

If a [policy is registered](#registering-policies) for the given model, the `can` method will automatically call the appropriate policy and return the boolean result. If no policy is registered for the model, the `can` method will attempt to call the closure-based Gate matching the given action name.

---

## Middleware Registering Middleware Middleware Groups Laravel's Default Middleware Groups
Middleware | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/middleware.md

#### Laravel's Default Middleware Groups

Laravel includes predefined `web` and `api` middleware groups that contain common middleware you may want to apply to your web and API routes. Remember, Laravel automatically applies these middleware groups to the corresponding `routes/web.php` and `routes/api.php` files:

| The `web` Middleware Group                                |
| --------------------------------------------------------- |
| `Illuminate\Cookie\Middleware\EncryptCookies`             |
| `Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse` |
| `Illuminate\Session\Middleware\StartSession`              |
| `Illuminate\View\Middleware\ShareErrorsFromSession`       |
| `Illuminate\Foundation\Http\Middleware\ValidateCsrfToken` |
| `Illuminate\Routing\Middleware\SubstituteBindings`        |

| The `api` Middleware Group                         |
| -------------------------------------------------- |
| `Illuminate\Routing\Middleware\SubstituteBindings` |

If you would like to append or prepend middleware to these groups, you may use the `web` and `api` methods within your application's `bootstrap/app.php` file. The `web` and `api` methods are convenient alternatives to the `appendToGroup` method:

```php
use App\Http\Middleware\EnsureTokenIsValid;
use App\Http\Middleware\EnsureUserIsSubscribed;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->web(append: [
        EnsureUserIsSubscribed::class,
    ]);

    $middleware->api(prepend: [
        EnsureTokenIsValid::class,
    ]);
})
```

You may even replace one of Laravel's default middleware group entries with a custom middleware of your own:

```php
use App\Http\Middleware\StartCustomSession;
use Illuminate\Session\Middleware\StartSession;

$middleware->web(replace: [
    StartSession::class => StartCustomSession::class,
]);
```

Or, you may remove a middleware entirely:

```php
$middleware->web(remove: [
    StartSession::class,
]);
```

---

## Authorization Authorizing Actions Using Policies Via the `Gate` Facade Actions That Don't Require Models
Authorization | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/authorization.md

#### Actions That Don't Require Models

As previously discussed, some policy methods like `create` do not require a model instance. In these situations, you should pass a class name to the `authorize` method. The class name will be used to determine which policy to use when authorizing the action:

```php
use App\Models\Post;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;

/**
 * Create a new blog post.
 *
 * @throws \Illuminate\Auth\Access\AuthorizationException
 */
public function create(Request $request): RedirectResponse
{
    Gate::authorize('create', Post::class);

    // The current user can create blog posts...

    return redirect('/posts');
}
```

---

## Verification Introduction Database Preparation
Verification | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/verification.md

### Database Preparation

Next, your `users` table must contain an `email_verified_at` column to store the date and time that the user's email address was verified. Typically, this is included in Laravel's default `0001_01_01_000000_create_users_table.php` database migration.

---

## Wire Model Customizing update timing
Wire Model | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/wire-model

## Customizing update timing

By default, Livewire will only send a network request when an action is performed (like `wire:click` or `wire:submit`), NOT when a `wire:model` input is updated.

This drastically improves the performance of Livewire by reducing network requests and provides a smoother experience for your users.

However, there are occasions where you may want to update the server more frequently for things like real-time validation.

### Live updating

To send property updates to the server as a user types into an input-field, you can append the `.live` modifier to `wire:model`:

```html
<input type="text" wire:model.live="title">
```

#### Customizing the debounce

By default, when using `wire:model.live`, Livewire adds a 150 millisecond debounce to server updates. This means if a user is continually typing, Livewire will wait until the user stops typing for 150 milliseconds before sending a request.

You can customize this timing by appending `.debounce.Xms` after `.live`. Here is an example of changing the debounce to 250 milliseconds:

```html
<input type="text" wire:model.live.debounce.250ms="title">
```

### Updating on "blur" event

The `.blur` modifier delays syncing until the user clicks away from the input:

```html
<input type="text" wire:model.blur="title">
```

To also send a network request on blur, add `.live`:

```html
<input type="text" wire:model.blur.live="title">
```

### Updating on "change" event

The `.change` modifier triggers on the change event, which is useful for select elements:

```html
<select wire:model.change="state">...</select>

<!-- With network request -->
<select wire:model.change.live="state">...</select>
```

### Updating on "enter" key

The `.enter` modifier syncs when the user presses the Enter key:

```html
<input type="text" wire:model.enter="search">

<!-- With network request -->
<input type="text" wire:model.enter.live="search">
```

---

## Passport Password Grant Customizing the User Provider
Passport | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/passport.md

### Customizing the User Provider

If your application uses more than one [authentication user provider](/docs/{{version}}/authentication#introduction), you may specify which user provider the password grant client uses by providing a `--provider` option when creating the client via the `artisan passport:client --password` command. The given provider name should match a valid provider defined in your application's `config/auth.php` configuration file. You can then [protect your route using middleware](#multiple-authentication-guards) to ensure that only users from the guard's specified provider are authorized.

---

## Middleware Registering Middleware Middleware Groups Manually Managing Laravel's Default Middleware Groups
Middleware | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/middleware.md

#### Manually Managing Laravel's Default Middleware Groups

If you would like to manually manage all of the middleware within Laravel's default `web` and `api` middleware groups, you may redefine the groups entirely. The example below will define the `web` and `api` middleware groups with their default middleware, allowing you to customize them as necessary:

```php
->withMiddleware(function (Middleware $middleware): void {
    $middleware->group('web', [
        \Illuminate\Cookie\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
    ]);

    $middleware->group('api', [
        // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        // 'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ]);
})
```

> [!NOTE]
> By default, the `web` and `api` middleware groups are automatically applied to your application's corresponding `routes/web.php` and `routes/api.php` files by the `bootstrap/app.php` file.

---

## Upgrade Upgrading To 12.0 From 11.x Database Database Constructor Signature Changes
Upgrade | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/upgrade.md

#### Database Constructor Signature Changes

**Likelihood Of Impact: Very Low**

In Laravel 12, several low-level database classes now require an `Illuminate\Database\Connection` instance to be provided via their constructors.

**These changes are primarily applicable to database package maintainers - it is extremely unlikely any of these changes affect normal application development.**

`Illuminate\Database\Schema\Blueprint`

The constructor of the `Illuminate\Database\Schema\Blueprint` class now expects a `Connection` instance as its first argument. This primarily affects applications or packages that manually instantiate `Blueprint` instances.

`Illuminate\Database\Grammar`

The constructor of the `Illuminate\Database\Grammar` class also now requires a `Connection` instance. In previous versions, the connection was assigned after construction using the `setConnection()` method. This method has been removed in Laravel 12:

```php
// Laravel <= 11.x
$grammar = new MySqlGrammar;
$grammar->setConnection($connection);

// Laravel >= 12.x
$grammar = new MySqlGrammar($connection);
````

In addition, the following APIs have been removed or deprecated:

- The `Blueprint::getPrefix()` method is deprecated.
- The `Connection::withTablePrefix()` method has been removed.
- The `Grammar::getTablePrefix()` and `setTablePrefix()` methods are deprecated.
- The `Grammar::setConnection()` method has been removed.

When working with table prefixes, you should now retrieve them directly from the database connection:

```php
$prefix = $connection->getTablePrefix();
```

If you maintain custom database drivers, schema builders, or grammar implementations, you should review their constructors and ensure a `Connection` instance is provided.

---

## Components Button > Full width
Components Button | livewire/flux@2.x | Source: https://fluxui.dev/components/button#livewire/flux

Full width

A button that spans the full width of the container.

<flux:button variant="primary" class="w-full">Send invite</flux:button>

---

## Wire Loading Customizing CSS display property
Wire Loading | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/wire-loading

## Customizing CSS display property

When `wire:loading` is added to an element, Livewire updates the CSS `display` property of the element to show and hide the element. By default, Livewire uses `none` to hide and `inline-block` to show.

If you are toggling an element that uses a display value other than `inline-block`, like `flex` in the following example, you can append `.flex` to `wire:loading`:

```blade
<div class="flex" wire:loading.flex>...</div>
```

Below is the complete list of available display values:

```blade
<div wire:loading.inline-flex>...</div>
<div wire:loading.inline>...</div>
<div wire:loading.block>...</div>
<div wire:loading.table>...</div>
<div wire:loading.flex>...</div>
<div wire:loading.grid>...</div>
```

---

## Upgrade Upgrading To 12.0 From 11.x Database Multi-Schema Database Inspecting
Upgrade | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/upgrade.md

#### Multi-Schema Database Inspecting

**Likelihood Of Impact: Low**

The `Schema::getTables()`, `Schema::getViews()`, and `Schema::getTypes()` methods now include the results from all schemas by default. You may pass the `schema` argument to retrieve the result for the given schema only:

```php
// All tables on all schemas...
$tables = Schema::getTables();

// All tables on the 'main' schema...
$tables = Schema::getTables(schema: 'main');

// All tables on the 'main' and 'blog' schemas...
$tables = Schema::getTables(schema: ['main', 'blog']);
```

The `Schema::getTableListing()` method now returns schema-qualified table names by default. You may pass the `schemaQualified` argument to change the behavior as desired:

```php
$tables = Schema::getTableListing();
// ['main.migrations', 'main.users', 'blog.posts']

$tables = Schema::getTableListing(schema: 'main');
// ['main.migrations', 'main.users']

$tables = Schema::getTableListing(schema: 'main', schemaQualified: false);
// ['migrations', 'users']
```

The `db:table` and `db:show` commands now output the results of all schemas on MySQL, MariaDB, and SQLite, just like PostgreSQL and SQL Server.

---

## Search Full-Text Search Running Full-Text Queries
Search | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/search.md

### Running Full-Text Queries

Once the index is in place, use the `whereFullText` query builder method to search against it. Laravel will generate the appropriate SQL for your database driver — for example, `MATCH(...) AGAINST(...)` on MariaDB and MySQL, and `to_tsvector(...) @@ plainto_tsquery(...)` on PostgreSQL:

```php
$articles = Article::whereFullText('body', 'web developer')->get();
```

When using MariaDB and MySQL, results are automatically ordered by relevance score. On PostgreSQL, `whereFullText` filters matching records but does not order them by relevance — if you need automatic relevance ordering on PostgreSQL, consider using [Scout's database engine](#database-engine), which handles this for you.

If you created a composite full-text index across multiple columns, you may search against all of them by passing the same array of columns to `whereFullText`:

```php
$articles = Article::whereFullText(
    ['title', 'body'], 'web developer'
)->get();
```

The `orWhereFullText` method may be used to add a full-text search clause as an "or" condition. For complete details, consult the [query builder documentation](/docs/{{version}}/queries#full-text-where-clauses).

---

## Upgrading New features in v4
Upgrading | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/upgrading

## New features in v4

Livewire v4 introduces several powerful new features you can start using immediately:

### Component features

**Single-file and multi-file components**

v4 introduces new component formats alongside the traditional class-based approach. Single-file components combine PHP and Blade in one file, while multi-file components organize PHP, Blade, JavaScript, and tests in a directory.

By default, view-based component files are prefixed with a ⚡ emoji to distinguish them from regular Blade files in your editor and searches. This can be disabled via the `make_command.emoji` config.

```bash
php artisan make:livewire create-post        # Single-file (default)
php artisan make:livewire create-post --mfc  # Multi-file
php artisan livewire:convert create-post     # Convert between formats
```

[Learn more about component formats →](/docs/4.x/components)

**Slots and attribute forwarding**

Components now support slots and automatic attribute bag forwarding using `{{ $attributes }}`, making component composition more flexible.

[Learn more about nesting components →](/docs/4.x/nesting)

**JavaScript in view-based components**

View-based components can now include `<script>` tags without the `@script` wrapper. These scripts are served as separate cached files for better performance and automatic `$wire` binding:

```blade
<div>
    <!-- Your component template -->
</div>

<script>
    // $wire is automatically bound as 'this'
    this.count++  // Same as $wire.count++

    // $wire is still available if preferred
    $wire.save()
</script>
```

[Learn more about JavaScript in components →](/docs/4.x/javascript)

### Islands

Islands allow you to create isolated regions within a component that update independently, dramatically improving performance without creating separate child components.

```blade
@island(name: 'stats', lazy: true)
    <div>{{ $this->expensiveStats }}</div>
@endisland
```

[Learn more about islands →](/docs/4.x/islands)

### Loading improvements

**Deferred loading**

In addition to lazy loading (viewport-based), components can now be deferred to load immediately after the initial page load:

```blade
<livewire:revenue defer />
```

```php
#[Defer]
class Revenue extends Component { ... }
```

**Bundled loading**

Control whether multiple lazy/deferred components load in parallel or bundled together:

```blade
<livewire:revenue lazy.bundle />
<livewire:expenses defer.bundle />
```

```php
#[Lazy(bundle: true)]
class Revenue extends Component { ... }
```

[Learn more about lazy and deferred loading →](/docs/4.x/lazy)

### Async actions

Run actions in parallel without blocking other requests using the `.async` modifier or `#[Async]` attribute:

```blade
<button wire:click.async="logActivity">Track</button>
```

```php
#[Async]
public function logActivity() { ... }
```

[Learn more about async actions →](/docs/4.x/actions#parallel-execution-with-async)

### New directives and modifiers

**`wire:sort` - Drag-and-drop sorting**

Built-in support for sortable lists with drag-and-drop:

```blade
<ul wire:sort="updateOrder">
    @foreach ($items as $item)
        <li wire:sort:item="{{ $item->id }}" wire:key="{{ $item->id }}">{{ $item->name }}</li>
    @endforeach
</ul>
```

[Learn more about wire:sort →](/docs/4.x/wire-sort)

**`wire:intersect` - Viewport intersection**

Run actions when elements enter or leave the viewport, similar to Alpine's [`x-intersect`](https://alpinejs.dev/plugins/intersect):

```blade
<!-- Basic usage -->
<div wire:intersect="loadMore">...</div>

<!-- With modifiers -->
<div wire:intersect.once="trackView">...</div>
<div wire:intersect:leave="pauseVideo">...</div>
<div wire:intersect.half="loadMore">...</div>
<div wire:intersect.full="startAnimation">...</div>

<!-- With options -->
<div wire:intersect.margin.200px="loadMore">...</div>
<div wire:intersect.threshold.50="trackScroll">...</div>
```

Available modifiers:
- `.once` - Fire only once
- `.half` - Wait until half is visible
- `.full` - Wait until fully visible
- `.threshold.X` - Custom visibility percentage (0-100)
- `.margin.Xpx` or `.margin.X%` - Intersection margin

[Learn more about wire:intersect →](/docs/4.x/wire-intersect)

**`wire:ref` - Element references**

Easily reference and interact with elements in your template:

```blade
<div wire:ref="modal">
    <!-- Modal content -->
</div>

<button wire:click="$js.scrollToModal">Scroll to modal</button>

<script>
    this.$js.scrollToModal = () => {
        this.$refs.modal.scrollIntoView()
    }
</script>
```

[Learn more about wire:ref →](/docs/4.x/wire-ref)

**`.renderless` modifier**

Skip component re-rendering directly from the template:

```blade
<button wire:click.renderless="trackClick">Track</button>
```

This is an alternative to the `#[Renderless]` attribute for actions that don't need to update the UI.

**`.preserve-scroll` modifier**

Preserve scroll position during updates to prevent layout jumps:

```blade
<button wire:click.preserve-scroll="loadMore">Load More</button>
```

**`data-loading` attribute**

Every element that triggers a network request automatically receives a `data-loading` attribute, making it easy to style loading states with Tailwind:

```blade
<button wire:click="save" class="data-loading:opacity-50 data-loading:pointer-events-none">
    Save Changes
</button>
```

[Learn more about loading states →](/docs/4.x/loading-states)

### JavaScript improvements

**`$errors` magic property**

Access your component's error bag from JavaScript:

```blade
<div wire:show="$errors.has('email')">
    <span wire:text="$errors.first('email')"></span>
</div>
```

[Learn more about validation →](/docs/4.x/validation)

**`$intercept` magic**

Intercept and modify Livewire requests from JavaScript:

```blade
<script>
this.$intercept('save', ({ ... }) => {
    // ...
})
</script>
```

[Learn more about JavaScript interceptors →](/docs/4.x/javascript#interceptors)

**Island targeting from JavaScript**

Trigger island renders directly from the template:

```blade
<button wire:click="loadMore" wire:island.append="stats">
    Load more
</button>
```

[Learn more about islands →](/docs/4.x/islands)

---

## Validation Using custom validators
Validation | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/validation

## Using custom validators

If you wish to use your own validation system in Livewire, that isn't a problem. Livewire will catch any `ValidationException` exceptions thrown inside of components and provide the errors to the view just as if you were using Livewire's own `validate()` method.

Below is an example of the `CreatePost` component, but instead of using Livewire's validation features, a completely custom validator is being created and applied to the component properties:

```php
use Illuminate\Support\Facades\Validator;
use Livewire\Component;
use App\Models\Post;

class CreatePost extends Component
{
	public $title = '';

    public $content = '';

    public function save()
    {
        $validated = Validator::make(
            // Data to validate...
            ['title' => $this->title, 'content' => $this->content],

            // Validation rules to apply...
            ['title' => 'required|min:3', 'content' => 'required|min:3'],

            // Custom validation messages...
            ['required' => 'The :attribute field is required'],
         )->validate();

		Post::create($validated);

		return redirect()->to('/posts');
    }

    // ...
}
```

---

## Database Introduction Configuration SQLite Configuration
Database | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/database.md

#### SQLite Configuration

SQLite databases are contained within a single file on your filesystem. You can create a new SQLite database using the `touch` command in your terminal: `touch database/database.sqlite`. After the database has been created, you may easily configure your environment variables to point to this database by placing the absolute path to the database in the `DB_DATABASE` environment variable:

```ini
DB_CONNECTION=sqlite
DB_DATABASE=/absolute/path/to/database.sqlite
```

By default, foreign key constraints are enabled for SQLite connections. If you would like to disable them, you should set the `DB_FOREIGN_KEYS` environment variable to `false`:

```ini
DB_FOREIGN_KEYS=false
```

> [!NOTE]
> If you use the [Laravel installer](/docs/{{version}}/installation#creating-a-laravel-project) to create your Laravel application and select SQLite as your database, Laravel will automatically create a `database/database.sqlite` file and run the default [database migrations](/docs/{{version}}/migrations) for you.

---

## Passport Personal Access Tokens Customizing the User Provider
Passport | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/passport.md

### Customizing the User Provider

If your application uses more than one [authentication user provider](/docs/{{version}}/authentication#introduction), you may specify which user provider the personal access grant client uses by providing a `--provider` option when creating the client via the `artisan passport:client --personal` command. The given provider name should match a valid provider defined in your application's `config/auth.php` configuration file. You can then [protect your route using middleware](#multiple-authentication-guards) to ensure that only users from the guard's specified provider are authorized.

---

## Upgrade Guide Scratch File new features (link to relevant docs files for each of these of course)
Upgrade Guide Scratch File | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/upgrade-guide-scratch-file

## new features (link to relevant docs files for each of these of course)

not sure where to note but view-based component files are prefixed withemojis by deatult. you can change make_command config for this and never see the emojis at all. however they are good to:
- distinguish plain blade files from livewire view-based files in your filesystem and editor searching and what now.

- data-loading attribute gets added to every element that triggered a network request. not sure if this is documented.
- wire:[click|...].preserve-scroll="..." - this helper makes it so that before a request comes back and updates the html fo the page it preserves scroll position so there's no layout jump while scrolling or anything. not sure if docuemnted. might need to look at source to determine where it goes
- `wire:intersect`. this is now a new api to mirror alpine's x-intersect. it allows you to run an action when an element enters the viewport. `wire:intersect:enter|leave` are avaialble modifier type things. also things like .once (only fire once) .half (wait till half is vislble/invisible) .full (waits till all of it is inthe viewport to fire) .threshold.50 allows you to manually configure the amoyunt visible needed. margin.200px (allows you to set a margin of intersection) or all of them like so: margin.10%.25px.25.25px
- SLots. components now have slots and attribute bag forwarding {{ $attributes }}
- `wire:ref` allows you to easily access element from js and dispatch events to targeted components inside a loop or something
- `wire:sort` new API to allow drag-sorting of items in a group. suports nesting and drag-between-groups type use-cases
- Livewire now ships with an `$errors` magic that gives you client-side access to the compoennts's error bag (this might need to be documented somewhere actually)
- Islands. obviously this is like the big feature of V4. there are docs for it.
- wire:click="$island('foo', { mode: 'prepend' })" i think is an undocumented feature for directly calling the render of an island and optionally pass a render mode like append or something
- `$intercept` magic. like `$wire.$intercept()` or `this.$intercept()` optionally accepts name of action to intercept and callback with hooks as params. this is doucmented you can reference that.
- `.async` wire:??? modifier and #[Async] attribute.
- `.renderless` is now an avaialble modifier like .async as an alternative to the existing #[Renderless] action/method attribute
- CSP-mode. If you set `csp_safe` to true in your config livewire will now use the alpine CSP build and your whole app will avoid unsafe eval violations. there are many restrictions when using this mode. you can no longer put complex js or global expressions like: `wire:click="doSomething($event.detail.foo)"` or global things like `wire:click="redirectHere(window.location.href)"`
- defer loading in addition to lazy. <livewire:component defer> attribute #[Defer] attribute for class (same signatures as lazy)
- can use additional `lazy.bundle` or `defer.bundle` additional syntax to flag the lazy load to bundle multiple lazy loads instead of them being isolated/parralel. There's also `#[Defer|Lazy(bundle: true)]` for this.
-kinda big one. view-based components can have  at the bottom with now `@script` wrapper and they work differently. their source is made available via a faux js file to frontend so caching and native module code can work. also they automatically bind this. ($wire is what this is ) and $wire is still available but this. is preferred.

_[Truncated]_