Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

theUnforgiven's avatar

Livewire. What am I missing....?

Hi all,

Happy Friday!

I have a Jetstream install and have setup a couple of routes:

Route::middleware(['verified'])->prefix('tasks')->group(function () {
    Route::get('', [Tasks::class, 'render']);
    Route::get('create', [AddTask::class, 'render']);
});

Pointing to two different Livewire classes. So the index page showing tasks works and navigating to the create page works, however when trying to submit the form it doesn't work...So what am I missing?

class AddTask extends Component
{
    public $task = '';
    public $alerts = '';

    protected $rules = [
        'body' => 'required',
        'alerts' => 'required',
    ];

    public function render()
    {
        return view('livewire.add-task');
    }

    public function save()
    {
        dd('testing');
    }
}

Then the form I have:

<form wire:submit.prevent="save">
                <div class="px-4 py-5 bg-white sm:p-6">
                    <div class="col-span-12 sm:col-span-6">
                        <x-jet-label for="current_password" value="Task" />
                        <x-form-input type="textarea" wire:model="task" class="mt-1 block w-full" />
                        @error('body') <span class="text-red-700">Task field is required</span> @enderror
                    </div>

                    <div class="col-span-12 sm:col-span-6 mt-2">
                        <x-jet-label for="current_password" value="Do you want alerting?" />
                        <div class="relative">
                            <select wire:model="alerts" class="mt-1 block appearance-none w-full border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500" id="grid-state">
                                <option value="">Please select</option>
                                <option>Yes</option>
                                <option>No</option>
                            </select>
                            <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
                            <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/></svg>
                            </div>
                        </div>
                        @error('alerts') <span class="text-red-700">Do you want an alert?</span> @enderror
                    </div>
                </div>

                <div class="flex items-center justify-end px-4 py-3 bg-gray-50 text-right sm:px-6">
                     <button type="submit" class="inline-flex justify-center py-2 px-4 border border-transparent text-sm leading-5 font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo active:bg-indigo-700 transition duration-150 ease-in-out">
                        Save
                    </button>
                </div>
        </form>

Put it doesn't submit to see the dd() and just adds a ? to the end of the URL tasks/create?

What am I missing here?

0 likes
42 replies
Sinnbeck's avatar

Yes but I assume that you have the component inserted somewhere?

<livewire:add-task />
theUnforgiven's avatar

I can see the form, it's not just submitting to the method on the class for some reason.

Sinnbeck's avatar

I assume that the form is inside add-task.blade.php and that you are including it like I mentioned above, somewhere? Can you show that piece of code (where you add it)

theUnforgiven's avatar

add-task.blade.php in side of resources/views/livewire

<x-app-layout>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 leading-tight">
            Create task
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
            <div class="shadow overflow-hidden sm:rounded-md">
             <form wire:submit.prevent="addTask">
                <div class="px-4 py-5 bg-white sm:p-6">
                    <div class="col-span-12 sm:col-span-6">
                        <x-jet-label for="current_password" value="Task" />
                        <x-form-input type="textarea" wire:model="task" class="mt-1 block w-full" />
                        @error('body') <span class="text-red-700">Task field is required</span> @enderror
                    </div>

                    <div class="col-span-12 sm:col-span-6 mt-2">
                        <x-jet-label for="current_password" value="Do you want alerting?" />
                        <div class="relative">
                            <select wire:model="alerts" class="mt-1 block appearance-none w-full border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500" id="grid-state">
                                <option value="">Please select</option>
                                <option>Yes</option>
                                <option>No</option>
                            </select>
                            <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
                            <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/></svg>
                            </div>
                        </div>
                        @error('alerts') <span class="text-red-700">Do you want an alert?</span> @enderror
                    </div>
                </div>

                <div class="flex items-center justify-end px-4 py-3 bg-gray-50 text-right sm:px-6">
                     <button type="submit" class="inline-flex justify-center py-2 px-4 border border-transparent text-sm leading-5 font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo active:bg-indigo-700 transition duration-150 ease-in-out">
                        Save
                    </button>
                </div>
                </form>
            </div>
        </div>
    </div>

</x-app-layout>

theUnforgiven's avatar

When I created it via terminal:

 php artisan livewire:make AddTask
 COMPONENT CREATED  🤙

CLASS: app/Http/Livewire/AddTask.php
VIEW:  resources/views/livewire/add-task.blade.php

So I just presumed I could put all the html in that blade and would then look to the method called on the wire:submit

theUnforgiven's avatar

Nope, the scripts and css are include with Jetstream on the layout

Sinnbeck's avatar

Try changing your syntax to how the docs does it for livewire

Route::get('create', AddTask::class);
theUnforgiven's avatar

Invalid route action: [App\Http\Controllers\App\Http\Livewire\AddTask] again I've tried changing routes and still nothing. I thought Livewire was suppose to be easy lol

Sinnbeck's avatar

I started learning it this morning :)

You seem to be importing the wrong thing.

Should be \App\Http\Livewire\AddTask::class

Route::get('create', \App\Http\Livewire\AddTask::class);
1 like
theUnforgiven's avatar

Still the same error, and I have it imported in the web.php file anyhow.

Sinnbeck's avatar

Can you show the content of your web.php file?

theUnforgiven's avatar
use App\Http\Livewire\AddTask;
use App\Http\Livewire\Tasks;
use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

Route::middleware(['verified'])->get('/dashboard', function () {
    return view('dashboard');
})->name('dashboard');


Route::middleware(['verified'])->prefix('tasks')->group(function () {
    Route::get('/', [Tasks::class, 'render']); // To show livewire classes...
    Route::get('create', AddTask::class);
});
Sinnbeck's avatar

Works perfectly here.

Can you try removing everything around the form from you code (so its just the code in the original example)

Sinnbeck's avatar

Yeah. You can set the layout you wish to use in the component


public function render()
    {
        return view('livewire.add-task')->layout('layouts.app-layout');
    }
theUnforgiven's avatar

The page and form are rendering, so I don't think that is the problem. Not sure what it is tbh

Sinnbeck's avatar

Me neither. I added the files using the make:livewire command, and copy pasted your code (minus the jetsteam components). And my web.php is the same as yours..

https://i.imgur.com/GPVQ2rL.png

This is my layouts/app.blade.php file

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        @livewireStyles

    </head>
    <body>

        {{ $slot }}
        @livewireScripts
    </body>
</html>

theUnforgiven's avatar

Guess it's some JetStream stuff then, oh well nevermind I'll stick to what I know. Thanks for trying to help buddy :)

Snapey's avatar

You can use the livewire classes as;

Route::middleware(['verified'])->prefix('tasks')->group(function () {
    Route::get('', Tasks::class);
    Route::get('create', AddTask::class);
});

You have changed the form submit to addTask? Have you changed it in the component also?

theUnforgiven's avatar

Yes, i just wondered if it was the naming of it, so was toying around with different names but makes no difference the form doesn't get submitted at all.

Snapey's avatar

don't include <x-app-layout> in your component view. Wrap the component in a single div.

<div>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 leading-tight">
            Create task
        </h2>
    </x-slot>

    <div class="py-12">

    </div>
</div>

theUnforgiven's avatar

I still get Invalid route action: [App\Http\Controllers\App\Http\Livewire\Tasks].

When using:

Route::middleware(['verified'])->prefix('tasks')->group(function () {
    Route::get('', Tasks::class);
    Route::get('create', AddTask::class);
});
Next

Please or to participate in this conversation.