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

argo's avatar
Level 1

Homestead and Browsersync (gulp file)

Hi, I'm trying to integrate BrowserSync into my gulp file, but for the time being it doesn't seem to be working inside the vagrant/homestead box. I have installed BrowserSync globally both in my pc as well as in the Vagrant box. If I start it in the PC using gitBash it works flawlessly, so that:

browser-sync start --proxy="mysite.app:8000" --files="/d/code/mysite/public/assets/css/*"

will proxy my vagrant box. Unfortunately, starting from my Homestead box the BrowserSync server will say it's listening to localhost:3000 but it doesn't respond. I have given up using Livereload as I'm on a windows 8 machine and the dependency paths seem to break havoc with the windows file system. I was wondering if anybody has been able to get it to work or if you could point me in the right direction. Once I get it to work I will try to integrate it into my gulp file

Thanks

0 likes
27 replies
argo's avatar
Level 1

Sorry, completely forgot about this thread @influencebydesign. As I was not able to make it work I did the following:

  • Created an alias on my .bashrc file so that when I type bs - I know :) - the following gets run:
alias bs='cd /d/code/mysite && browser-sync start --config bs-config.js'

Where d:\code\mysite is where my laravel app is.

The bs-config file is as follows:


/* |-------------------------------------------------------------------------- | Browser-sync config file |-------------------------------------------------------------------------- | | For up-to-date information about the options: | http://www.browsersync.io/docs/options/ | | There are more options than you see here, these are just the ones that are | set internally. See the website for more info. | | */ module.exports = { "files": [ "public/assets/**", "app/views/**" ], "server": false, "proxy": "mysite.app:8000", "port": 3000, "ghostMode": { "clicks": true, "scroll": true, "location": false, "forms": { "submit": true, "inputs": true, "toggles": true } }, "logLevel": "info", "logPrefix": "BS", "logConnections": false, "logFileChanges": true, "logSnippet": true, "open": "local", "browser": "default", "xip": false, "hostnameSuffix": false, "notify": true, "scrollProportionally": true, "scrollThrottle": 0, "reloadDelay": 0, "injectChanges": true, "startPath": null, "minify": true, "host": null, "codeSync": true, "timestamps": true, "socket": { "path": "/browser-sync/socket.io", "clientPath": "/browser-sync", "namespace": "/browser-sync" }, "debugInfo": true };
  • The files array is where I have specified the directories that I want to watch
  • The proxy is the local url you want to proxy from
  • The port is the port your proxy (browser-sync) will actually use to view your auto-update site

This means that you have to have one window (I use git bash) for gulp watch, another for browser-sync and yet another for homestead. But it works pretty well.

Hope it helps

Shovels's avatar

I tend to run Gulp / browsersync in my local env as it seems to run quicker. If you want the settings for the gulpfile let me know. It works a treat (even in Windows ;)

1 like
argo's avatar
Level 1

@Shovels would love to see that. That is why I had to do it in such a convoluted way. I seems that I would always get the paths longer than the 256 characters allowed by Windows with the npm installation.

Shovels's avatar

@argo ahh yeah... the dreaded limitations of Windows (well one of them ;) I only tend to run into issues when trying to delete a folder with npm modules in - Often having to rename folder names to a single character until it's below the threshold :-/

I have gulp installed globally, then a gulpfile with this for browsersync...

var gulp = require('gulp')
  browsersync = require('browser-sync'),
  reload = browserSync.reload;

// Configure the proxy server for livereload
var proxyServer = "http://project.app:8000",

 port = 3001;

// Array of files to watch
 (JS / CSS can be triggered separately - see below)
var arrAddFiles = [
    './app/**/*.php'
];

// browser-sync task for starting the server.
gulp.task('browser-sync', function() {
    browserSync({
        proxy: proxyServer,
        port: port,
        files: arrAddFiles,
        ghostMode: {
            clicks: true,
            location: true,
            forms: true,
            scroll: true
        },
        notify: false,
        open: false
    });
});

