Skip to content

Routes

On this page you give the FAQ two addresses, /admin/faq and /faq, answered for now by closures that Controllers replaces. A package declares its routes in files under src/Routes and loads them from its service provider, with admin and storefront routes in separate files because they run under different middleware.

The Middleware Bagisto Provides

MiddlewareRegistered byWhat it does
adminUser packageWebkul\User\Http\Middleware\Bouncer: requires a signed-in admin, enforces two-factor authentication and checks the route against the ACL
shopShop packageA group of Theme, Locale and Currency, which set the channel's theme, locale and currency for the request
theme, locale, currencyShop packageThe same three, one at a time
customerShop packageRequires a signed-in customer
cache.responseShop packageLets the full page cache store the response; Cache Strategy lists what is cached and what clears it
Webkul\Core\Http\Middleware\NoCacheMiddlewareCore package, by class nameSends Cache-Control: no-store, so a browser never shows an admin page from its cache
Webkul\Core\Http\Middleware\PreventRequestsDuringMaintenanceCore package, by class nameAnswers storefront requests with the maintenance page while the channel is in maintenance mode

Admin routes run under web, admin and NoCacheMiddleware, prefixed with config('app.admin_url'), which is admin unless APP_ADMIN_URL changes it. Core's admin group also adds PreventRequestsDuringMaintenance, but that middleware lets every admin URL through, so a package leaves it out. Storefront routes run under web, shop and PreventRequestsDuringMaintenance, with no prefix, as core's do.

Create the Admin Routes

File: packages/Webkul/Faq/src/Routes/admin-routes.php

php
<?php

use Illuminate\Support\Facades\Route;
use Webkul\Core\Http\Middleware\NoCacheMiddleware;

Route::group([
    'middleware' => ['web', 'admin', NoCacheMiddleware::class],
    'prefix' => config('app.admin_url'),
], function () {
    Route::get('faq', function () {
        return 'FAQ admin';
    })->name('admin.faq.index');
});

web comes first because admin reads the session it starts. Name every admin route admin.<package>.<action>, so the name says where the route belongs and doesn't collide with core's.

Create the Storefront Routes

File: packages/Webkul/Faq/src/Routes/shop-routes.php

php
<?php

use Illuminate\Support\Facades\Route;
use Webkul\Core\Http\Middleware\PreventRequestsDuringMaintenance;

Route::group([
    'middleware' => ['web', 'shop', PreventRequestsDuringMaintenance::class],
], function () {
    Route::get('faq', function () {
        return 'FAQ storefront';
    })->name('shop.faq.index');
});

Without shop, the page renders with no theme, locale or currency set for the request. Without PreventRequestsDuringMaintenance, it stays reachable while the rest of the storefront is down for maintenance.

Load the Route Files

Add both files to the provider's boot() method:

File: packages/Webkul/Faq/src/Providers/FaqServiceProvider.php

php
<?php

namespace Webkul\Faq\Providers;

use Illuminate\Support\ServiceProvider;

class FaqServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     */
    public function register(): void {}

    /**
     * Bootstrap services.
     */
    public function boot(): void
    {
        $this->loadMigrationsFrom(__DIR__.'/../Database/Migrations');

        $this->loadRoutesFrom(__DIR__.'/../Routes/admin-routes.php');

        $this->loadRoutesFrom(__DIR__.'/../Routes/shop-routes.php');
    }
}

Test It

  1. List the routes. admin/faq is named admin.faq.index and faq is named shop.faq.index, each with its middleware:

    bash
    php artisan route:list --name=faq -v
  2. Signed in to the admin, open /admin/faq. The page shows FAQ admin.

  3. Open /faq on the storefront. The page shows FAQ storefront.

Things to Watch

  • Admin routes fail closed. The admin middleware maps every route name in every acl.php to a permission and refuses a route missing from that map with a 401. Only a role whose permissions are set to All skips the check, so /admin/faq works for the default administrator and fails for any custom role until Access Control List adds the package's entries.
  • Read the prefix from configuration. A literal admin/ prefix breaks on a store that sets APP_ADMIN_URL.
  • The storefront catch-all runs last. The Shop package resolves product and category URLs with Route::fallback(), which Laravel tries only after every other route, so /faq is always reachable. The cost falls the other way: a product or category whose URL key is faq can no longer be opened at /faq, so choose storefront paths a merchant is unlikely to use as a URL key.
  • Route names must be unique across the application. When two routes share a name, route() returns whichever was registered last and php artisan route:cache fails.

Next Step

The routes answer with placeholder strings. Next, point them at controllers that use the repository.

Continue to: Controllers

Released under the MIT License.