Skip to content

How to Split Laravel Routes into Separate Files: 3 Methods for Better Organization & Scalability

Discover 3 proven methods to split Laravel routes into separate files. Learn route organization techniques with practical examples for better code structure, scalability, and team collaboration in Laravel applications.

Dasun Kalupahana 2 min read 959 views 0 comments
On this page
  1. Option 1: Simple File Inclusion in routes/web.php
  2. Option 2: Bootstrap App Configuration (Laravel 11+)
  3. Option 3: RouteServiceProvider (Laravel 10 and Below)
  4. Best Practices and Recommendations
  5. Conclusion

As your Laravel application grows, your route files can become large and hard to maintain. A single routes/web.php file with hundreds of routes becomes difficult to navigate and manage. Fortunately, Laravel provides several ways to split routes into smaller, organized files. Let me show you three practical approaches.



Option 1: Simple File Inclusion in routes/web.php

This is the most straightforward method — using require or include to load additional route files directly in your main routes file.

Step 1: Create Your Controller

First, let’s create a controller for user accounts:

app/Http/Controllers/Account/AccountController.php

namespace App\Http\Controllers\Account;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class AccountController extends Controller
{
    public function index()
    {
        return 'account overview';
    }
    
    public function profile()
    {
        return 'user profile';
    }
    
    public function settings()
    {
        return 'account settings';
    }
}

Step 2: Create Separate Route File

Create a dedicated route file for user accounts:

routes/user/account.php

<?php

use App\Http\Controllers\Account\AccountController;
use Illuminate\Support\Facades\Route;

Route::group([
    'prefix'     => 'account',
    'as'         => 'account.',
    'middleware' => 'auth',
], function () {
    Route::get('overview', [AccountController::class, 'index'])->name('overview');
    Route::get('profile', [AccountController::class, 'profile'])->name('profile');
    Route::get('settings', [AccountController::class, 'settings'])->name('settings');
});

Step 3: Include in Main Routes File

routes/web.php

<?php

use Illuminate\Support\Facades\Route;

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

// Include additional route files
require __DIR__ . '/user/account.php';

// You can include multiple files
require __DIR__ . '/admin/products.php';
require __DIR__ . '/admin/users.php';

Result: You can now access /account/overview, /account/profile, and /account/settings routes, all protected by the auth middleware.

Note: Laravel Breeze and other starter kits often use this approach for auth routes.



Option 2: Bootstrap App Configuration (Laravel 11+)

For Laravel 11 and above, you can define routes directly in the bootstrap/app.php file using the withRouting() method.

Method A: Adding Additional Routes with then

bootstrap/app.php

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Support\Facades\Route;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
        then: function () {
            // Load admin routes with specific middleware
            Route::middleware(['web', 'auth', 'admin'])
                ->prefix('admin')
                ->name('admin.')
                ->group(base_path('routes/admin/panel.php'));
                
            // Load API routes
            Route::middleware('api')
                ->prefix('api/v1')
                ->group(base_path('routes/api/v1.php'));
        },
    )
    ->withMiddleware(function (Middleware $middleware) {
        // Middleware configuration
    })
    ->withExceptions(function (Exceptions $exceptions) {
        // Exception configuration
    })->create();

Method B: Complete Control with using

