Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Fortify Ui Laravel Package

zacksmash/fortify-ui

A ready-made UI layer for Laravel Fortify, adding Blade views and components for login, registration, password reset, email verification, and two-factor authentication so you can scaffold secure auth screens without building them from scratch.

View on GitHub
Deep Wiki
Context7

Getting Started

Fortify UI is a Blade/Tailwind view layer for Laravel Fortify — Fortify gives you the headless authentication backend (routes, actions, 2FA endpoints), and this package supplies the screens so you don't hand-roll login, registration, password reset, email verification, and two-factor setup.

Minimal path:

  1. composer require zacksmash/fortify-ui (Laravel Fortify should already be installed and its FortifyServiceProvider registered — this package builds on it, it doesn't replace it).
  2. Run the installer: php artisan fortify-ui:install. This publishes the auth views (typically into resources/views/auth), plus supporting config/routes depending on your chosen options.
  3. Enable the Fortify features you want in config/fortify.php — registration, resetPasswords, emailVerification, updateProfileInformation, and twoFactorAuthentication. If you enable 2FA, add the two_factor_secret, two_factor_recovery_codes, and two_factor_confirmed_at columns to users and migrate.
  4. npm install && npm run dev so Tailwind picks up the published views.

First use case: confirm the login/register screens render at /login and /register, then walk the 2FA enrollment flow at /user/two-factor-authentication — enable, scan the QR, and submit a code from your authenticator. On v2.0.2 that flow now includes the confirmation step (see Gotchas), which is the single most useful smoke test of this release.

Implementation Patterns

Treat Fortify as the backend, this package as the frontend. Every form posts to Fortify's named routes; the views are just markup. When you need to change behaviour (extra validation, custom user creation), edit the Fortify action classes in app/Actions/Fortify/ rather than the Blade files.

Publish-then-own the views. The normal workflow is to publish once and customise resources/views/auth/* to match your design system. Keep a note of the package version you published from — this is the main source of drift (see Gotchas).

The 2FA flow is a two-phase state machine. Enabling 2FA generates a secret and QR code but the account is not "confirmed" until the user submits a valid TOTP code back to the confirmation endpoint. In Blade terms:

  • POST /user/two-factor-authentication — enable, generates secret
  • GET /user/two-factor-qr-code — JSON payload for the QR (fetch with credentials so the session cookie is sent)
  • POST /user/confirmed-two-factor-authentication — the confirmation step fixed in v2.0.2
  • GET /user/two-factor-recovery-codes — recovery codes, regenerable via POST

Gate anything sensitive behind the password.confirm middleware, and use verified on routes that require a confirmed email.

Configure confirmation explicitly. In config/fortify.php, the 2FA feature array needs 'confirm' => true for the confirmation step to be enforced, and 'confirmPassword' => true if you want password re-entry before enabling/disabling. Without confirm, the newly-fixed confirmation view is effectively unreachable and 2FA presents as active the moment it's enabled.

Testing. Feature-test the enrollment path end to end: enable, assert the secret is set, POST a valid TOTP to the confirmation endpoint, assert two_factor_confirmed_at is populated — then assert a protected route still challenges before confirmation and passes after. Fortify ships helpers for generating valid codes in tests; use those rather than freezing time and hardcoding digits.

Don't mix scaffolds. If Breeze or Jetstream is also installed, you'll get duplicate route names and competing auth views. Pick one authentication UI per application.

Gotchas and Tips

Published views don't receive package updates — this is the critical one for v2.0.2. The fix for the missing 2FA confirmation step lives in the package's shipped Blade files. If you published views on v2.0.1 or earlier, upgrading the composer package changes nothing on screen: your app still owns stale copies of the 2FA templates. After upgrading, diff the package's views against your published ones (vendor/zacksmash/fortify-ui/resources/views) and port the confirmation-step markup across manually. Any team that published and edited these files is silently still vulnerable to the bug this release fixes.

Symptom of the bug this release fixes: users can enable 2FA, the UI redirects or re-renders as though setup succeeded, but two_factor_confirmed_at stays null — so twoFactorAuthenticationConfirmed() is false and the account is in a half-enrolled state that can lock users out of recovery codes. If you see reports of "2FA is on but I never got recovery codes," check your published views before anything else.

Missing columns fail quietly-ish. If two_factor_confirmed_at doesn't exist, confirmation writes go nowhere and Fortify's confirmation check never passes. Verify the migration ran rather than assuming a silent success.

Stale caches after publishing. Run php artisan config:clear and php artisan view:clear after install/upgrade; a cached fortify config will keep the old feature flags and make you think the confirmation option "doesn't work."

Tailwind purging. If you don't publish views and render them from the vendor path, your content globs must include ./vendor/zacksmash/fortify-ui/resources/views/**/*.blade.php or the auth screens ship unstyled in production while looking fine in dev.

QR code fetching is session-dependent. The QR endpoint is an authenticated JSON route; a plain fetch without credentials: 'include' or a missing CSRF header returns 401/419 and the modal appears blank. Inspect the network tab before blaming the package.

Extension points worth knowing: Fortify's view-binding methods (Fortify::loginView(), registerView(), etc.) and per-feature config in config/fortify.php let you point at your own templates without forking. Rate limiting lives in FortifyServiceProvider's configureRateLimiting(); redirects after login live in LoginResponse/TwoFactorLoginResponse. None of these require touching published views.

Debugging shortcut: php artisan route:list --path=user/two-factor quickly shows whether the confirmation route is registered and which middleware guards it — the fastest way to distinguish "Fortify misconfigured" from "my template is stale."

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle