People searching “Laravel restore soft delete” call restore() on a normal route and get a 404. The row is deleted, so binding cannot see it. Opt in on that route only.
TL;DR
- The restore route uses withTrashed() or the binding 404s before your controller runs.
- Do not turn
withTrashed()on for the whole route group. - Do not restore in the browser by clearing
deleted_aton the prop.
The fix#
Route::post('/posts/{post}/restore', [PostController::class, 'restore'])
->withTrashed()
->middleware('auth')
->name('posts.restore');public function restore(Post $post): RedirectResponse
{
$this->authorize('restore', $post);
$post->restore();
return back();
}The Vue button posts to that URL. It sits on the trash list, which used onlyTrashed(). A normal edit form should not offer restore.
What to avoid#
Gotcha
Do not turn withTrashed() on for the whole route group. Edit and update would start opening deleted posts. Do not restore in the browser by clearing deleted_at on the prop. The column is not yours to edit from the page.
FAQ#
How do I restore a soft-deleted row from Vue?
The restore route uses withTrashed() or the binding 404s before your controller runs.
What goes wrong with Laravel restore soft delete?
Many developers call restore() on a normal route and get a 404. Do not turn withTrashed() on for the whole route group.



