text:
Script completed
Wall time 5.1 seconds
Output:

text:
Warning: truncated output (original token count: 12481)
Total output lines: 1

{"content":[{"type":"text","text":"# Search Results\n\n## Routing Rate Limiting Attaching Rate Limiters to Routes\nRouting | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/routing.md\n\n\n### Attaching Rate Limiters to Routes\n\nRate limiters may be attached to routes or route groups using the `throttle` [middleware](/docs/{{version}}/middleware). The throttle middleware accepts the name of the rate limiter you wish to assign to the route:\n\n```php\nRoute::middleware(['throttle:uploads'])->group(function () {\n    Route::post('/audio', function () {\n        // ...\n    });\n\n    Route::post('/video', function () {\n        // ...\n    });\n});\n```\n\n---\n\n## Lazy Disabling lazy loading for tests\nLazy | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/lazy\n\n## Disabling lazy loading for tests\n\nWhen unit testing a lazy component, or a page with nested lazy components, you may want to disable the \"lazy\" behavior so that you can assert the final rendered behavior. Otherwise, those components would be rendered as their placeholders during your tests.\n\nYou can easily disable lazy loading using the `Livewire::withoutLazyLoading()` testing helper like so:\n\n```php\n<?php\n\nnamespace Tests\\Feature\\Livewire;\n\nuse App\\Livewire\\Dashboard;\nuse Livewire\\Livewire;\nuse Tests\\TestCase;\n\nclass DashboardTest extends TestCase\n{\n    public function test_renders_successfully()\n    {\n        Livewire::withoutLazyLoading() // [tl! highlight]\n            ->test(Dashboard::class)\n            ->assertSee(...);\n    }\n}\n```\n\nNow, when the dashboard component is rendered for this test, it will skip rendering the `placeholder()` and instead render the full component as if lazy loading wasn't applied at all.\n\n---\n\n## Components Modal > flux:modal.close\nComponents Modal | livewire/flux@2.x | Source: https://fluxui.dev/components/modal#livewire/flux\n\n
flux:modal.close

<ui-table-scroll-area>

Slot

Description

\n    default\n

The close trigger element (e.g., button).

</ui-table-scroll-area>

\n\n---\n\n## Fortify Authentication Customizing User Authentication Authentication Guard\nFortify | laravel/fortify@latest | Source: https://github.com/laravel/docs/blob/13.x/fortify.md\n\n\n#### Authentication Guard\n\nYou may customize the authentication guard used by Fortify within your application's `fortify` configuration file. However, you should ensure that the configured guard is an implementation of `Illuminate\\Contracts\\Auth\\StatefulGuard`. If you are attempting to use Laravel Fortify to authenticate an SPA, you should use Laravel's default `web` guard in combination with [Laravel Sanctum](https://laravel.com/docs/sanctum).\n\n---\n\n## Testing Browser testing\nTesting | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/testing\n\n## Browser testing\n\nPest v4 includes first-party browser testing support powered by Playwright. This allows you to test your Livewire components in a real browser, interacting with them just like a user would.\n\n### Installing browser testing\n\nFirst, install the Pest browser plugin:\n\n```shell\ncomposer require pestphp/pest-plugin-browser --dev\n```\n\nNext, install Playwright via npm:\n\n```shell\nnpm install playwright@latest\nnpx playwright install\n```\n\nFor complete browser testing documentation, see the [Pest browser testing guide](https://pestphp.com/docs/browser-testing).\n\n### Writing browser tests\n\nInstead of using `Livewire::test()`, you can use `Livewire::visit()` to test your component in a real browser:\n\n```php\nit('can create a new post', function () {\n    Livewire::visit('post.create')\n        ->type('[wire\\:model=\"title\"]', 'My first post')\n        ->type('[wire\\:model=\"content\"]', 'This is the content')\n        ->press('Save')\n        ->assertSee('Post created successfully');\n});\n```\n\nBrowser tests are slower than unit tests but provide end-to-end confidence that your components work as expected in a real browser environment.\n\nFor a complete list of available browser testing assertions, see the [Pest browser testing assertions](https://pestphp.com/docs/browser-testing#content-available-assertions).\n\n> [!info] When to use browser tests\n> Use browser tests for critical user flows and complex interactions. For most component testing, the standard `Livewire::test()` approach is faster and sufficient.\n\n---\n\n## Pulse Custom Cards Styling Tailwind CSS\nPulse | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/pulse.md\n\n\n#### Tailwind CSS\n\nWhen using Tailwind CSS, you should create a dedicated CSS entrypoint. The following example excludes Tailwind's [Preflight](https://tailwindcss.com/docs/preflight) base styles which are already included by Pulse, and scopes Tailwind using a CSS selector to avoid conflicts with Pulse's Tailwind classes:\n\n```css\n@import \"tailwindcss/theme.css\";\n\n@custom-variant dark (&:where(.dark, .dark *));\n@source \"./../../views/livewire/pulse/top-sellers.blade.php\";\n\n@theme {\n  /* ... */\n}\n\n#top-sellers {\n  @import \"tailwindcss/utilities.css\" source(none);\n}\n```\n\nYou will also need to include an `id` or `class` attribute in your card's view that matches the CSS selector in your entrypoint:\n\n```blade\n<x-pulse::card id=\"top-sellers\" :cols=\"$cols\" :rows=\"$rows\" class=\"$class\">\n    ...\n</x-pulse::card>\n```\n\n---\n\n## Routing Rate Limiting Defining Rate Limiters\nRouting | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/routing.md\n\n\n### Defining Rate Limiters\n\nLaravel includes powerful and customizable rate limiting services that you may utilize to restrict the amount of traffic for a given route or group of routes. To get started, you should define rate limiter configurations that meet your application's needs.\n\nRate limiters may be defined within the `boot` method of your application's `App\\Providers\\AppServiceProvider` class:\n\n```php\nuse Illuminate\\Cache\\RateLimiting\\Limit;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\RateLimiter;\n\n/**\n * Bootstrap any application services.\n */\npublic function boot(): void\n{\n    RateLimiter::for('api', function (Request $request) {\n        return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());\n    });\n}\n```\n\nRate limiters are defined using the `RateLimiter` facade's `for` method. The `for` method accepts a rate limiter name and a closure that returns the limit configuration that should apply to routes that are assigned to the rate limiter. Limit configuration are instances of the `Illuminate\\Cache\\RateLimiting\\Limit` class. This class contains helpful \"builder\" methods so that you can quickly define your limit. The rate limiter name may be any string you wish:\n\n```php\nuse Illuminate\\Cache\\RateLimiting\\Limit;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\RateLimiter;\n\n/**\n * Bootstrap any application services.\n */\npublic function boot(): void\n{\n    RateLimiter::for('global', function (Request $request) {\n        return Limit::perMinute(1000);\n    });\n}\n```\n\nIf the incoming request exceeds the specified rate limit, a response with a 429 HTTP status code will automatically be returned by Laravel. If you would like to define your own response that should be returned by a rate limit, you may use the `response` method:\n\n```php\nRateLimiter::for('global', function (Request $request) {\n    return Limit::perMinute(1000)->response(function (Request $request, array $headers) {\n        return response('Custom response...', 429, $headers);\n    });\n});\n```\n\nSince rate limiter callbacks receive the incoming HTTP request instance, you may build the appropriate rate limit dynamically based on the incoming request or authenticated user:\n\n```php\nRateLimiter::for('uploads', function (Request $request) {\n    return $request->user()->vipCustomer()\n        ? Limit::none()\n        : Limit::perHour(10);\n});\n```\n\n---\n\n## Fortify Authentication Customizing User Authentication Authentication Guard\nFortify | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/fortify.md\n\n\n#### Authentication Guard\n\nYou may customize the authentication guard used by Fortify within your application's `fortify` configuration file. However, you should ensure that the configured guard is an implementation of `Illuminate\\Contracts\\Auth\\StatefulGuard`. If you are attempting to use Laravel Fortify to authenticate an SPA, you should use Laravel's default `web` guard in combination with [Laravel Sanctum](https://laravel.com/docs/sanctum).\n\n---\n\n## Browser Testing\nBrowser Testing | pestphp/pest@4.x | Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md\n\n---\ntitle: Browser Testing\ndescription:\n---\n\n# Browser Testing\n\nBrowser testing is an essential part of modern web development, allowing you to ensure that your application works correctly across different browsers and devices. Pest provides a simple and elegant way to write browser tests. Here is an example of how to write a browser test using Pest:\n\n```php\nit('may welcome the user', function () {\n    $page = visit('/');\n\n    $page->assertSee('Welcome');\n});\n```\n\nThis is a basic example of a browser test that checks if the homepage contains the text \"Welcome\". However, Pest's browser testing capabilities go beyond this simple example. You can use various methods to interact with the page, such as clicking buttons, filling out forms, and navigating between pages.\n\nHere is an example of a more complex browser test, on Laravel, that checks if a user can sign in:\n\n```php\nit('may sign in the user', function () {\n    Event::fake();\n\n    User::factory()->create([ // assumes RefreshDatabase trait is used on Pest.php...\n        'email' => 'nuno@laravel.com',\n        'password' => 'password',\n    ]);\n\n    $page = visit('/')->on()->mobile()->firefox();\n\n    $page->click('Sign In')\n         ->assertUrlIs('/login')\n         ->assertSee('Sign In to Your Account')\n         ->fill('email', 'nuno@laravel.com')\n         ->fill('password', 'password')\n         ->click('Submit')\n         ->assertSee('Dashboard');\n\n    $this->assertAuthenticated();\n\n    Event::assertDispatched(UserLoggedIn::class);\n});\n```\n\nNote that, you are leveraging the full power of Laravel's testing capabilities, such as refresh database, event faking, and authentication assertions, while also actually doing browser testing.\n\n## Getting Started\n\nTo get started with browser testing in Pest, you need to install the Pest Browser plugin. You can do this by running the following command:\n\n```bash\ncomposer require pestphp/pest-plugin-browser --dev\n\nnpm install playwright@latest\nnpx playwright install\n```\n\nFinally, add `tests/Browser/Screenshots` to your `.gitignore` file to avoid committing screenshots taken during browser tests.\n\n### Running Browser Tests\n\nRunning browser tests is similar to running regular Pest tests:\n\n```bash\n./vendor/bin/pest\n```\n\nWe recommend running tests in parallel using the `--parallel` option to speed up the execution:\n\n```bash\n./vendor/bin/pest --parallel\n```\n\nFor debugging purposes, you can run the tests in a headed mode and pause the execution at the end of the failed test run:\n\n```bash\n./vendor/bin/pest --debug\n```\n\n### Navigation\n\nThe `visit()` method is used to navigate to a specific URL in your browser test. It provides various methods to interact with the page:\n\n```php\ntest('example', function () {\n    $page = visit('/');\n\n    $page->assertSee('Welcome');\n});\n```\n\n### Using Other Browsers\n\nBy default, the `visit()` method uses Chrome as the browser. However, if you want to use a different browser, you can specify it using the `--browser` option when running the tests:\n\n```bash\n./vendor/bin/pest --browser firefox\n./vendor/bin/pest --browser safari\n```\n\nIf you wish to use a different browser by default without specifying it in the command line, you can set it in your `Pest.php` configuration file:\n\n```php\npest()->browser()->inFirefox();\npest()->browser()->inSafari();\n```\n\n### Using Other Devices\n\nThe `visit()` method uses a desktop viewport. However, you can specify a mobile viewport using the `onMobile()` method. For example:\n\n```php\n$page = visit('/')->on()->mobile();\n```\n\nIf you wish to use a specific device, you can use the `on()` method and chain it with the `macbook14`, `iPhone14Pro`, etc:\n\n```php\n$page = visit('/')->on()->iPhone14Pro();\n```\n\n### Using Dark Mode\n\nPest enforces a light color scheme by default. However, you can specify a dark color scheme using the `inDarkMode()` method:\n\n```php\n$page = visit('/')->inDarkMode();\n```\n\n### Visiting Multiple Pages\n\nYou can visit multiple pages simultaneously by passing an array of URLs to the `visit()` method. This is useful for testing scenarios where you need to interact with multiple pages at once:\n\n```php\n$pages = visit(['/', '/about']);\n\n$pages->assertNoSmoke()\n    ->assertNoAccessibilityIssues()\n    ->assertNoConsoleLogs()\n    ->assertNoJavaScriptErrors();\n\n[$homePage, $aboutPage] = $pages;\n\n$homePage->assertSee('Welcome to our website');\n$aboutPage->assertSee('About Us');\n```\n\n### Navigation\n\nAfter visiting a page, you can navigate to other pages using the `navigate()` method. This method allows you to navigate to a different URL while keeping the current browser context:\n\n```php\n$page = visit('/');\n\n$page->navigate('/about')\n     ->assertSee('About Us');\n```\n\n### Locating Elements\n\nYou can locate elements in the DOM using text or CSS selectors. Pest provides a simple syntax for locating elements:\n\n```php\n// Clicks the first link with the text \"Login\"\n$page->click('Login');\n\n// Clicks the first element with the class \"btn-primary\"\n$page->click('.btn-primary');\n\n// Clicks the element with the data-test attribute \"login\"\n$page->click('@login');\n\n// Clicks the element with the ID \"submit-button\"\n$page->click('#submit-button');\n\n// etc...\n```\n\n### Configuring Timeouts\n\nSometimes, elements may take time to appear on the page. By default, Pest waits for `5` seconds before timing out. You can configure the default timeout for browser tests in your `Pest.php` configuration file:\n\n```php\npest()->browser()->timeout(10000);\n```\n\n### Configuring User Agent\n\nBy default, the User Agent will default to the Browser you're running for tests such as: `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/133.0.6943.16 Safari/537.36` \n\nYou may wish to override the User Agent of the browser for all of your tests, you can configure this in the `Pest.php` configuration file:\n\n```php\npest()->browser()->userAgent('CustomUserAgent');\n```\n\n### Configuring Host\n\nBy default, the server will bind to `127.0.0.1` for all browser tests.\n\nYou may wish to override the host for subdomain applications. You can configure this in the `Pest.php` configuration file:\n\n```php\npest()->browser()->withHost('some-subdomain.localhost');\n```\n\n### Geolocation\n\nSometimes, you need to define where the browser believes it is physically on the earth.  This method takes a latitude and longitude and will set the `geolocation` permission in the browser and then make the coordinates available via Javascript's getCurrentPosition API:\n\n```php\n$page = visit('/')\n     ->geolocation(39.399872, -8.224454);\n\n$page->assertSee('Portugal');\n```\n\nYou may also define one of several specific preset cities which will configure the browser's geolocation, timezone and locale:\n\n```php\n$page = visit('/')\n     ->from()->losAngeles();\n\n$page->assertSee('Los Angeles');\n$page->assertSee('America/Los_Angeles');\n$page->assertSee('en-US');\n```\n\n### Configuring Locale\n\nYou can set the locale for your test requests using the `withLocale` method. This is particularly useful for testing multilingual applications.\n\n```php\n$page = visit('/')->withLocale('fr-FR');\n\n$page->assertSee('Bienvenue');\n```\n### Configuring Timezone\n\nYou can set the timezone for your test requests using the `withTimezone` method. This is useful for testing date and time displays in different time zones.\n\n```php\n$page = visit('/')->withTimezone('America/New_York');\n\n$page->assertSee('EST');\n```\n\n### Configuring UserAgent\n\nYou can set the User-Agent header for your test requests using the `withUserAgent` method. This is useful for testing how your application responds to different types of clients, such as mobile browsers or bots.\n\n```php\n$page = visit('/')->withUserAgent('Googlebot');\n\n$page->assertSee('Welcome, bot!');\n```\n\n### Configuring Host\n\nYou can set the host for your test server using the `withHost` method. This is useful for testing subdomains or where different hosts serve different content.\n\n```php\n$page = visit('/dashboard')->withHost('some-subdomain.localhost');\n\n$page->assertSee('Welcome to Some Subdomain');\n```\n\n## Table of Contents\n\n### Available Assertions\n\n
\n\n[assertTitle](#assert-title)\n[assertTitleContains](#assert-title-contains)\n[assertSee](#assert-see)\n[assertDontSee](#assert-dont-see)\n[assertSeeIn](#assert-see-in)\n[assertDontSeeIn](#assert-dont-see-in)\n[assertSeeAnythingIn](#assert-see-anything-in)\n[assertSeeNothingIn](#assert-see-nothing-in)\n[assertCount](#assert-count)\n[assertScript](#assert-script)\n[assertSourceHas](#assert-source-has)\n[assertSourceMissing](#assert-source-missing)\n[assertSeeLink](#assert-see-link)\n[assertDontSeeLink](#assert-dont-see-link)\n[assertChecked](#assert-checked)\n[assertNotChecked](#assert-not-checked)\n[assertIndeterminate](#assert-indeterminate)\n[assertRadioSelected](#assert-radio-selected)\n[assertRadioNotSelected](#assert-radio-not-selected)\n[assertSelected](#assert-selected)\n[assertNotSelected](#assert-not-selected)\n[assertValue](#assert-value)\n[assertValueIsNot](#assert-value-is-not)\n[assertAttribute](#assert-attribute)\n[assertAttributeMissing](#assert-attribute-missing)\n[assertAttributeContains](#assert-attribute-contains)\n[assertAttributeDoesntContain](#assert-attribute-doesnt-contain)\n[assertAriaAttribute](#assert-aria-attribute)\n[assertDataAttribute](#assert-data-attribute)\n[assertVisible](#assert-visible)\n[assertPresent](#assert-present)\n[assertNotPresent](#assert-not-present)\n[assertMissing](#assert-missing)\n[assertEnabled](#assert-enabled)\n[assertDisabled](#assert-disabled)\n[assertButtonEnabled](#assert-button-enabled)\n[assertButtonDisabled](#assert-button-disabled)\n[assertUrlIs](#assert-url-is)\n[assertSchemeIs](#assert-scheme-is)\n[assertSchemeIsNot](#assert-scheme-is-not)\n[assertHostIs](#assert-host-is)\n[assertHostIsNot](#assert-host-is-not)\n[assertPortIs](#assert-port-is)\n[assertPortIsNot](#assert-port-is-not)\n[assertPathBeginsWith](#assert-path-begins-with)\n[assertPathEndsWith](#assert-path-ends-with)\n[assertPathContains](#assert-path-contains)\n[assertPathIs](#assert-path-is)\n[assertPathIsNot](#assert-path-is-not)\n[assertQueryStringHas](#assert-query-string-has)\n[assertQueryStringMissing](#assert-query-string-m…2481 tokens truncated…>\n\n```css\n/* [!code filename:app.css] */\n.my-element {\n  background: white;\n\n  /* [!code highlight:4] */\n  @variant hover:focus {\n    background: black;\n  }\n}\n```\n\n```css\n/* [!code filename:Compiled CSS] */\n.my-element {\n  background: white;\n\n  /* [!code highlight:8] */\n  &:hover {\n    @media (hover: hover) {\n      &:focus {\n        background: black;\n      }\n    }\n  }\n}\n```\n\n</CodeExampleStack>\n\nTo apply the same styles for multiple variants, separate each variant with a comma:\n\n<CodeExampleStack>\n\n```css\n/* [!code filename:app.css] */\n.my-element {\n  background: white;\n\n  /* [!code highlight:4] */\n  @variant hover, focus {\n    background: black;\n  }\n}\n```\n\n```css\n/* [!code filename:Compiled CSS] */\n.my-element {\n  background: white;\n\n  /* [!code highlight:6] */\n  &:hover {\n    @media (hover: hover) {\n      background: black;\n    }\n  }\n\n  /* [!code highlight:4] */\n  &:focus {\n    background: black;\n  }\n}\n```\n\n</CodeExampleStack>\n\n\n\n---\n\n## Docs Upgrading > Prerequisites\nDocs Upgrading | livewire/flux@2.x | Source: https://fluxui.dev/docs/upgrading#livewire/flux\n\n
\n            Prerequisites\n

Before upgrading to Flux v2, make sure you have the following:

\n    Laravel version 10 or later\n

\n    Livewire version 3.5.19 or later\n

\n    Tailwind CSS version 4 or later\n

Flux v2 is built on top of Tailwind CSS v4, so if you are using an older version of Tailwind CSS, you need to upgrade it to v4 or later by following the Tailwind CSS upgrade guide.
\n\n---\n\n## Styling With Utility Classes Managing style conflicts\nStyling With Utility Classes | tailwindcss@4.x | Source: https://github.com/tailwindlabs/tailwindcss.com/blob/main/src/docs/styling-with-utility-classes.mdx\n\n## Managing style conflicts\n\n### Conflicting utility classes\n\nWhen you add two classes that target the same CSS property, the class that appears later in the stylesheet wins. So in this example, the element will receive `display: grid` even though `flex` comes last in the actual `class` attribute:\n\n<CodeExampleStack>\n\n```html\n<!-- [!code filename:HTML] -->\n<!-- prettier-ignore -->\n<div class=\"grid flex\">\n  <!-- ... -->\n</div>\n```\n\n```css\n/* [!code filename: CSS] */\n.flex {\n  display: flex;\n}\n.grid {\n  display: grid;\n}\n```\n\n</CodeExampleStack>\n\nIn general, you should just never add two conflicting classes to the same element — only ever add the one you actually want to take effect:\n\n```jsx\n// [!code filename:example.jsx]\n// [!code word:gridLayout\\ \\?\\ \\\"grid\\\"\\ \\:\\ \\\"flex\\\"]\nexport function Example({ gridLayout }) {\n  return <div className={gridLayout ? \"grid\" : \"flex\"}>{/* ... */}</div>;\n}\n```\n\nUsing component-based libraries like React or Vue, this often means exposing specific props for styling customizations instead of letting consumers add extra classes from outside of a component, since those styles will often conflict.\n\n### Using the important modifier\n\nWhen you really need to force a specific utility class to take effect and have no other means of managing the specificity, you can add `!` to the end of the class name to make all of the declarations `!important`:\n\n<CodeExampleStack>\n\n```html\n<!-- [!code filename:HTML] -->\n<!-- [!code classes:bg-red-500!] -->\n<!-- prettier-ignore -->\n<div class=\"bg-teal-500 bg-red-500!\">\n  <!-- ... -->\n</div>\n```\n\n```css\n/* [!code filename: Generated CSS] */\n/* [!code word:!important] */\n.bg-red-500\\! {\n  background-color: var(--color-red-500) !important;\n}\n.bg-teal-500 {\n  background-color: var(--color-teal-500);\n}\n```\n\n</CodeExampleStack>\n\n### Using the important flag\n\nIf you're adding Tailwind to a project that has existing complex CSS with high specificity rules, you can use the `important` flag when importing Tailwind to mark _all_ utilities as `!important`:\n\n<CodeExampleStack>\n\n```css\n/* [!code filename:app.css] */\n/* [!code word:important] */\n@import \"tailwindcss\" important;\n```\n\n```css\n/* [!code filename:Compiled CSS] */\n/* [!code word:!important] */\n@layer utilities {\n  .flex {\n    display: flex !important;\n  }\n  .gap-4 {\n    gap: 1rem !important;\n  }\n  .underline {\n    text-decoration-line: underline !important;\n  }\n}\n```\n\n</CodeExampleStack>\n\n### Using the prefix option\n\nIf your project has class names that conflict with Tailwind CSS utilities, you can prefix all Tailwind-generated classes and CSS variables using the `prefix` option:\n\n<CodeExampleStack>\n\n```css\n/* [!code filename:app.css] */\n/* [!code word:important] */\n@import \"tailwindcss\" prefix(tw);\n```\n\n```css\n/* [!code filename:Compiled CSS] */\n/* [!code word:tw\\:] */\n@layer theme {\n  :root {\n    --tw-color-red-500: oklch(0.637 0.237 25.331);\n  }\n}\n\n@layer utilities {\n  .tw\\:text-red-500 {\n    color: var(--tw-color-red-500);\n  }\n}\n```\n\n</CodeExampleStack>\n\n\n---\n\n## Fortify Authentication Customizing User Authentication\nFortify | laravel/fortify@latest | Source: https://github.com/laravel/docs/blob/13.x/fortify.md\n\n\n### Customizing User Authentication\n\nFortify will automatically retrieve and authenticate the user based on the provided credentials and the authentication guard that is configured for your application. However, you may sometimes wish to have full customization over how login credentials are authenticated and users are retrieved. Thankfully, Fortify allows you to easily accomplish this using the `Fortify::authenticateUsing` method.\n\nThis method accepts a closure which receives the incoming HTTP request. The closure is responsible for validating the login credentials attached to the request and returning the associated user instance. If the credentials are invalid or no user can be found, `null` or `false` should be returned by the closure. Typically, this method should be called from the `boot` method of your `FortifyServiceProvider`:\n\n```php\nuse App\\Models\\User;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\Hash;\nuse Laravel\\Fortify\\Fortify;\n\n/**\n * Bootstrap any application services.\n */\npublic function boot(): void\n{\n    Fortify::authenticateUsing(function (Request $request) {\n        $user = User::where('email', $request->email)->first();\n\n        if ($user &&\n            Hash::check($request->password, $user->password)) {\n            return $user;\n        }\n    });\n\n    // ...\n}\n```\n\n---\n\n## Browser Testing waitForKey\nBrowser Testing | pestphp/pest@4.x | Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md\n\n\n### waitForKey\n\nThe `waitForKey` method opens the current page URL in the default web browser and waits for a key press:\n\n```php\n$page->waitForKey(); // Useful for debugging\n```\n\n## Debugging tests\n\n\nSometimes you may want to debug your browser tests. Pest provides a convenient way to do this by using the `--debug` option, which makes pest to open the browser window and pause the execution of the test when it fails. You can then inspect the page and see what went wrong.\n\n```bash\n./vendor/bin/pest --debug\n```\n\nOptionally, you can also use the `debug()` method in your test. It will limit execution to this test (like using [`only()`](/docs/filtering-tests#only)), pause the execution and open the browser window:\n\n```php\n$page->debug();\n```\n\n\n\nYou can also take a screenshot of the current page using the `screenshot()` method. This is useful for visual debugging:\n\nNOTE: If you don't pass the filename, it will use the test name as the filename.\n\n```php\n$page->screenshot();\n$page->screenshot(fullPage: true);\n$page->screenshot(filename: 'custom-name');\n```\n\n\nYou can also take a screenshot of a specific element using the `screenshotElement()` method:\n\n```php\n$page->screenshotElement('#my-element');\n```\n\n\nYou can also use the `tinker()` method to open a Tinker session in the context of the current page. This allows you to interact with the page using PHP code:\n\n```php\n$page->tinker();\n```\n\n\nAfter you can run your tests with the `--headed` option to open the browser window:\n\n```bash\n./vendor/bin/pest --headed\n```\n\nIf you wish to run the tests in a headed mode by default, you can set it in your `Pest.php` configuration file:\n\n```php\npest()->browser()->headed();\n```\n\n## Continuous Integration\n\nYou may refer to Pest's [Continuous Integration](https://pestphp.com/docs/continuous-integration) documentation for more information on how to run your browser tests in a CI environment.\n\nHowever, if you are using GitHub Actions, you need to add the following steps to your workflow file:\n\n```yaml\n    - uses: actions/setup-node@v4\n      with:\n        node-version: lts/*\n\n    - name: Install dependencies\n      run: npm ci\n\n    - name: Install Playwright Browsers\n      run: npx playwright install --with-deps\n```\n\n---\n\nNow, let's dive into architectural testing and how it can benefit your development process. By performing architectural testing, you can evaluate the overall design of your application and identify potential flaws before they become significant issues: [Arch Testing](/docs/arch-testing)\n\n---\n\n## Upgrading New features in v4\nUpgrading | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/upgrading\n\n## New features in v4\n\nLivewire v4 introduces several powerful new features you can start using immediately:\n\n### Component features\n\n**Single-file and multi-file components**\n\nv4 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.\n\nBy 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.\n\n```bash\nphp artisan make:livewire create-post        # Single-file (default)\nphp artisan make:livewire create-post --mfc  # Multi-file\nphp artisan livewire:convert create-post     # Convert between formats\n```\n\n[Learn more about component formats →](/docs/4.x/components)\n\n**Slots and attribute forwarding**\n\nComponents now support slots and automatic attribute bag forwarding using `{{ $attributes }}`, making component composition more flexible.\n\n[Learn more about nesting components →](/docs/4.x/nesting)\n\n**JavaScript in view-based components**\n\nView-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:\n\n```blade\n<div>\n    <!-- Your component template -->\n</div>\n\n<script>\n    // $wire is automatically bound as 'this'\n    this.count++  // Same as $wire.count++\n\n    // $wire is still available if preferred\n    $wire.save()\n</script>\n```\n\n[Learn more about JavaScript in components →](/docs/4.x/javascript)\n\n### Islands\n\nIslands allow you to create isolated regions within a component that update independently, dramatically improving performance without creating separate child components.\n\n```blade\n@island(name: 'stats', lazy: true)\n    <div>{{ $this->expensiveStats }}</div>\n@endisland\n```\n\n[Learn more about islands →](/docs/4.x/islands)\n\n### Loading improvements\n\n**Deferred loading**\n\nIn addition to lazy loading (viewport-based), components can now be deferred to load immediately after the initial page load:\n\n```blade\n<livewire:revenue defer />\n```\n\n```php\n#[Defer]\nclass Revenue extends Component { ... }\n```\n\n**Bundled loading**\n\nControl whether multiple lazy/deferred components load in parallel or bundled together:\n\n```blade\n<livewire:revenue lazy.bundle />\n<livewire:expenses defer.bundle />\n```\n\n```php\n#[Lazy(bundle: true)]\nclass Revenue extends Component { ... }\n```\n\n[Learn more about lazy and deferred loading →](/docs/4.x/lazy)\n\n### Async actions\n\nRun actions in parallel without blocking other requests using the `.async` modifier or `#[Async]` attribute:\n\n```blade\n<button wire:click.async=\"logActivity\">Track</button>\n```\n\n```php\n#[Async]\npublic function logActivity() { ... }\n```\n\n[Learn more about async actions →](/docs/4.x/actions#parallel-execution-with-async)\n\n### New directives and modifiers\n\n**`wire:sort` - Drag-and-drop sorting**\n\nBuilt-in support for sortable lists with drag-and-drop:\n\n```blade\n<ul wire:sort=\"updateOrder\">\n    @foreach ($items as $item)\n        <li wire:sort:item=\"{{ $item->id }}\" wire:key=\"{{ $item->id }}\">{{ $item->name }}</li>\n    @endforeach\n</ul>\n```\n\n[Learn more about wire:sort →](/docs/4.x/wire-sort)\n\n**`wire:intersect` - Viewport intersection**\n\nRun actions when elements enter or leave the viewport, similar to Alpine's [`x-intersect`](https://alpinejs.dev/plugins/intersect):\n\n```blade\n<!-- Basic usage -->\n<div wire:intersect=\"loadMore\">...</div>\n\n<!-- With modifiers -->\n<div wire:intersect.once=\"trackView\">...</div>\n<div wire:intersect:leave=\"pauseVideo\">...</div>\n<div wire:intersect.half=\"loadMore\">...</div>\n<div wire:intersect.full=\"startAnimation\">...</div>\n\n<!-- With options -->\n<div wire:intersect.margin.200px=\"loadMore\">...</div>\n<div wire:intersect.threshold.50=\"trackScroll\">...</div>\n```\n\nAvailable modifiers:\n- `.once` - Fire only once\n- `.half` - Wait until half is visible\n- `.full` - Wait until fully visible\n- `.threshold.X` - Custom visibility percentage (0-100)\n- `.margin.Xpx` or `.margin.X%` - Intersection margin\n\n[Learn more about wire:intersect →](/docs/4.x/wire-intersect)\n\n**`wire:ref` - Element references**\n\nEasily reference and interact with elements in your template:\n\n```blade\n<div wire:ref=\"modal\">\n    <!-- Modal content -->\n</div>\n\n<button wire:click=\"$js.scrollToModal\">Scroll to modal</button>\n\n<script>\n    this.$js.scrollToModal = () => {\n        this.$refs.modal.scrollIntoView()\n    }\n</script>\n```\n\n[Learn more about wire:ref →](/docs/4.x/wire-ref)\n\n**`.renderless` modifier**\n\nSkip component re-rendering directly from the template:\n\n```blade\n<button wire:click.renderless=\"trackClick\">Track</button>\n```\n\nThis is an alternative to the `#[Renderless]` attribute for actions that don't need to update the UI.\n\n**`.preserve-scroll` modifier**\n\nPreserve scroll position during updates to prevent layout jumps:\n\n```blade\n<button wire:click.preserve-scroll=\"loadMore\">Load More</button>\n```\n\n**`data-loading` attribute**\n\nEvery element that triggers a network request automatically receives a `data-loading` attribute, making it easy to style loading states with Tailwind:\n\n```blade\n<button wire:click=\"save\" class=\"data-loading:opacity-50 data-loading:pointer-events-none\">\n    Save Changes\n</button>\n```\n\n[Learn more about loading states →](/docs/4.x/loading-states)\n\n### Chunked, resumable, and multiple-file S3 uploads\n\nFile uploads now handle large files and unreliable connections automatically — no markup or API changes required:\n\n- **Large files bypass PHP's upload limits.** Files above the chunk threshold are sliced in the browser and reassembled server-side, so `upload_max_filesize` / `post_max_size` no longer cap your uploads — your `max:` validation rule does.\n- **Interrupted uploads resume.** Cancel, connection drop, or a full page reload — re-selecting the same file resumes from the chunks the server already has.\n- **S3 gets multiple files and native multipart.** Multiple-file S3 uploads now work (one presigned PUT per file), and large files use real S3 multipart uploads.\n\nThis is on by default. A few things to be aware of when upgrading:\n\n- **Chunking is enabled automatically.** Any local-disk file larger than 1MB now flows through the new chunk endpoint instead of a single POST. Set `temporary_file_upload.chunking` to `false` to opt out.\n- **If you set a custom upload `middleware`,** it now also governs the chunked upload endpoint, where a single file arrives as many rapid requests. A tight throttle like `throttle:60,1` will fail large uploads — throttle generously (the built-in default for the chunk endpoint is `throttle:600,1`).\n- **S3 users should add an `AbortIncompleteMultipartUpload` lifecycle rule** so abandoned multipart uploads don't accrue invisible storage. Re-running `php artisan livewire:configure-s3-upload-cleanup` adds it for you.\n- **`S3DoesntSupportMultipleFileUploads` is no longer thrown** (S3 multiple uploads are supported now). The class remains for backward compatibility but is deprecated; tests asserting this exception should be removed.\n\n[Learn more about uploads →](/docs/4.x/uploads)\n\n### JavaScript improvements\n\n**`$errors` magic property**\n\nAccess your component's error bag from JavaScript:\n\n```blade\n<div wire:show=\"$errors.has('email')\">\n    <span wire:text=\"$errors.first('email')\"></span>\n</div>\n```\n\n[Learn more about validation →](/docs/4.x/validation)\n\n**`$intercept` magic**\n\nIntercept and modify Livewire requests from JavaScript:\n\n```blade\n<script>\nthis.$intercept('save', ({ ... }) => {\n    // ...\n})\n</script>\n```\n\n[Learn more about JavaScript interceptors →](/docs/4.x/javascript#interceptors)\n\n**Island targeting from JavaScript**\n\nTrigger island renders directly from the template:\n\n```blade\n<button wire:click=\"loadMore\" wire:island.append=\"stats\">\n    Load more\n</button>\n```\n\n[Learn more about islands →](/docs/4.x/islands)\n\n---\n\n## Docs Upgrading > Upgrade guide\nDocs Upgrading | livewire/flux@2.x | Source: https://fluxui.dev/docs/upgrading#livewire/flux\n\n

\n    Upgrade guide\n

Follow this guide to upgrade from Flux v1.x to v2.x.

\n\n---\n\n## Fortify Authentication Customizing User Authentication\nFortify | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/fortify.md\n\n\n### Customizing User Authentication\n\nFortify will automatically retrieve and authenticate the user based on the provided credentials and the authentication guard that is configured for your application. However, you may sometimes wish to have full customization over how login credentials are authenticated and users are retrieved. Thankfully, Fortify allows you to easily accomplish this using the `Fortify::authenticateUsing` method.\n\nThis method accepts a closure which receives the incoming HTTP request. The closure is responsible for validating the login credentials attached to the request and returning the associated user instance. If the credentials are invalid or no user can be found, `null` or `false` should be returned by the closure. Typically, this method should be called from the `boot` method of your `FortifyServiceProvider`:\n\n```php\nuse App\\Models\\User;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\Hash;\nuse Laravel\\Fortify\\Fortify;\n\n/**\n * Bootstrap any application services.\n */\npublic function boot(): void\n{\n    Fortify::authenticateUsing(function (Request $request) {\n        $user = User::where('email', $request->email)->first();\n\n        if ($user &&\n            Hash::check($request->password, $user->password)) {\n            return $user;\n        }\n    });\n\n    // ...\n}\n```\n\n_[Truncated]_"}],"isError":false}


exec

status: completed

input:
const r = await tools.exec_command({cmd:"php artisan test --compact",workdir:"/Users/wesner/Herd/shop",yield_time_ms:30000,max_output_tokens:20000});
text(r.output);


type: CommandExecution

command:
/bin/zsh
-lc
php artisan test --compact

type: unknown

cmd: php artisan test --compact

status: completed


text:
Script completed
Wall time 1.3 seconds
Output:

text:
  .................................

  Tests:    33 passed (75 assertions)
  Duration: 1.13s


status: completed

input:
const results = await Promise.all([
  tools.exec_command({cmd:"sed -n '1,260p' config/auth.php; sed -n '1,220p' config/fortify.php; sed -n '1,260p' bootstrap/app.php; sed -n '1,260p' app/Models/User.php",workdir:"/Users/wesner/Herd/shop",yield_time_ms:10000,max_output_tokens:25000}),
  tools.exec_command({cmd:"sed -n '1,240p' resources/views/welcome.blade.php; sed -n '1,240p' resources/views/layouts/app.blade.php; sed -n '1,240p' resources/css/app.css; sed -n '1,220p' resources/js/app.js",workdir:"/Users/wesner/Herd/shop",yield_time_ms:10000,max_output_tokens:20000}),
  tools.exec_command({cmd:"sed -n '1,220p' database/seeders/DatabaseSeeder.php; sed -n '1,240p' tests/Pest.php; sed -n '1,220p' tests/TestCase.php",workdir:"/Users/wesner/Herd/shop",yield_time_ms:10000,max_output_tokens:12000})
]);
for (const r of results) text(r.output);


command: sed -n '1,260p' config/auth.php; sed -n '1,220p' config/fortify.php; sed -n '1,260p' bootstrap/app.php; sed -n '1,260p' app/Models/User.php

auth.php

type: read

cmd: sed -n '1,260p' config/auth.php

fortify.php

cmd: sed -n '1,220p' config/fortify.php

app.php

cmd: sed -n '1,260p' bootstrap/app.php

User.php

cmd: sed -n '1,260p' app/Models/User.php

stdout:
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option defines the default authentication "guard" and password
    | reset "broker" for your application. You may change these values
    | as required, but they're a perfect start for most applications.
    |
    */

    'defaults' => [
        'guard' => env('AUTH_GUARD', 'web'),
        'passwords' => env('AUTH_PASSWORD_BROKER', 'users'),
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | which utilizes session storage plus the Eloquent user provider.
    |
    | All authentication guards have a user provider, which defines how the
    | users are actually retrieved out of your database or other storage
    | system used by the application. Typically, Eloquent is utilized.
    |
    | Supported: "session"
    |
    */

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication guards have a user provider, which defines how the
    | users are actually retrieved out of your database or other storage
    | system used by the application. Typically, Eloquent is utilized.
    |
    | If you have multiple user tables or models you may configure multiple
    | providers to represent the model / table. These providers may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => env('AUTH_MODEL', App\Models\User::class),
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | These configuration options specify the behavior of Laravel's password
    | reset functionality, including the table utilized for token storage
    | and the user provider that is invoked to actually retrieve users.
    |
    | The expiry time is the number of minutes that each reset token will be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    | The throttle setting is the number of seconds a user must wait before
    | generating more password reset tokens. This prevents the user from
    | quickly generating a very large amount of password reset tokens.
    |
    */

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'),
            'expire' => 60,
            'throttle' => 60,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Password Confirmation Timeout
    |--------------------------------------------------------------------------
    |
    | Here you may define the number of seconds before a password confirmation
    | window expires and users are asked to re-enter their password via the
    | confirmation screen. By default, the timeout lasts for three hours.
    |
    */

    'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800),

];
<?php

use Laravel\Fortify\Features;

return [

    /*
    |--------------------------------------------------------------------------
    | Fortify Guard
    |--------------------------------------------------------------------------
    |
    | Here you may specify which authentication guard Fortify will use while
    | authenticating users. This value should correspond with one of your
    | guards that is already present in your "auth" configuration file.
    |
    */

    'guard' => 'web',

    /*
    |--------------------------------------------------------------------------
    | Fortify Password Broker
    |--------------------------------------------------------------------------
    |
    | Here you may specify which password broker Fortify can use when a user
    | is resetting their password. This configured value should match one
    | of your password brokers setup in your "auth" configuration file.
    |
    */

    'passwords' => 'users',

    /*
    |--------------------------------------------------------------------------
    | Username / Email
    |--------------------------------------------------------------------------
    |
    | This value defines which model attribute should be considered as your
    | application's "username" field. Typically, this might be the email
    | address of the users but you are free to change this value here.
    |
    | Out of the box, Fortify expects forgot password and reset password
    | requests to have a field named 'email'. If the application uses
    | another name for the field you may define it below as needed.
    |
    */

    'username' => 'email',

    'email' => 'email',

    /*
    |--------------------------------------------------------------------------
    | Lowercase Usernames
    |--------------------------------------------------------------------------
    |
    | This value defines whether usernames should be lowercased before saving
    | them in the database, as some database system string fields are case
    | sensitive. You may disable this for your application if necessary.
    |
    */

    'lowercase_usernames' => true,

    /*
    |--------------------------------------------------------------------------
    | Home Path
    |--------------------------------------------------------------------------
    |
    | Here you may configure the path where users will get redirected during
    | authentication or password reset when the operations are successful
    | and the user is authenticated. You are free to change this value.
    |
    */

    'home' => '/dashboard',

    /*
    |--------------------------------------------------------------------------
    | Fortify Routes Prefix / Subdomain
    |--------------------------------------------------------------------------
    |
    | Here you may specify which prefix Fortify will assign to all the routes
    | that it registers with the application. If necessary, you may change
    | subdomain under which all of the Fortify routes will be available.
    |
    */

    'prefix' => '',

    'domain' => null,

    /*
    |--------------------------------------------------------------------------
    | Fortify Routes Middleware
    |--------------------------------------------------------------------------
    |
    | Here you may specify which middleware Fortify will assign to the routes
    | that it registers with the application. If necessary, you may change
    | these middleware but typically this provided default is preferred.
    |
    */

    'middleware' => ['web'],

    /*
    |--------------------------------------------------------------------------
    | Rate Limiting
    |--------------------------------------------------------------------------
    |
    | By default, Fortify will throttle logins to five requests per minute for
    | every email and IP address combination. However, if you would like to
    | specify a custom rate limiter to call then you may specify it here.
    |
    */

    'limiters' => [
        'login' => 'login',
        'two-factor' => 'two-factor',
    ],

    /*
    |--------------------------------------------------------------------------
    | Register View Routes
    |--------------------------------------------------------------------------
    |
    | Here you may specify if the routes returning views should be disabled as
    | you may not need them when building your own application. This may be
    | especially true if you're writing a custom single-page application.
    |
    */

    'views' => true,

    /*
    |--------------------------------------------------------------------------
    | Features
    |--------------------------------------------------------------------------
    |
    | Some of the Fortify features are optional. You may disable the features
    | by removing them from this array. You're free to only remove some of
    | these features, or you can even remove all of these if you need to.
    |
    */

    'features' => [
        Features::registration(),
        Features::resetPasswords(),
        Features::emailVerification(),
        Features::twoFactorAuthentication([
            'confirm' => true,
            'confirmPassword' => true,
            // 'window' => 0
        ]),
    ],

];
<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware): void {
        //
    })
    ->withExceptions(function (Exceptions $exceptions): void {
        //
    })->create();
<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Str;
use Laravel\Fortify\TwoFactorAuthenticatable;

class User extends Authenticatable
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable, TwoFactorAuthenticatable;

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var list<string>
     */
    protected $hidden = [
        'password',
        'two_factor_secret',
        'two_factor_recovery_codes',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }

    /**
     * Get the user's initials
     */
    public function initials(): string
    {
        return Str::of($this->name)
            ->explode(' ')
            ->take(2)
            ->map(fn ($word) => Str::substr($word, 0, 1))
            ->implode('');
    }
}