Skip to main content
Version: 1.0

Routing

In order to declare routes in a project with Laravext, you'll have to use some of the methods provided by it.

Route::laravext(...)

This method is responsible for automagically declaring routes for the project based on the structure of your nexus directory (check Configuration/Nexus Directory for more details on how to change it, if needed), and can be used in the plain way in your routes/web.php file (or in a separate ./routes/laravext.php, as suggested in the Quick Start Installation), like this:

use Illuminate\Support\Facades\Route;

/**
* This will automagically generate all the file-based routes of your application.
* It's recomended that you use it at the top of your routes file, so you can use override it
* with more complex route declarations, if needed.
*/
Route::laravext();

It does, however, accept some parameters so you can use it in a more customized way:

Route::laravext($uri = null, $route_group_attributes = [], $root_view = null)

The parameters:

  • uri: is used so you can define which urls will be matched to this route declaration. If nothing is set, then it'll apply to all the routes created by the Laravext router.
  • route_group_attributes: is used to define the attributes that will be passed to the route group, (such as middleware, as). In order to avoid conflicts with the automagically generate route segments, the prefix parameters that you'd usually use with a route group is not used
  • root_view: is used to define the root view that will be used to render the component. This will override the default root view defined in the configuration file. If nothing is set, the default root view will be used.

Here's an example where any automagically generate route from this point forward (including the '/dashboard' route itself) will contain the defined route group attributes, such as middleware and name prefix, but the prefix will be ignored, unlike a common route group. Any other route that was generated by the Route::laravext() method before this declaration and doesn't start with dashboard will not be affected by this route group attributes.

use Illuminate\Support\Facades\Route;

// You can still use the default way of declaring routes before any complex route declaration
Route::laravext();

Route::laravext('dashboard', route_group_attributes: [

// the prefix key is unset internally, to avoid conflicts with the laravext router
// 'prefix' => 'dashboard',

'middleware' => [
'auth',
'verified'
],

'as' => 'admin.'
]);

As mentioned before, in the Quick Start Installation section, this is technically optional, as there're other ways to generate your routes in a more granular way, but it's entirely up to you on how you want to use it. (Although I think that if you are using Laravext and came all the way here, you probably want to use it).

warning

Important note: as exemplified in examples/laravel-11-vue/routes/laravext.php #L48, if you redeclare any other route that would be a subroute of '/dashboard', like '/dashboard/teams/1/edit', any middleware or other attributes set in the route_group_attributes will not be used in this new route declaration. So if any important middleware is needed, you'll have to redeclare it in the new route declaration, or create a Route::group([...], function() {...}) that would contain both routes so you don't have to redeclare that middleware.

Route::nexus(...)

Similar to Inertia.js' Shorthand Routes, you can manually set a route to a specific nexus component using the Route::nexus method. This method is useful when you want to create a route that doesn't follow the file-based route structure of Laravext, or when you want to set a specific file convention (see FileConvention for more details), root view, etc.

Route::nexus($uri = '{nexusSlug?}', $page = null, $root_view = null, ...$parameters)

The (named) parameters:

  • uri: is used to define the url that will be matched to this route declaration. If nothing is set, then it'll apply to all the routes created by the Laravext router. Unlike the Route::laravext method, this parameter does not affect any subroute.
  • page: is used to define the nexus component that will be rendered. If nothing is set, it'll use any previously page file convention that was detected for that path.
  • root_view: is used to define the root view that will be used to render the component. This will override the default root view defined in the configuration file. If nothing is set, the default root view will be used.
  • parameters: is a variadic parameter that can be used to pass one or more of the following parameters:
    • merge_with_existing_route: wether or not this nexus declaration will be merged to any automagically created route before it by a Route::laravext(). This is so that you don't have to redeclare every file convention for that route, and define only those that you want to to override. This defaults to true, but you can set it to false if you want to completely override the automagically generated route.
    • middleware: the path to the middleware.(jsx|tsx|js|ts|vue) file that will be used to this route.
    • layout: the path to the layout.(jsx|tsx|js|ts|vue) file that will be used to this route.
    • error: the path to the error.(jsx|tsx|js|ts|vue) file that will be used to this route.
    • server_skeleton: the ⚠️html content⚠️ of a skeleton that will be server-side rendered. See FileConvention/Server Side (Basic HTML) for more details.

