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

< GDB >'s avatar

Named route > works differently than expected > What am I missing?

I sadly found out that my understanding of routing is still not complete. When I do this :

web.php

					use App\Http\Controllers\TestController;
// Company page
	Route::get('/test', [TestController::class, 'index'])->name('test.index');

controller.php

public function index(){
	return view('test.index');
}

This return an error

		view [test] not found

If I change like this :

web.php

					use App\Http\Controllers\TestController;
// Company page
	Route::get('/test.index', [TestController::class, 'index'])->name('test.index');

view is returned..

What am I not understanding in order to use the above (first route)?

0 likes
34 replies
tykus's avatar

The name of a route, and the name of a view are not the same thing. You have explicitly defined a route called test.index, it does not follow that you will have a view with the same name.

The expectation for the following erxpression:

return view('test.index');

is a view template exists resources/views/test/index.blade.php - test being a subdirectory under the default views directory, and index being a Blade template whose filename is index.blade.php

1 like
< GDB >'s avatar

@tykus Not sure if I understand you.

You have explicitly defined a route called test.index, it does not follow that you will have a view with the same name

Only when I give both the same naming it works

return view('test.index');

yes, my index file is found in resources>views>test>index.blade.php

tykus's avatar

I explain below how test.index route name allows using the route() helper method - there is no correlation between the route name and the view template it may return. Indeed the route name is entirely optional.

1 like
MichalOravec's avatar
php artisan route:clear

www.example.com/test this url you have to visit for the first option

1 like
< GDB >'s avatar

@michaloravec

Did not help to clear cache.

yes, I understand or my goal is indeed that the url would be example.com/test (-> view test.index is shown)

