Disabling user registration in Laravel used to be a one-liner.
Working on a Laravel app from before Laravel 8?
The oldAuth::routes(['register' => false])one-liner still works — see our original 2018 guide. For modern Laravel with Fortify, read on.
Since then, Laravel Fortify replaced the old Auth::routes() scaffolding, and the new starter kits with Inertia use Wayfinder for type-safe routing on the frontend. This gives us a lot more power — but also a gotcha or two.
Let's walk through the scenarios we encounter most often.
Disabling Registration in Fortify
This is the most common case. Your Laravel app uses Fortify and you don't need public registration.
The official docs advise you to comment out the feature Features::registration():
// in config/fortify.php
'features' => [
// Features::registration(),
Features::resetPasswords(),
Features::emailVerification(),
Features::twoFactorAuthentication([
'confirm' => true,
'confirmPassword' => true,
]),
],
On the backend, this is all you need. Fortify stops registering the /register route, and the canRegister prop your views receive will evaluate to false. No route, no registration. Clean.
The Wayfinder Gotcha
If you're using one of Laravel's starter kits with Inertia (React or Vue), your frontend imports route helpers generated by Wayfinder.
When you disable Features::registration(), the generated route for /register disappears, and any file that imports it directly fails to build:
Build failed with 1 error:
[UNLOADABLE_DEPENDENCY] Error: Could not load ../../../../../../../resources/js/routes/register
╭─[ resources/js/pages/auth/register.tsx:11:23 ]
│
11 │ import { store } from "@/routes/register";
│ ─────────┬─────────
│ ╰─────────── No such file or directory (os error 2)
From the Laravel docs:
When using the React, Svelte or Vue starter kits, you will also need to remove any references to the disabled feature's routes in your frontend code. For example, if you disable email verification, you should remove the imports and references to the verification routes in your React, Svelte, or Vue components. This is necessary because these starter kits use Wayfinder for type-safe routing, which generates route definitions at build time. If you reference routes that no longer exist, your application will fail to build.
— Laravel docs
The Solution
If you've followed the above step in a fresh React starter kit, you now need to comment out the relevant imports in your frontend files.
1. resources/js/pages/welcome.tsx — remove register from the destructured import:
import { dashboard, login /* register */ } from '@/routes';
2. resources/js/pages/auth/login.tsx — comment out the whole import line:
// import { register } from '@/routes';
3. resources/js/pages/auth/register.tsx — comment out the whole import line:
// import { store } from '@/routes/register';
That's it.
Referencing Removed Symbols
The JSX in these files still references the removed symbols, but the canRegister prop is now false, so the && guards short-circuit before those references are ever evaluated.
// in resources/js/pages/welcome.tsx
{canRegister && (
<Link href={register()} className="...">
Register
</Link>
)}
With canRegister === false, JavaScript never gets to register() — the expression short-circuits at the && and React renders nothing. The orphan reference is dead code at runtime.
The Register page itself is never rendered either, since /register no longer exists.
Keeping TypeScript Happy
npm run build will pass — Vite uses esbuild, which strips types without running a full check. But tsc --noEmit and your IDE will flag the orphan reference:
Cannot find name 'register'.
The cleanest fix is a one-line stub right next to the commented import. The JSX stays completely untouched:
// import { register } from '@/routes';
const register = () => '/register';
Apply the same pattern in any file where you removed an import but left a reference behind — for example, store in auth/register.tsx. Since canRegister is false, the stubs are never called at runtime; they're only there to satisfy the type-checker.
Re-Enable Registration Later
To re-enable registration later, uncomment Features::registration() in config/fortify.php, then reverse the comments in the three frontend files. Done.
Bonus: A Skill for Your Agent
Working with an AI coding agent? Drop the snippet below into your .claude/skills/, .cursor/skills/, or equivalent skills folder and let your agent apply all of the steps above for you.
---
name: disable-laravel-fortify-registration
description: Disable public user registration in a Laravel app using Fortify with an Inertia starter kit (React or Vue), including the required Wayfinder frontend cleanup.
---
# Disable Fortify Registration
## When to Apply
Laravel + Fortify + Inertia starter kit (React or Vue) where public registration should be turned off.
## Checklist
1. In `config/fortify.php`, comment out `Features::registration()` in the `features` array.
2. In `resources/js/pages/welcome.tsx`, remove `register` from the destructured `from '@/routes'` import.
3. In `resources/js/pages/auth/login.tsx`, comment out `import { register } from '@/routes';`.
4. In `resources/js/pages/auth/register.tsx`, comment out `import { store } from '@/routes/register';`.
5. For any file that still references a removed symbol, add a one-line stub next to the commented import to satisfy TypeScript, e.g. `const register = () => '/register';`.
6. Verify the changes with `npm run build` and `npm run types:check`.
Bonus: Laravel Nova
Let's assume you have both Fortify with an Inertia starter kit and Laravel Nova in your project. Nova comes with its own login page, for example.
Do I Need to Disable Registration in Nova as Well?
Good news: Nova doesn't have a registration feature. Users are created through the Nova UI. So if you want to disable registration, you only need to do what we described above — comment out Features::registration() in Fortify and update the frontend imports. Nova is not affected.
Should I Only Use Laravel Nova for Login?
You could skip Fortify entirely — or never install a starter kit in the first place — and let Nova handle authentication on its own. This works, but only for admin-only applications with no public-facing users.
But the moment you need client-facing authentication, you'll have to retrofit Fortify onto an app that wasn't built for it. Keeping Fortify around from day one means the switch costs you nothing later.
Our Recommendation
Deactivate Laravel Nova's separate login and use Fortify as your single authentication layer.
// app/Providers/NovaServiceProvider.php
protected function routes(): void
{
// BEFORE
// Nova::routes()
// ->withAuthenticationRoutes()
// ->withPasswordResetRoutes()
// ->withoutEmailVerificationRoutes()
// ->register();
// AFTER
Nova::routes()
->withoutAuthenticationRoutes()
->withoutPasswordResetRoutes()
->withoutEmailVerificationRoutes()
->register();
}
Wrapping Up
What used to be a one-liner now takes a few coordinated changes — but we get type-safe routes, independent feature control per surface, and a clean separation between the main app and the admin panel in return.

