Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Foxandxss's avatar

Deploy Laravel and Angular on same domain

Hello, after seeing that letting Laravel serve Angular is not that good idea, I started to play with the idea of having two different applications, different folders but same domain, for example:

example.com/
example.com/stuff

That both will serve angular.

example.com/api/stuff

That will go to Laravel. So Angular lives in the root and Laravel under /api.

I managed to create an nginx conf for that:

server {
    server_name mroot.local;
    root /var/www/laravel/mroot/client/tmp;

    location / {
        index index.html;
        try_files $uri $uri/ /index.html =404;
    }

    location /api {
        root /var/www/laravel/mroot/foo/public;
        try_files /index.php =404;

        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        fastcgi_param APP_ENV dev;
        fastcgi_pass 127.0.0.1:9000;
    }
}

(client is Angular, foo is laravel)

My question is. How do you see this idea?

I am not sure if it has some serious downsides. I tried a basic demo with a GET and it works like charm (even html5mode) but maybe other stuff won't work.

One "downside" is that I limit laravel just to /api (which well, can be expected on this kind of applications). I guess I can always create more location in nginx to provide API versioning.

What do you think? I guess that having two different nginx configurations (two different domains) is more flexible, but comes with prices (for example, two SSL, which I have nothing against them, but for some pet projects I don't want to pay twice for SSL).

Thanks.

0 likes
13 replies
Alias's avatar

Don't know the scope of your project, but I have a project which uses Laravel as the base and Angular as the MVC framework ontop which plays together very nicely.

Basically, I have a single php view page (app/views/index.blade.php). This file acts as the wrapper for your angular project, so is basically structured like so:

<!doctype html ng-app="App">
<head>
   <!-- stylesheets -->
   <!-- scripts --> 
</head>
<body ng-controller="MasterCtrl">
   <div data-ui-view></div>
</body>
</html>

Using ui.router here, but you get the picture.

Then my routes file looks something like this:

<?php

Route::controller('api', 'ApiController');

App::missing(function($exception)
{
    return View::make('index');
});

Basically Laravel still picks up any defined routes, but anything which is not found (in this case, even the index page), AngularJS will pickup and deal with... Allowing you to handle the routes/states from there. This also works with html5 routing enabled or disabled.

In the above example, I have my AngularJS hitting the api/ route to grab content, but it also means I can still use the power of Laravel as my backend.

1 like
Foxandxss's avatar

Hello @alias. I like your way, but I got in a pretty good discussion the other day saying that that way is pretty coupled. If you need to update your angular, you need to redeploy your API and viceversa (which is right, but not thaaat problematic).

Also serving the angular using a route like that seems to be problematic as well (not so sure because the other frameworks does the same). I got a friend who uses Route::filter to do a !Request::wantJson() to render the angular view or move to the /api request. A worthy option I guess.

Alias's avatar

Yeah totally get what you're saying, however if you really want an application which, at the end of the day is mixing two totally different MVC frameworks together, it will get "messy".

I personally haven't experienced any issues using the approach described above, that being said I am currently developing it and not maintaining it yet.

larryeitel's avatar

I also have L4+Angular running. I have begun with using Angular to give ajax'y functions to a form. One thing that stumped me was that other links on a page that involved Angular would not load. I had to add target="_self" to affected links in order to force page load when hitting those links.

afreire's avatar

Hi there... i'm actually building a laravel backend for an existing angularjs app. They will live under the same domain.Your final approach seems, to me, a good one. In my case i'm more concern with the auth and security level. @larryeitel if you had to hack your routes that way you're doing it wrong. You're mixing laravel and ajs routes. I would really like a definitive solution (boillerplate) to this problem. Having complete separation of concerns living in the same ecosystem could solve a lot of small problems

larryeitel's avatar

@afreire, I suspected I was doing something wrong but as I was about to abandon the effort, I found a 'work-around'. I look forward to reviewing any suggestions. :)

Foxandxss's avatar

Hey @afreire. Security is not an issue. You can use any common solution. I highly recommend JWT. I wrote a bit about it on my blag, but I pretend to write something more using Laravel :)

lukehowell's avatar

This solution does not handle the case of files that actually exists that you may want to access (robots.txt, favicon.ico, other images, etc.). I know for an api backend this might not always be necessary, however we are going to be serving help docs for the api so we will need the frontend.

This solution appears to work because it is abusing the 404 catch and not actually doing a try_files. Try_files would be the ultimate solution however there is still an open bug in nginx using alias and try_files referenced at http://trac.nginx.org/nginx/ticket/97#comment:14 on the nignx site.

I have worked up a solution that solves both problems and from my initial tests will route to files and directories if they exists and if not will fall back to the index.php to allow Laravel to handle the routing. This is what try_files does for you when it works.

I am using this solution on my servers as well as my Homestead box. The only catch obviously is that reprovisioning the server will overwrite the nginx files. Our setup for Homestead is to have the app point to the Angular code base and then add the location /api block to our nginx config.

This should restore Laravel routing to full functionality. This will allow for versioning of the API.

NGINX config and routing example are below.

