How to install WordPress alongside Laravel on Nginx with pretty permalinks (SEO-friendly URLs)?

I have a Laravel site running on Nginx, and it’s fine.

It has a normal folder structure like:

Read More
/app
/public
/vendor
...

The /public folder is where the Laravel index.php is.

I’ve installed WordPress at /public/blog because I want my blog to be visible at mywebsite.org/blog.

The blog currently works fine if I leave the Permalink Settings defined at /blog/wp-admin/options-permalink.php set to “Default” (which means the URLs for posts look like /blog/?p=123). If I change Permalink Settings to /blog/%postname%/, I can’t view the posts (I get a Laravel 404 page).

I definitely want my blog posts to have SEO-friendly URLs (pretty permalinks).

My current Nginx config is:

server {
    #This config is based on https://github.com/daylerees/laravel-website-configs/blob/6db24701073dbe34d2d58fea3a3c6b3c0cd5685b/nginx.conf and seemed to be necessary to get Laravel working.
    server_name mysite.local;

     # The location of our project's public directory.
    root F:/code/mysite/public/;

     # Point index to the Laravel front controller.
    index           index.php;

    location / {
        # URLs to attempt, including pretty ones.
        try_files   $uri $uri/ /index.php?$query_string;
    }

    # Remove trailing slash to please routing system.
    if (!-d $request_filename) {
            rewrite     ^/(.+)/$ /$1 permanent;
    }

    # Yoast WordPress SEO plugin says to add these 2 rewrites:
    rewrite ^/blog/sitemap_index.xml$ /blog/index.php?sitemap=1 last;
    rewrite ^/blog/([^/]+?)-sitemap([0-9]+)?.xml$ /blog/index.php?sitemap=$1&sitemap_n=$2 last;

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9123
    location ~ .php$ {
        fastcgi_pass   127.0.0.1:9123;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    location ~* .(css|js|gif|jpe?g|png)$ {
        #images, CSS, and JS have 1 week expiration: http://aspyct.org/blog/2012/08/20/setting-up-http-cache-and-gzip-with-nginx/ See also: http://serverfault.com/questions/339240/chromium-audit-says-its-not-caching-static-content-yet-headers-are-set-who-i
        expires 168h;
        add_header Pragma public;
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
    }

}

I have spent hours reviewing other answers (listed below) and haven’t figured out how to get this working.

Suggestions?

P.S. I’m flexible with where I’d install the WordPress files (e.g. either at /public/blog or move it up a level to /blog or /wordpress).

Related posts

Leave a Reply

1 comment

  1. You route everything to laravel in your / location, but you need to write everything /blog/ to the index.php in /blog/index.php:

    location /blog/ {
        try_files $uri $uri/ @wordpress;
    }
    
    location @wordpress {
        rewrite /blog/ /blog/index.php;
    }
    

    Then your php handler needs path info support:

    location ^/blog/index.php(/.*)?$ {
        fastcgi_split_path_info ^(/blog/index.php)(/.*)$;
        fastcgi_pass   127.0.0.1:9123;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_param  PATH_INFO $fastcgi_path_info;
        include fastcgi_param;
    }
    

    Turn on debug verbosity for error log if this doesn’t work and post log info.

    UPDATE: Note from original question asker:

    Here is a snippet of my new Nginx config, which seems to work for these URLs: /, /blog, /course, /blog/innately-happy, and /blog/sitemap_index.xml

    ...
    error_log /Users/myuser/code/myproject/storage/logs/nginx_error.log debug;
    
     # Point index to the Laravel front controller.
    index           index.php;
    
    location /blog/ {
        try_files $uri $uri/ @wordpress;
    }
    
    location @wordpress {
        rewrite /blog/ /blog/index.php;
    }
    
    location ^/blog/index.php(/.*)?$ {
        fastcgi_split_path_info ^(/blog/index.php)(/.*)$;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_param  PATH_INFO $fastcgi_path_info;
        include fastcgi_params;
    }
    
    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }
    ...