@method

Emits the hidden _method field that spoofs PUT, PATCH and DELETE from an HTML form.

Signature
@method('PUT')

Parameters

ParameterTypeDescription
$methodstringThe HTTP verb to spoof, such as PUT, PATCH or DELETE. Case-insensitive; Laravel uppercases it.

Return value

stringA hidden input named _method carrying the given verb — equivalent to the method_field() helper.

Errors

Never throws — an unrecognised verb simply produces a request no route matches, surfacing as a 405 Method Not Allowed.

HTML forms can only issue GET and POST. @method('PUT') writes a hidden _method field that Laravel reads while building the request, so a route registered with Route::put() or Route::delete() matches.

How to use it

The form's own method attribute stays POST. The directive goes inside the form, next to @csrf — spoofed verbs are still session-authenticated requests and still need the token.

What trips people up

Spoofing only applies to POST submissions. Put @method('DELETE') in a method="GET" form and the field travels as a harmless query parameter while the request stays a GET, producing a 405 or a match against the wrong route.

It also does nothing for fetch or Axios calls: JavaScript can send a real DELETE, so set the verb on the request instead of sending _method.

And a delete triggered from a link cannot work — an anchor issues a GET. The usual pattern is a one-button form, or a small JavaScript handler that submits a hidden form.

Route::resource generates PUT/PATCH update and DELETE destroy routes, so nearly every resourceful form needs this directive.

Example

Example · php
<?php

// resources/views/orders/edit.blade.php
$form = <<<'BLADE'
<form action="/orders/1" method="POST">
    @csrf
    @method('PUT')

    <input type="text" name="reference" value="{{ $order->reference }}">
    <button type="submit">Update</button>
</form>
BLADE;

// @method compiles to a call to the method_field() helper:
echo method_field('PUT');
// <input type="hidden" name="_method" value="PUT">

When to use it

  • Submit an edit form to a Route::put update action
  • Delete a record from a one-button form inside a table row
  • Send a PATCH from a settings form that updates a single field

Frequently asked questions

How do I send a DELETE request from an HTML form in Laravel?

Set the form's method to POST and add @method('DELETE') inside it, along with @csrf. Blade emits a hidden _method field that Laravel reads when resolving the request verb.

Does @method work on a GET form?

No. Method spoofing is only honoured for POST submissions; on a GET form the _method field is sent as an ordinary query parameter and the request remains a GET.

What is the difference between @method('PUT') and @method('PATCH')?

They spoof different verbs and match different routes: PUT for a full replacement of the resource, PATCH for a partial update. Route::resource registers the update action for both, so either works there.

More examples

Deleting from a table row

Each row carries its own POST form because a link cannot issue a DELETE. Both directives are required: @method makes the route match, and @csrf keeps the middleware from rejecting the submission with a 419 before the verb is ever considered.

Example · php
<?php

// routes/web.php
Route::delete('/orders/{order}', [OrderController::class, 'destroy'])
    ->name('orders.destroy');

// resources/views/orders/index.blade.php
$row = <<<'BLADE'
@foreach ($orders as $order)
    <tr>
        <td>{{ $order->number }}</td>
        <td>
            <form action="{{ route('orders.destroy', $order) }}" method="POST">
                @csrf
                @method('DELETE')

                <button type="submit">Delete</button>
            </form>
        </td>
    </tr>
@endforeach
BLADE;

echo view('orders.index', ['orders' => $orders])->render();

The verbs a resource controller expects

Only store needs no spoofing, because a POST form already sends POST. Update and destroy both do. PATCH is accepted for update as well, which is the verb to use when the form submits a subset of the model's fields.

Example · php
<?php

// Route::resource('photos', PhotoController::class) registers:
// GET    /photos             index
// GET    /photos/create      create
// POST   /photos             store       -> @csrf only
// GET    /photos/{photo}     show
// GET    /photos/{photo}/edit edit
// PUT    /photos/{photo}     update      -> @csrf + @method('PUT')
// DELETE /photos/{photo}     destroy     -> @csrf + @method('DELETE')

$create = <<<'BLADE'
<form action="{{ route('photos.store') }}" method="POST">
    @csrf
</form>
BLADE;

$update = <<<'BLADE'
<form action="{{ route('photos.update', $photo) }}" method="POST">
    @csrf
    @method('PUT')
</form>
BLADE;

echo $update;

JavaScript does not need it

Spoofing exists because HTML forms are limited to GET and POST; XMLHttpRequest and fetch are not. Sending a real DELETE keeps the route matching, the middleware and any HTTP cache in agreement, and avoids a body parameter that has to survive every proxy in between.

Example · php
<?php

// Wrong: sending _method from fetch when the verb can be set directly.
$wrong = <<<'JS'
fetch('/orders/1', {
    method: 'POST',
    body: new URLSearchParams({ _method: 'DELETE' }),
});
JS;

// Right: send the real verb, plus the token header.
$right = <<<'JS'
fetch('/orders/1', {
    method: 'DELETE',
    headers: {
        'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
    },
});
JS;

echo $right;

Discussion

  • Be the first to comment on this lesson.