gulp.task('css', function(){
  gulp.src('./assets/sass/*.scss')
  ...
  .pipe(reload({stream:true}))
}

gulp.task('watch', function(){
 gulp.watch('./assets/sass/**/*.scss', ['css']);
  ...
});

gulp.task('default', ['browser-sync', 'css', 'watch']);
1 like
argo's avatar
Level 1

@Shovels much appreciated. I will give it a go as soon as I finish the project that I'm working on and see if I run into problems :)

1 like
plakhin's avatar

@anheru88, tried to email you, but message returned with an error.

Thanks for extension, it should be very helpful! Trying to set it up. When I use example config (gulpfile.js) It works, but how to make less compilation working too? I'm new to gulp.

Can you please help me with gulpfile.js?

I need when I run "gulp watch" it watch for ./resources/assets/less/ folder and compile app.less file when it changes and also browser sync works as proxy for "localhost:8000" and watches for changes in .resources/views and ./public/css.

I would be very grateful for your help.

anheru88's avatar

Hi @plakhin if you need watch a less folder you can use elixir normaly, you can see the documentation of laravel elixir http://laravel.com/docs/5.0/elixir you can use the following example.

elixir(function(mix) {
    mix.BrowserSync();
    mix.less("app.less");
});

mauroavello's avatar

Using @anheru88 plugin, my config is as follows:

process.env.DISABLE_NOTIFIER = true;

var elixir = require('laravel-elixir');

require( 'laravel-elixir-browsersync' );

elixir( function ( mix ) {
    mix.less( 'app.less' );
    mix.BrowserSync( {
                         proxy:           "re.dev",
                         logConnections:  false,
                         reloadOnRestart: false,
                         notify:          false
                     } );
} );

I find that if I don't specify the proxy the browsersync server keeps waiting for a connection.

The first line taken from @HRcc to remove the notifications.

Hope it helps

PS Thanks to @anheru88 for his plugin

1 like
stringbean's avatar

Anyone know how to configure BrowserSync with this set up to inject the CSS styles instead of reloading the page?

Other than that, the laravel-elixir-browsersync plugin works great!

thiagocoelho's avatar

Well I would like to reload the page only if some php file or javascript has changed. Instead of reloading the page for every css change.

I think that reloading the page to see a css change is slower than just inject the css.

Is that possible?

Shovels's avatar

Yep, BrowserSync can just inject the CSS (the styles update, but without the page reloading). You can also configure it watch certain directors/files for changes and trigger an automatic page reload.

mauroavello's avatar

Ok, so if you want to do what @Shovels suggests, instead of doing:

elixir( function ( mix ) {
    mix.browserSync( [
                         'app/**/*',
                         'public/**/*',
...

you'd want to be more specific on what directories to watch. So that instead of 'public/**/*' you'd put 'public/js/*' making more granular the directories you are watching.

Hope it helps

1 like
thiagocoelho's avatar

@mauroavello I've done that and works nice the page doesn't reload but the css isn't injected in the page too.

I have projects using browser sync and it works injecting the css in the page but I'm not using laravel elixir in any of them.

Am I doing something wrong?

Just in case here is my gulpfile:

elixir(function(mix) {
  mix.scripts([
    '/bower/script/script.js',
    '/bower/script2/script.js'
  ], 'public/js/vendors.js')
  .scripts([
    '/app/module1.js',
    '/app/module2.js',
    '/app/app.js'
  ], 'public/js/app.js');

  mix.browserSync([
    'app/**/*',
    'resources/views/**/*',
    'public/js/**/*'
  ], {
    proxy: 'myproject.local'
  });

  mix.less('app.less');
});
davidspell's avatar

Hey everyone, I am new to browser sync and elixir. I have set up my gulp file according to the basic instructions, it seems to load the localhost:3000 the first time, but it doesnt seem to be watching in the terminal window.

I have this code: require('laravel-elixir-browser-sync');

elixir( function ( mix ) { mix.browserSync( [ 'app//', 'public//', 'resources/views/*/' ], { proxy: 'mona-trivia.app',

                     logConnections:  false,
                     reloadOnRestart: true,
                     notify:          true
                 } );
mix.less( 'app.less' );

} );

When I make a change I see it running this script below but I dont see it rendering my changes as livereloading in my browser. I get in the terminal window [09:53:11] Starting 'watch-assets'... [09:53:11] Finished 'watch-assets' after 733 ms

Am I doing something wrong?

thiagocoelho's avatar

@Shovels @mauroavello

I'm using this new package now: laravel-elixir-browser-sync-simple

Everything works fine,

Thanks.

@davidspell I suppose that you are running gulp watch task right?

Just to confirm your gulpfile looks like this?

elixir(function(mix) { 
  mix.browserSync([
    'app/**/*',
    'public/**/*',
    'resources/views/**/*'
  ], { 
    proxy: 'mona-trivia.app',
    logConnections: false,
    reloadOnRestart: true,
    notify: true
  });

  mix.less('app.less');
});
mauroavello's avatar

I think that the problem is that you're executing Browsersync before you compile your less file. Try putting mix.browserSync as the last thing you run in the elixir function. So that it looks like this:

process.env.DISABLE_NOTIFIER = true;
var elixir = require( 'laravel-elixir' );

require( 'laravel-elixir-browser-sync' );

elixir( function ( mix ) {
    mix.less( 'app.less' );
    mix.scripts( 'form-selectize.js' );
    mix.browserSync( [
                         'app/**/*',
                         'public/**/*',
                         'resources/views/**/*'
                     ], {
                         proxy:           'yuuju.dev',
                         browser:         'google-chrome',
                         logConnections:  false,
                         reloadOnRestart: false,
                         notify:          false
                     } );
} );

Sorry, I just realized that I posted it wrong to begin with. I've deleted the old post so there is no confusion

mkesy's avatar

In my case I propose something like this. It works for me as simple solution without any additional library

In a root directory of project foo-task.js was created

var gulp = require('gulp');
var elixir = require('laravel-elixir');
var config = elixir.config;
var fs = require('fs');

elixir.extend('foo', function(src, output) {
    gulp.task('foo',['less', 'scripts'] ,function() {
        
        fs.writeFileSync('public/live/foo', 'ON');
    });
    this.registerWatcher('foo',config.assetsDir+'**');
    return this.queueTask('foo');
});

In gulpfile.js added :

require('./foo-task');


elixir(function(mix) {

...

   mix.foo();

});

Somewhere in app.blade.php file

@if (env('LIVERELOAD',false)) 
    <script>
      window.setInterval(function(){
       $.get('/live/foo?p='+ Math.floor(Math.random() * (100 -1)) + 1, function(result) {
            if (result == 'ON') {       
                location.reload(true);
                $.get('/api/foo', function(result) {
                      console.log('/api/foo');
                }); 
            }
       });
     }, 1000);
    </script>      
@endif 

And finally in routes.php

 get('/api/foo', function (){
    
        $file = "live/foo";
        $f = fopen ($file,'w');
        fwrite($f, 'OFF');
        fclose($f);
      
  })->where(env('LIVERELOAD',false)?'true':'false','true');

And how it works. In public/live directory I have created file with the name foo. It contains OFF or ON and works like semafor.

gulp watch

and every change in resources/assets.. causes live reload of the page

Shovels's avatar

I've run through the setup a few times now, and it appears to all be working with the following configuration:

// pull in the BrowserSync package
npm install laravel-elixir-browser-sync-simple --save-dev

Then edit gulpfile.js

var elixir = require('laravel-elixir');
require('laravel-elixir-browser-sync-simple');

elixir(function (mix) {
    mix.sass('app.scss')
        .browserSync({
            files: [
                'public/css/*.css',                     // This is the one required to get the CSS to inject
                'resources/views/**/*.blade.php',       // Watch the views for changes & force a reload
                'app/**/*.php'                      // Watch the app files for changes & force a reload
            ],
            proxy: 'yourproject.app',
            logPrefix: "Laravel Eixir BrowserSync",
            logConnections: false,
            reloadOnRestart: false,
            notify: false,
            open: false
        });
});
1 like
lukee's avatar

Hi all,

Even now with Elixir 3.3 including BrowserSync, I still found the whole process to be quite slow. As my front-end projects got bigger and more complex, there were times that I was still waiting close to 3 seconds (!) before the livereload kicked in. This got annoying pretty quickly...

So, I eventually started working on an alternative to Elixir, and tonight I finished it. It's called Fannypack, aka "the toolbelt for front-end developers" lol

It's literally brand spankin' new, so it doesn't have all the functionality that Elixir community's provided, but if you all would be nice enough to check it out, I'd be happy to fill in any missing tasks.

That said, it's incredibly quick --- including reloads.

Thanks!

mtpultz's avatar

@Shovels I've tried your setup, but similar to the original question the browser just stalls out trying to load the application. Has anything changed?

Shovels's avatar

@mtpultz - I'm using the inbuilt version of BrowserSync in Elixir now - seems to work fine out of the box.

You should be able to drop the line at the top of gulpfile.js importing the plugin:

// require('laravel-elixir-browser-sync-simple');

Here's a sample of the config required:

mix.browserSync({
            files: [
                'public/css/*.css', // This is the one required to get the CSS to inject
                'public/js/**/*.js',
                'resources/views/**/*.blade.php',       // Watch the views for changes & force a reload
                'app/**/*.php''
            ],
            proxy: 'http://yourapp.dev',
            logPrefix: "Laravel Eixir BrowserSync",
            logConnections: false,
            reloadOnRestart: false,
            notify: false,
            open: false
        });

Hope that helps :)

1 like
brian-lamb-software-engineer's avatar

Im not able to get port forwarding to work at all, I have tried forwarding through the Vagrantfile, and through the Homestead.yaml, and I have tried using various ports when running gulp watch, I also have an alternate setup which also worked before moving into vagrant, that one also doesn't work. I like @Shovels example, it starts correctly, but no connect, ERR_CONNECTION_REFUSED mostly, is displayed in the browser.

  mix.sass('resources/assets/sass/app.scss', publicDir + '/css')
  // mix.sass('resources/assets/sass/helpers.scss', publicDir + '/css')
  .browserSync({
      files: [
          'public/css/*.css',                     // This is the one required to get the CSS to inject
          'resources/views/**/*.blade.php',       // Watch the views for changes & force a reload
          'app/**/*.php'                      // Watch the app files for changes & force a reload
      ],
      proxy: 'my.app',
      logPrefix: "Laravel Eixir BrowserSync",
      logConnections: false,
      reloadOnRestart: false,
      notify: false,
      open: false,
      // port: 3002,
  });

app.blade

    <script type="text/javascript" id="__bs_script__">//<![CDATA[
            document.write("<script async src='http://HOST:3000/browser-sync/browser-sync-client.js?v=2.18.6'><\/script>".replace("HOST", location.hostname));
            //]]>
    </script>

(i have tried changing location.hostname to all the specific ip's mentioned at the bottom of this post, also.)

Homestead.yaml

ports:
    # browsersync
    # - send: 3000
    #   to: 3000
    # - send: 3001
    #   to: 3001
    - send: 3002
      to: 3000

The terminal shows success on browsersync start

[Laravel Eixir BrowserSync] Proxying: http://my.app
[Laravel Eixir BrowserSync] Access URLs:
 -------------------------------------
       Local: http://localhost:3000
    External: http://10.255.20.26:3000
 -------------------------------------
          UI: http://localhost:3001
 UI External: http://10.255.20.26:3001
 -------------------------------------
[Laravel Eixir BrowserSync] Watching files...
[Laravel Eixir BrowserSync] Reloading Browsers...
[Laravel Eixir BrowserSync] Reloading Browsers...
[Laravel Eixir BrowserSync] Reloading Browsers...
[Laravel Eixir BrowserSync] Reloading Browsers...

As mentioned, i have tried every feasible combination or port combos above, i didnt just try what you see configured in the snips above.

Any suggestions on why I might be getting the Connection Refused? I am in a corp proxy, so not sure if thats part of the problem, but I thought local ports should be able to connect into the vbox.

Which is the guest, the vbox right? Which the host? The operating system that has vbox installed on it right?

I use Win7, and the terminal im using to launch all this is msys2. Also note, i have ssh'd into the vbox numerous times to use curl, im still getting the same, plus CONNECTION_RESET in some instances, but thats because I was shooting in the dark with ports. I also used ip 192.168.10.10, my.app, 10.0.2.2, localhost, 127.0.0.1, and 10.255.20.26 with all the port combos mentioned above.

Note, im running the gulp watch from the Windows box, msys2 terminal. Browsersync is probably the single most complicating piece to setup at times.

NOTE: This url from my (host?) Win Box works http://localhost:3000/browser-sync/browser-sync-client.js?v=2.18.6 so the file is there, and is being served.

Any suggestions?

The other way I had it working (before moving to homestead) was via and or npm run watch and configured like this on my webpack.mix.js file

//https://stackoverflow.com/questions/42047874/laravel-5-4-mix-how-to-run-browser-live-reload
 const BrowserSyncPlugin = require('browser-sync-webpack-plugin');

 mix.webpackConfig({
    plugins: [
        new BrowserSyncPlugin({
            port: 3001,
            files: [
                'app/**/*',
                 publicDir + '/**/*',
                'resources/views/**/*',
                'resources/assets/**/*',
                'routes/**/*'
            ]
        })
    ]
 }) ;

Please or to participate in this conversation.