You can also chain methods such as ->middleware('auth'), ->withoutMiddleware('verified') or ->name('admin.dashboard') to the route declaration, as you would with a common route declaration.

warning

Important note: if you're declaring a nexus route, it'll not have the name of a previously automagically generated route, as it's a completely new route declaration. If you want to use the same name, you'll have to set it manually.

use Illuminate\Support\Facades\Route;

Route::laravext();

Route::nexus('dashboard/settings')->middleware([
'auth'
])->withoutMiddleware([
'verified'
])->name('admin.dashboard.settings');

As mentioned before, you can override the page component, root view or other file conventions like:

use Illuminate\Support\Facades\Route;
use App\Models\Order;

Route::laravext();

Route::nexus('orders/{order}', layout: '(app)/layout.jsx')->middleware([
'auth',
'can:read,order' // assuming you have a policy for the Order model
])->withoutMiddleware([
'verified'
])->name('admin.orders.order');

Once again, this declaration will already know the page file conventions to use because it was already found before to this uri before (because of the Route::laravext above it). If you want to completely override the automagically generated route's file conventions, you can set the merge_with_existing_route parameter to false:

use Illuminate\Support\Facades\Route;
use App\Models\Order;

Route::laravext();

// assuming a route for 'orders/{order}' was already created by the router
Route::nexus('orders/{order}', '(app)/orders/order/page.jsx', layout: '(app)/layout.jsx')->middleware([
'auth',
'can:read,order' // assuming you have a policy for the Order model
], merge_with_existing_route: false)->withoutMiddleware([
'verified'
])->name('admin.orders.order');
Hint: there's no need to set a root view, as the default one will still be used, but you can override as well, if you want

On both previous examples, the order route param would be available in the laravext prop passed to the page.(jsx|tsx|js|ts|vue) component, more specifically in the laravext.route_params.order key. Check Concepts/Laravext Prop for more details.

Route priority

As mentioned in the Quick Start Installation section, the Route::laravext() should be the last route declaration after any other route that is not a Route::laravext('...') or Route::nexus(). This is to ensure that it doesn't mess with any other route declaration that you might have in your routes/web.php file. That's why it's recommended you separate any Route::laravext() or Route::nexus() declaration in another file, like routes/laravext.php or routes/nexus.php (name it as you see fit), and include it at the end of your routes/web.php file, like the example ahead taken from the React example project.

This is completely optional, but I'd recommend it if you have any route that is not a Route::laravext() or Route::nexus() in your routes/web.php file to prevent accidently causing unexpected behavior, as I did myself while creating the React example project and noticed that the short link was being caught by the user.article route, and not the article.short-link route, as I expected.

As you can see in the example below, this prevents, for example, that the user.article route is not cought by either the article.short-link or share routes, as they are declared before it, and could be mistaken for a user.article route.

<?php
// routes/web.php
use App\Models\Article;
use App\Models\Share;
use Illuminate\Support\Facades\Route;

Route::view('about-this-project', 'sections.about-this-project')->name('about-this-project');

// Redirect article short link codes to the article
Route::get('sl/{article:short_link_code}', function (Article $article) {
return redirect()->route('user.article', ['article' => $article->slug, 'user' => $article->user->username]);
})->name('article.short-link');

// Redirect share links to the article
Route::get('s/{share:code}', function (Share $share) {
return redirect()->route('user.article', ['article' => $share->article->slug, 'user' => $share->article->user->username, 'sid' => $share->id]);
})->name('share');

require __DIR__ . '/laravext.php';

and the routes/laravext.php file:

use App\Models\Article;
use App\Models\Read;
use App\Models\User;
use Illuminate\Support\Facades\Route;

Route::laravext();

Route::nexus('')->name('home');

Route::nexus('new')->middleware('auth')->name('new');

// For simplicity reasons, I won't be using a controller for some of these routes
Route::get('{user:username}', function (User $user) {
$user->loadCount(['articles', 'comments', 'followers', 'following', 'tags']);

return nexus(props: compact('user'))->render();
})->name('user');


Route::get('{user:username}/{article:slug}', function (User $user, Article $article) {

// You can see the rest of the code in the example. I removed to keep it simple

return nexus(props: compact('article', 'latest_articles_from_user'))
->withViewSkeleton('partials.article')
->withHeadTitle($article->title)
->render();
})->name('user.article');

Route::group([
'middleware' => ['auth', 'role:admin'],
], function () {
Route::laravext('admin', root_view: 'sections.admin');
});