35

I am trying to get Laravel 5 (5.1.31) to return a http status response of 404 when a page is not found. I have tried several things and it always returns 200.

In my controller I have this:

else
   {
   header('HTTP/1.0 404 Not Found');
   return view('errors.404);
   }

I have also tried:

else
   {
   http_response_code(404);
   return view('errors.404);
   }

and

else
   {
   abort(404, 'Page not found');
   }

I also tried putting this in the 404.blade

@inject( 'response', 'Illuminate\Http\Response' )
{{ $response->status(404) }}

No success. No matter what I try, Laravel returns 200. How do I get it to return 404?

Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145
Dan Willett
  • 945
  • 2
  • 10
  • 20
  • https://laravel.com/docs/5.1/errors . Where do you see the code 200? In the developer toolbar? – Angelin Calu Mar 05 '17 at 21:30
  • In the browser when I am loading the page, laravel returns 200 for the status code. I need it to return 404 for page not found, this is especially important for the search engine spiders so that they know when they have reached a bad address. – Dan Willett Mar 05 '17 at 22:05
  • `abort(404)` should work. Is the else part of your if statement definitely getting executed? – Rwd Mar 05 '17 at 23:13
  • It is definitely executing the abort(404,"message") as it displays the message on the 404 page, however it is still sending a 200 status code to the browser. – Dan Willett Mar 06 '17 at 14:57

7 Answers7

81

you may use the abort helper:

abort(404);
风声猎猎
  • 1,065
  • 1
  • 7
  • 9
  • 1
    No, it MUST NOT BE the accepted answer. This answer not only doesn't address the question, it shows the person answering didn't read the question, because that non-solution is already addressed in the question. In short, the answer does not work, and if the person who wrote that answer would have read the question, they would have known it doesn't work. – Dan Willett Jul 07 '21 at 15:30
  • @DanWillett don't be so salty mate. as a random user coming from "google: laravel return 404 view" this answere is totally valid. could not care less about some $data variable. classical case of "what's good for me vs. what's good for everybody else" – clockw0rk Feb 28 '23 at 01:22
  • and hint: i did never say "answere is correct" i only said "don't be so salty" – clockw0rk Feb 28 '23 at 01:26
  • @clockw0rk I am glad you found the information you were looking for. I would point out that the $data is not the part that addresses the core issue raised by the original question. The core issue, which many people apparently have a hard time understanding is that the response being returned to the browser / web spider was returning a status code of 200 success instead of the correct 404 error in the header which was causing search engines to index non-existent pages instead of correctly recognizing that the URL was invalid by it correctly returning a 404 error code in the header. – Dan Willett Mar 01 '23 at 21:54
27

While I don't know why abort is not returning the 404 status as it is suppose to, I did find a solution that will make Laravel return a 404 status:

Here is what I did:

else {
    $data['title'] = '404';
    $data['name'] = 'Page not found';
    return response()->view('errors.404',$data,404);
}

This actually works better for my purposes because it doesn't mess with the contents of my 404.blade like the abort does.

Sebastian Viereck
  • 5,455
  • 53
  • 53
Dan Willett
  • 945
  • 2
  • 10
  • 20
17

Very simple, I assumed you use Laravel v5++ just go to

app > Exceptions > Handler.php

See the picture as below:

enter image description here

And modify the codes from:

public function render($request, Exception $e)
{
    return parent::render($request, $e);
}

to

public function render($request, Exception $e)
{
    if ($e instanceof MethodNotAllowedHttpException)
    {
        abort(404);
    }
    return parent::render($request, $e);
}

Then, do not forget to add 404.blade.php page in errors folder:

enter image description here

Well, you can customise by yourself the 404 page in 404.blade.php.


Note

This case only when you run the URL were not listed as in the routes. You may find in web.php file.

In case you need to call by custom, just call in the controller like below:

public function show_me()
{
   abort(404);  //404 page
}

Hope it helps!

Nere
  • 4,097
  • 5
  • 31
  • 71
  • 2
    Already have the /errors/404.blade.php. Have already tried using the abort(404) in my controller. It is returning the correct 404 blade, but it is still sending status code 200 to the browser instead of the correct 404 error code. You may wish to read the entire question as all of this information is in the original question as well as to what version of Laravel I am running... – Dan Willett Mar 06 '17 at 14:58
3

If you want to return JSON instead of a view, you can call this in your controller:

return response(['error'=>true,'error-msg'=>$msg],404);
nicomonjelat
  • 167
  • 1
  • 10
3

If you have a 404 page under resources/views/errors/ then just do a

return view('errors.404');

or like 风声猎猎 suggests

abort(404);
Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145
  • This is a repeat of other answers above that do not accomplish the needed result. You should read the other answers and avoid creating a duplicate answer. – Dan Willett May 18 '21 at 15:26
  • @DanWillett where do you see this part «404 page under resources/views/errors/ » in the others? also «do not accomplish the needed result» is wrong because the link I've provided to my other answer you can see that working :) – Tiago Martins Peres May 18 '21 at 15:43
  • Actually it is in the question itself. Perhaps you didn't fully read the question and see what the problem was and what had already been tried, which included what you have in your answer, which doesn't solve the problem, which is that while the error page was displayed, the status code being returned in the header to the browser was 200 - success instead of the correct 404 - page not found. – Dan Willett Jul 07 '21 at 15:25
  • @DanWillett where exactly do you mention «If you have a 404 page under resources/views/errors/ then just do a...»? In your question you just point to the line of codes, not existence of a file in a precise folder, let alone with visuals from that. – Tiago Martins Peres Jul 07 '21 at 22:57
  • to quote "It is definitely executing the abort(404,"message") as it displays the message on the 404 page, however it is still sending a 200 status code to the browser." --- notice where I said "the 404 page", The issue was not whether or not it was displaying the 404 page, it was that it was sending a 200 success code in the header while displaying the 404 page, which is what search engines rely on to determine whether the page address is good or not. – Dan Willett Aug 06 '21 at 15:02
0

This is what I did because I needed to use my custom view and a 404 header:

return response()
            ->view('my_view', $data, 404);

I found it on https://laravel.com/docs/8.x/responses#view-responses

It worked in Laravel 8, but it seems that it works in older versions.

Luis Rodriguez
  • 355
  • 3
  • 7
0

You can also do this

return response(view('view_name'), 404);

You can also add headers to the response like this

return response(view('view_name'), 404, [
    'header_1' => 'header 1 value',
    'header_2' => 'header 2 value' ...
]);

Extra info

The thing is that it works both on Laravel and Lumen (micro framework by Laravel). However,

response()->view() 

doesn't work on Lumen.

Koushik Das
  • 9,678
  • 3
  • 51
  • 50