Hence why I thought get('/test) and name('test.index') would get the job done.

tykus's avatar

Naming a route allows you to use route helper method(s) to get a URL:

route('test.index') // http://www.example.com/test

Wherever you return a view, using a similar syntax it translates to the filesystem location of the view template as I described above. If it is easier to grok, you could use a slash over a dot:

return view('test/index');
1 like
< GDB >'s avatar

I'm so sorry @tykus, I really want to understand what you mean and it's probably an easy thing too, but frustratingly I still don't understand :-|

This is how i understood / thought it was:

Route::get('/test.index', [TestController::class, 'index'])->name('bananas');

In the Route::get part I have to define the file location, in this case :

resources>views>test>index.blade.php

The nice thing of giving it a name ('bananas' just to change example from test.index) is to avoid having to change all hard coded routes if I would ever change the directory name/location/...

As long as i follow this method, everything works fine (hence why I'm so convinced i understood perfectly).

HOWEVER, my route name / url is example.com/test.index NOT example.com/test

So I looked at a earlier project from laravel from scratch course and I have this :

//Route to articlespage (all articles) - 2 ways string syntax and php syntax
                    // PHP Syntax
Route::get('/articles', [ArticlesController::class, 'index'])->name('articles.index'); 

This works and has url example.com/articles but directory is also resources>views>articles>index.blade.php

So now I'm really confused why it's not working for me in this case :

Route::get('/test', [TestController::class, 'index'])->name('bananas');

shouldn't the routehelper function see class, 'index' and know that it is referring to the index.blade.php file in the test folder?

tykus's avatar

The route name can be anything or not even defined - it is not relevant to the template path. Don't confuse the route name with the route URI; they are not the same thing; the route name is a convenience for us developers - the browser can do nothing with it.

shouldn't the routehelper function see class, 'index' and know that it is referring to the index.blade.php file in the test folder

No! The index in that case refers the the action in the controller - your TestController has an index method.

There is a different Route method called view which would do something like you are describing:

Route::view('test', 'test.index');

In this case, test.index is the view template location.

1 like
< GDB >'s avatar

@tykus

The route name can be anything or not even defined - it is not relevant to the template path. Don't confuse the route name with the route URI; they are not the same thing; the route name is a convenience for us developers - the browser can do nothing with it.

Yes, it's optional, can be anything, doesn't matter.

No! The index in that case refers the the action in the controller - your TestController has an index method.

Sorry, yes it looks at the index function in controller and returns the view given in that method.

But can you please explain me why this works :

//Route to articlespage (all articles) - 2 ways string syntax and php syntax
                    			// PHP Syntax
Route::get('/articles', [ArticlesController::class, 'index']); 

But this doesn't:

                    			// PHP Syntax
					use App\Http\Controllers\TestController;
Route::get('/test', [TestController::class, 'index']);
tykus's avatar

What does ArticleController look like?

1 like
< GDB >'s avatar

@tykus

ArticleController:

  public function index(){
    	//If tag is in url -> only show articles with that tag
   		 if(request('tag')){
        		$articles = Tag::where('name', request('tag'))->firstOrFail()->articles;
    	}else {
        		//Get all articles
        		$articles = Article::latest()->get();
    }
    return view('articles.index', ['articles'=>$articles]);
tykus's avatar

Ok, so you have a view template located at resources/views/articles/index.blade.php which is returned by that index action in the ArticleController, which handles a request to http://www.example.com/articles.

If you apply the same approach to http://www.example.com/test endpoint, then you would have an index action in TestController; and that action returns a view located at resources/views/test/index.blade.php. I am assuming that (i) you have only one route defined which handles the /test URI (and it is the route you have shown) (ii) your routes are not cached - clear them if they are. If all of the above is true, and there is still an issue, then please share the stacktrace with the relevant error message(s).

1 like
< GDB >'s avatar

@tykus Thank you very much, here's the stacktrace error :

vendor/laravel/framework/src/Illuminate/View/FileViewFinder.php:137

short:

throw new InvalidArgumentException("View [{$name}] not found.");

long:

* @param  array  $paths

 * @return string

 *

 * @throws \InvalidArgumentException

 */

protected function findInPaths($name, $paths)

{

    foreach ((array) $paths as $path) {

        foreach ($this->getPossibleViewFiles($name) as $file) {

            if ($this->files->exists($viewPath = $path.'/'.$file)) {

                return $viewPath;

            }

        }

    }



    throw new InvalidArgumentException("View [{$name}] not found.");

}



/**

 * Get an array of possible view files.

 *

 * @param  string  $name

 * @return array

 */

protected function getPossibleViewFiles($name)

{

    return array_map(function ($extension) use ($name) {

        return str_replace('.', '/', $name).'.'.$extension;

    }, $this->extensions);

}

Additional :

- yes only 1 route (currently)
- yes controller has index function returning view
- clearing cache doesn't seem to have effect
tykus's avatar

What view is it attempting to find? What does the exception message say? If the exception is being thrown from the FileViewFinder, it would seem that the view template file you are attempting to return is not located where you are describing. Again, if you return view('test.index') this means you should have a Blade template located at resources/views/test/index.blade.php - that entire path (no typos, correct case etc.) must be correct.

< GDB >'s avatar

@tykus sorry for that this is the exception

InvalidArgumentException
	View [test] not found	

This is TestController

public function index(){
	return view('bananas')
}

This is route

use App\Http\Controllers\TestController;
Route::get('/test', [TestController::class, 'index'])->name('bananas');

This is the directory

resources/views/test/index.blade.php
automica's avatar

@gillesdeb your view represents its location in the resources folder.

so

resources/views/test/index.blade.php

would be returned as

return view('test.index')

if you want to get

view('bananas')

then you'd need a blade at

resources/views/bananas.blade.php

Routes and views may look the same but defining a route named 'foo' doesn't mean that you'd get a view called 'foo' too.

1 like
< GDB >'s avatar

@automica

But if I change only this

This is TestController

public function index(){
	return view('bananas')
}

This is route

use App\Http\Controllers\TestController;
Route::get('/test.index', [TestController::class, 'index'])->name('bananas');

This is the directory

resources/views/test/index.blade.php

It works fine

and also this : The route name can be anything or not even defined (confirmed by @tykus)

So what is so clear you guys are saying and I just don't seem to grasp

automica's avatar

@gillesdeb whats this though?

'/test.index'

surely that should just be

'/tests'

or

'/tests/index'

why the dot?

1 like
< GDB >'s avatar

@automica it's the path of directory... folder is named test and in that folder is the index.blade.php file

BTW the 'test' is just the wording that I changed, to keep it more generic (might have failed with that...)

automica's avatar

no. it isn't. the first argument in Route::get() is the url that you hit to access the route. Its nothing to do with the location of the blade file.

1 like
< GDB >'s avatar

@automica

But that is what I'm trying to say from the beginning, as soon as I fill in just /company it doesn't work. If I put /company.index it works. But you confirmed also my thought:

the first argument in Route::get() is the url that you hit to access the route

So the first argument could be anything really because the route is defined in web.php.

if i hit /company -> do this action defined in controller (f.ex. index)
if I hit /company/change -> do this action defined in controller (f.ex. edit) 

BTW I understood that "/" and "." are the same.. Next the action defined in controller is called upon this part

[CompanyController::class, 'index']

Lastly, optional, I can give a name to this route (whatever I want) to call it in my blade files to avoid having to change it if I change the first parameter in the future

->name('company');

Result :

Route::get('/company', [CompanyController::class, 'index'])->name('company');

Controller:

public function index(){

        return view('company');
    }
}

Now:

This should work right?

But it doesn't

tykus's avatar

@gillesdeb what is in RoutingController root action? I suspect that it is this route that is matching your request to /company; and maybe inferring the view location from the URI segment(s) - this is why there is a view not found which has the same name as the URI segment. To test this idea; you could comment out

// Route::get('{any}', 'RoutingController@root')->name('any');

And see if the /company URI works?

tykus's avatar

If that is the exception message, then the code you are sharing is not getting executed - nowhere is there a view named test that you have shared with us. Can you please post your full Routes file?

There must be another route definition that responds to http://www.example.com/test, so that whenever you are visiting it in your browser; it is that other logic being executed, and not the TestController code you have shared.

1 like
< GDB >'s avatar

@tykus, yes I'm more than happy to share that with you. Please note that everything with 'test' is just changed from 'company'. So instead of it being TestController it's CompanyController.

This is web.php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Auth::routes();

Route::get('/home', function () {
    return redirect(route('second', ['dashboard', 'ecommerce']));
})->middleware('auth')->name('home');

Route::group(['middleware' => 'auth', 'prefix' => '/'], function () {
    Route::get('{first}/{second}/{third}/{fourth}', 'RoutingController@fourthLevel')->name('fourth');
    Route::get('{first}/{second}/{third}', 'RoutingController@thirdLevel')->name('third');
    Route::get('{first}/{second}', 'RoutingController@secondLevel')->name('second');
    Route::get('{any}', 'RoutingController@root')->name('any');
});

// landing - homepage pre-login-registration
Route::get('', 'RoutingController@index')->name('index');

// Profile
    use App\Http\Controllers\UserController;
    //Profile show
    Route::get('/useraccount.show', [UserController::class, 'show'])->name('useraccount.show');

    //Profile edit
    Route::get('/useraccount.edit', [UserController::class, 'edit'])->name('useraccount.edit');

    //Profile Update
    Route::put('/useraccount', [UserController::class, 'update'])->name('useraccount.update');

This is the one below (prev. Test)

// Company
    use App\Http\Controllers\CompanyController;
    // Company page
    Route::get('/company', [CompanyController::class, 'index'])->name('bananas');

This is CompanyController.php (prev TestController):

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use DB;
use App\Models\Company;

class CompanyController extends Controller
{
    // INDEX
    public function index(){

        return view('bananas');
    }
}
tykus's avatar
tykus
Best Answer
Level 104

Why introduce complexity by changing the names????

Also, Route::get('{any}', 'RoutingController@root')->name('any'); is a catch-all route which will respond to http://www.example.com/company before your explicitly defined route - move it to the very bottom of your routes file.

automica's avatar

@tykus and moving that route to the bottom will explain to @gillesdeb that there is no blade called bananas.blade.php

1 like
< GDB >'s avatar

@tykus

  • Sorry for changing names, thought it would be easier, it clearly wasn't

  • Moving this (Route::get('{any}', 'RoutingController@root')->name('any');) to the bottom showed what you all explained multiple times...

  • I'll go hide in shame now

Seriously thank you for the patience!

2 likes
tykus's avatar

No worries @gillesdeb 👍

Go check out the Laravel From Scratch series whenever you get a chance - they will put you on the right path.

1 like
< GDB >'s avatar

@automica yeah... this is awkward... thnx for your help though, really appreciated!

< GDB >'s avatar

@automica @tykus

ashamed to admit I watched 'section 2' multiple times, in which Jeffrey even quickly explains a catch-all route.

Those routes ( were defined by the template, didn't really bother looking at it. Wish I did actually before making my own theories...

MichalOravec's avatar

I see only one problem it's between your chair and monitor.

< GDB >'s avatar

Clearly I'm the issue no need to rub it in though...

automica's avatar

a couple of abbreviations for this:

  • PEBCAK - problem exists between Chair and Keyboard
  • PICNIC - problem in chair not in computer

Please or to participate in this conversation.