People searching “Inertia router.post” use it for every button, including forms that need errors. router.post is for a click that has no fields: publish, archive, log out.
TL;DR
- router.post sends one action that has no fields.
- useForm is the right call when the user is typing.
- Do not send a logout through
router.get. - Do not add Vue Router’s
pushafterrouter.post.
The fix#
<script setup lang="ts">
import { router } from "@inertiajs/vue3";
function publish(id: number) {
router.post(`/posts/${id}/publish`, {}, { preserveScroll: true });
}
</script>The second argument is the body. An empty object is a POST with no fields. The Laravel route still has to be post, and the controller still checks the policy.
When the user typed a title, use useForm so form.errors.title exists. router.post does not give you that object. You would be reading errors off the page props by hand.
What to avoid#
Gotcha
Do not send a logout through router.get. Logout is a POST so a random page cannot log the user out with an image. Do not add Vue Router’s push after router.post. Inertia follows the redirect the controller returns.
FAQ#
How do I post from Vue with router.post?
router.post sends one action that has no fields. useForm is the right call when the user is typing.
What goes wrong with Inertia router.post?
Many developers use it for every button, including forms that need errors. Do not send a logout through router.get.