bootstrap/app.php

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Support\Facades\Route;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        commands: __DIR__.'/../routes/console.php',
        using: function () {
            // Main web routes
            Route::middleware('web')
                ->group(base_path('routes/web.php'));
            
            // User account routes
            Route::middleware(['web', 'auth'])
                ->prefix('user')
                ->name('user.')
                ->group(base_path('routes/user/account.php'));
            
            // Admin panel routes
            Route::middleware(['web', 'auth', 'admin'])
                ->prefix('admin')
                ->name('admin.')
                ->group(base_path('routes/admin/panel.php'));
                
            // API routes
            Route::middleware('api')
                ->prefix('api/v1')
                ->name('api.v1.')
                ->group(base_path('routes/api/v1.php'));
        },
    )
    ->withMiddleware(function (Middleware $middleware) {
        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();


Option 3: RouteServiceProvider (Laravel 10 and Below)

Note: This method is for Laravel 10 and earlier versions. In Laravel 11+, the RouteServiceProvider was removed in favor of the bootstrap/app.php configuration.

Step 1: Create Controller and Route File

app/Http/Controllers/Admin/PanelController.php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class PanelController extends Controller
{
    public function index()
    {
        return 'panel dashboard';
    }
    
    public function users()
    {
        return 'manage users';
    }
    
    public function settings()
    {
        return 'admin settings';
    }
}

routes/admin/panel.php

<?php

use App\Http\Controllers\Admin\PanelController;
use Illuminate\Support\Facades\Route;

Route::get('/', [PanelController::class, 'index'])->name('dashboard');
Route::get('/users', [PanelController::class, 'users'])->name('users');
Route::get('/settings', [PanelController::class, 'settings'])->name('settings');

Step 2: Register in RouteServiceProvider

app/Providers/RouteServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            // API routes
            Route::middleware('api')
                ->prefix('api')
                ->group(base_path('routes/api.php'));

            // Main web routes
            Route::middleware('web')
                ->group(base_path('routes/web.php'));

            // Admin routes with auth middleware and prefix
            Route::middleware(['web', 'auth'])
                ->prefix('admin')
                ->name('admin.')
                ->group(base_path('routes/admin/panel.php'));
                
            // User account routes
            Route::middleware(['web', 'auth'])
                ->prefix('user')
                ->name('user.')
                ->group(base_path('routes/user/account.php'));
        });
    }

    protected function configureRateLimiting(): void
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
        });
    }
}


Best Practices and Recommendations

1. Choose the Right Method for Your Laravel Version

  • Laravel 11+: Use Option 2 (bootstrap/app.php configuration)
  • Laravel 10 and below: Use Option 3 (RouteServiceProvider)
  • All versions: Option 1 (simple require) works universally

2. Use Meaningful Route Names and Prefixes

// Good organization
Route::prefix('admin')->name('admin.')->group(function () {
    Route::get('users', [UserController::class, 'index'])->name('users.index');
    Route::get('products', [ProductController::class, 'index'])->name('products.index');
});

3. Apply Middleware Strategically

// Public routes
Route::middleware('web')->group(...);

// Authenticated user routes  
Route::middleware(['web', 'auth'])->group(...);

// Admin-only routes
Route::middleware(['web', 'auth', 'admin'])->group(...);

// API routes
Route::middleware('api')->group(...);


Conclusion

All three methods effectively solve the problem of bloated route files, but each has its place:

  • Option 1 is simple and works everywhere — perfect for quick organization
  • Option 2 is the modern Laravel 11+ approach — clean and centralized
  • Option 3 is for legacy Laravel 10- applications — robust and feature-rich

Choose the method that best fits your Laravel version and project needs. By organizing your routes logically, you’ll create a more maintainable and scalable application that’s easier for your team to work with.

If you found this helpful, feel free to share or drop a comment. Happy coding with Laravel! 🧱✨

Free resources for this topic

Code snippets and fixes for this topic

Get one practical tip every week

New tutorials, fixes and free cheat sheets from DEV Talk, straight to your inbox. No spam, unsubscribe in one click.

Free download: Laravel interview questions (PDF)

Have a question about this post?

Ask the community: other developers and the author can answer.

Ask the community

Get notified about new articles

One click, no email needed. Turn it off anytime with the bell at the top.

Get new articles on your iPhone

Add DEV Talk to your Home Screen, open it, then tap the bell.

Rate this post
0.0
Share

Enjoying the content?

If this article helped you, you can support the author with a coffee. It keeps new posts coming.

Buy me a coffee (opens in a new tab)

Comments 0

Be kind. Comments with links are reviewed before they appear.

No comments yet

Be the first to share your thoughts.

Get new articles in your inbox

Practical tutorials and deep dives, about once a week. No spam, unsubscribe anytime.

Privacy policy

Add DEV Talk to your Home Screen

  1. 1 Tap the Share button in Safari's toolbar.
  2. 2 Scroll down and tap Add to Home Screen.
  3. 3 Tap Add. Open it from the Home Screen to read like an app and to turn on notifications with the bell.

We use cookies to improve your experience and analyze traffic. By continuing, you agree to our Privacy Policy.