Redirect www to non-www URLs in Laravel

Published 28 November 2019 20:02 (4-minute read)

I want my site to show as robindirksen.com and not www.robindirksen.com in the search results or any other place, but how do you handle the removal of www in your application so you don't lose your visitors?

There are a few ways how you can solve this. I recommend the server-side (for example nginx or htaccess) above application-based redirects (for example Laravel) because these will also redirect static files to the non-www version of your site.

Nginx configuration

You can make a new configuration in your configuration directory, this is usually in the /etc/nginx/conf.d/ directory. You can make a file (for example: /etc/nginx/conf.d/redirect.conf) and place the following configuration:

server {
    server_name www.robindirksen.com;
    return 301 $scheme://robindirksen.nl$request_uri;
}

This will redirect everything that requests www.robindirksen.com to the non-www version, robindirksen.com.

.htaccess file

In a Laravel application, you will find a .htaccess file in your public folder. Here you can add the following code to redirect the visitors.

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.robindirksen.com$ [NC]
RewriteRule ^(.*)$ http://robindirksen.com/$1 [R=301,L]

To enable redirect you have to install mod_rewrite to the server and switch RewriteEngine to on.

Laravel Application

One of the ways to do this is by making a middleware and enable this to all your requests.

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Redirect;

class RedirectToNonWwwMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (substr($request->header('host'), 0, 4) == 'www.') {
            $request->headers->set('host', 'robindirksen.com');

            return Redirect::to($request->path());
        }
        
        return $next($request);
    }
}

After you've made your middleware you need to add it to the requests, this can be done by adding it to all of the requests (web, API, etc) or only the web.

To add it to all of your requests, you can add the middleware (\App\Http\Middleware\TrustProxies::class) to the $middleware array, then it will look sometime like this:

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \App\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\TrustProxies::class,
    ];

It's also possible to only add it to the web-group requests (and not your API endpoints). With a basic Laravel 6 installation, it will be added to all the requests made to the routes defined in routes/web.php.

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\HttpsProtocolMiddleware::class,

            \App\Http\Middleware\RedirectToNonWwwMiddleware::class
        ],

        'api' => [
            ...
        ],
    ];
}

Please pay attention, when you have links to static files (like images, css, or javascript) you have to enable htaccess or nginx redirects, otherwise, those keep be served from the www version. This happens because the static files won't boot the framework what means it doesn't receive the redirect.

Which status code do I need to use?

Last but not least, which redirect HTTP code do you need to use? It's really simple, you want to permanently show your non-www site in the results, then you redirect with a 301 status code.

Sometimes it can happen to only redirect the users for a specific time to another URL, then you want a temporary redirect. This can be done by redirecting with a 302 status code.


Robin Dirksen
Robin Dirksen

Follow me on Twitter, there I post web-related content, tips/tricks, and other interesting things.

On my blog, you can find articles that I've found useful or wanted to share with anyone else.

If you want to know more about this article or just want to talk to me, don't hesitate to reach out.

Legal