nginx Config

server {                                                                                                                                                                                                                                  
    listen 80; ## Listen on port 80 ##
    server_name example.com;  ## Domain Name ##
    root /home/vagrant/example.com/angular/build;  ## Site root for the Angular code ##

    index index.html index.php;  ## Set the index for site to use ##

    charset utf-8; ## Set the charset ##

    location / { ## Handle default requests ##
        try_files $uri $uri/ /index.html;  ## Try files and fall back to index.html ##
    }

    location /api { ## URL string to use for api ##
        alias /home/vagrant/example.com/laravel/public; ## Site root for Laravel code ##

        ## Check for file existing and if there, stop ##
        if (-f $request_filename) {
            break;
        }

        ## Check for file existing and if there, stop ##
        if (-d $request_filename) {
            break;
        }

        ## If we get here then there is no file or directory matching request_filename ##
        rewrite (.*) /api/index.php?$query_string;

        ## Normal php block for processing ##
        location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_index index.php;
            include fastcgi_params;
        }
    }

    ## Don't fail or log request to favicon or robots.txt ##
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    ## Access log is off and error log location is set ##
    access_log off;
    error_log  /var/log/nginx/example.com-error.log error;

    ## Disable sendfile ##
    sendfile off;

    ## Normal php block for processing ##
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }

    ## Don't allow access to .ht files ##
    location ~ /\.ht {
        deny all;
    }
}

Routing example

Route::group(['prefix' => 'v1'], function() {
    Route::get('/', ['as' =>'v1', 'uses' => 'LandingController@v1']);
    Route::get('users', ['as' => 'users', 'uses' => 'V1\UserController@index']);
});

Route::group(['prefix' => 'v2'], function() {
    Route::get('/', ['as' =>'v2', 'uses' => 'LandingController@v2']);
});
anil1712's avatar

Hello @snumb130 I did exactly same as above, my angular project running as html but the laravel api doesn't seems to be work, whenever I hit the url http://localhost/api it shows "No input file specified." in the browser, please give me some suggestion on this. Here is my configuration please let me know am I doing something wrong.

FYI, I am using W8 OS and Laravel5, for fast cgi using xampp php-cgi.exe in 127.0.0.1:9123 port

server {                                                                                     
        listen 80; ## Listen on port 80 ##
        server_name localhost;  ## Domain Name ##
        root F:\xampp\htdocs\laravel_angular_project;  ## Site root for the Angular code ##

        index index.html index.php;  ## Set the index for site to use ##

        charset utf-8; ## Set the charset ##

        location / { ## Handle default requests ##
            try_files $uri $uri/ /index.html;  ## Try files and fall back to index.html ##
        }

        location /api { ## URL string to use for api ##
            alias F:\xampp\htdocs\laravel_angular_project\api\public; ## Site root for Laravel code ##

            ## Check for file existing and if there, stop ##
            if (-f $request_filename) {
                break;
            }

            ## Check for file existing and if there, stop ##
            if (-d $request_filename) {
                break;
            }

            ## If we get here then there is no file or directory matching request_filename ##
            rewrite (.*) /api/index.php?$query_string;

            ## Normal php block for processing ##
            location ~ \.php$ {                                     
                fastcgi_split_path_info ^(.+\.php)(/.+)$;               
                fastcgi_pass 127.0.0.1:9123;
                fastcgi_index index.php;
                include fastcgi_params;     
            }
        }

        ## Don't fail or log request to favicon or robots.txt ##
        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }

        ## Access log is off and error log location is set ##
        access_log off;
        #error_log  /var/log/nginx/example.com-error.log error;

        ## Disable sendfile ##
        sendfile off;

        ## Normal php block for processing ##
        location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;           
            fastcgi_pass 127.0.0.1:9123;
            fastcgi_index index.php;
            include fastcgi_params;         
        }

        ## Don't allow access to .ht files ##
        location ~ /\.ht {
            deny all;
        }
    }
1 like
lukehowell's avatar

I don't have a Windows install up right now where I can test this, but I wonder if there is some conflict because your api directory is inside your main root. See if moving the api outside of your main project root has any effect.

devmark's avatar

Hi, Why don't just make two sites, api.my.com for Laravel and my.com for site?

After do that, We can use JWT FOR Auth part, and also we need to set CORS in Laravel site. so that we can make sure who calling api is from my.com

any ideas?

MarkLL's avatar

Hi @anil1712 I have a modified WAMP install which I have swapped out Apache for nginx. I'm also running W8.1.

I tried to get the Apache Alias for phpMyAdmin to work using the Alias command and no matter what I tried, it just did not work! (same error as you)

What you can try (it worked for me with above) is to move you Lavavel App (I kinda agree with @snumb130 in that it may clash cause it's already in the root area) to say F:\xampp\htdocs\laravel_angular_project_api and then in the F:\xampp\htdocs\laravel_angular_project folder create a symbolic link to the api location (mklink /D api "F:\xampp\htdocs\laravel_angular_project_api/public"). You will need to ensure that the api directory does not exist first :)

Please or to participate in this conversation.