Whilst experimenting with Nuxt.js (A Vue.js framework) as a front end client for Laravel I discovered I was going to face some issues with CORS, certificates for HTTPS and the whole serving the client over port 3000 and the API over port 80 thing.

In the development environment this isn’t so bad as I can run both the Laravel artisan web server and serve Nuxt.js and have them talk to each other – within reason. The problems started when I wanted to use Social Sign In using Facebook, Google etc. The callback from the OAuth process would fire, but the client would fail with CORS errors as I would have to redirect the client using the API from the OAuth callback.

To resolve this issue I tried adding in a CORS module for Laravel and setting the values appropriately, but still failed.

So I began thinking what this would look like in production. I wouldn’t want to serve the API and client separately and I’d probably put them both behind a reverse proxy, so let’s look at using Nginx.

My thinking was that I can already serve a Laravel project using Nginx over HTTP or HTTPS, let’s follow that plan. If I setup Nginx and PHP just the way I’d do for a regular Laravel server, I can then change it so that it only responds to calls to the location /api as that is all I will be using Laravel for, I wont have any web routes in Laravel as I won’t be serving any client based materials like blades, css, html or compiled Vue components.

The client will be served from the Nuxt.js server. It will get all of it’s client interface, css and html from Nuxt.js.

The use of Nginx as a proxy for Nuxt.js is documented here. All I’ve done is blend that configuration with my Laravel configuration to come up with and Nginx server that serves /api from Laravel, and everything else / gets proxied to Nuxt.js (@proxy).

map_hash_max_size 262144;
map_hash_bucket_size 262144;
map $sent_http_content_type $expires {
"text/html" epoch;
"text/html; charset=utf-8" epoch;
default off;
server {
listen 80;
listen 443 ssl;
server_name dev.domain.tld;
root "C:/mnt/data/Documents/projects/laravel-oauth/public";
index index.php;
# Access Restrictions
deny all;
location /api {
try_files $uri $uri/ /index.php$is_args$args;
location / {
try_files $uri $uri/ @proxy;
autoindex on;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass php_upstream;
#fastcgi_pass unix:/run/php/php7.0-fpm.sock;
# Enable SSL
ssl_certificate "C:/etc/ssl/mycert.crt";
ssl_certificate_key "C:/etc/ssl/mycert.key";
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
charset utf-8;
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
location ~ /\.ht {
deny all;
location @proxy {
expires $expires;
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline';";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Cache-Status $upstream_cache_status;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_ignore_headers Cache-Control;
proxy_http_version 1.1;
proxy_read_timeout 1m;
proxy_connect_timeout 1m;
proxy_pass; # set the adress of the Node.js instance here
#proxy_cache nuxt-cache;
proxy_cache_bypass $arg_nocache; # probably better to change this
proxy_cache_valid 200 302 60m; # set this to your needs
proxy_cache_valid 404 1m; # set this to your needs
proxy_cache_lock on;
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
proxy_cache_key $uri$is_args$args;
#proxy_cache_purge PURGE from;
view raw 00-nuxtjs.conf hosted with ❤ by GitHub

Now I can manage any CORS requirements using the Nginx config.

What’s more the basis of this config can also be used with Laragon to serve from Windows.