How to configure Browser Sync live reloading in your current or next Laravel project running on Homestead Virtual Machine

|5 min read|
Teklog
Teklog


Introduction

Browser Sync is an open source tool that can instantaneously synchronize your code changes with your browser. As soon as the file is saved, automatic webpage reload happens, without any action from your side.

You could use Browser Sync outside Laravel and without Laravel Mix asset bundler, however in this tutorial I will focus primarily on how to harvest its greatest features with truly minimalistic configuration.

All the hardest work has already been done by Laravel Mix, which lets you incorporate Browser Sync into your project with little effort. If you are interested, Laravel Mix uses Webpack module bundler with browser-sync-webpack-plugin under the hood.

So, do you want to gain some time while developing your current or future Laravel project? If the answer is yes, then let's start it off right away!

Assumptions

  • Homestead Virtual Machine is up and running
  • Fresh or existing Laravel project with Laravel Mix is configured and running in your browser

Solution

Update Laravel Mix webpack.mix.js configuration file

mix.browserSync({
  open: false,
  files: [
    'app/**/*',
    'public/**/*',
    'resources/views/**/*',
    'routes/**/*'
  ]
})

As you see, Browser Sync will listen for changes only inside the most important Laravel folders, as well as their subfolders. Additionally, option open is set to false, because inside the Virtual Machine there is no X Window System configured - therefore no way to open the graphical browser window from a terminal.

Make sure you don't track changes on directories like resources/js, resources/sass, since those are usually pre-processed by specific plugins (e.g: Sass processor, Babel transpiler). What you should be really up for are the output files generated by them, usually saved under public folder, as shown below

mix.sass('resources/assets/sass/app.scss', 'public/css')
  .js('resources/assets/js/app.js', 'public/js')
  .react('resources/assets/js/appreact.js', 'public/js');

Next, head over to your Blade main layout file and paste following snippet right before </body> tag.

@if (getenv('APP_ENV') === 'local')
  <script id="__bs_script__">//<![CDATA[
    document.write("<script async src='http://HOST:3000/browser-sync/browser-sync-client.js?v=2.18.12'></script>".replace("HOST", location.hostname));
    //]]>
  </script>
@endif

Before we continue, let's stop and try to understand what is happening there

  • Browser Sync client script will be loaded only after you define APP_ENV variable as local inside .env file
  • HOST placeholder will be replaced by Hostname (if your URI was http://homestead.app/users, then HOST will become homestead.app)
  • 3000 is a default port used by Browser Sync, if you defined other port inside your webpack.mix.js, make sure you change this too
  • 2.18.12 is a Browser Sync version, verify your version by running node_modules/browser-sync/bin/browser-sync.js --version and adjust the ?v variable accordingly

Next, open terminal window on your host machine and SSH onto your Homestead Virtual Machine

homestead ssh

If your host Unix-like operating system doesn't recognize this command, consider creating a helpful function

function homestead() {
 ( cd ~/path/to/your/homestead/directory && vagrant $* )
}

It should be placed inside your shell configuration file (e.g: .bashrc, .bash_profile, .zshrc) and sourced, if you want to use it immediately (source ~/.bashrc).

Inside your Virtual Machine, traverse to your Laravel application directory (the one where package.json exists) and run

npm run watch

You may experience dependency pre-installation screen, as shown below

Additional dependencies must be installed. This will only take a moment.
.
.
.
Finished. Please run Mix again.

This will most probably install browser-sync-webpack-plugin package.

Once it's finished, rerun previous command: npm run watch and you should see the output similar to the one below

DONE Compiled successfully in 7168ms 
.
.
.
[BS] Proxying: http://app.dev
[BS] Access URLs:
 ----------------------------------
 Local: http://localhost:3000
 External: http://10.0.2.15:3000
 ----------------------------------
 UI: http://localhost:3001
 UI External: http://10.0.2.15:3001
 ----------------------------------
[BS] Watching files...

Don't worry about those magic Hosts and IPs, you may change them inside your Browser Sync configuration, but from my experience, they didn't have any effect.

Hint: If npm watching does not work for you, consider using npm run watch-poll.

That's all that is to it, now it's high time to test if everything works well.

On your host machine, open your favorite browser and paste the project's url (e.g http://homestead.app). On the top right corner you should see a popup with text Connected to BrowserSync.

Head over to your IDE editor, change something in your Blade template, Javascript or CSS files and save it. Make sure it's also saved on your Homestead Virtual Machine, since this is the place where Browser Sync is watching for changes.

Once done, you should see the live reloading in play. Isn't it cool? If you have two monitors, this can tremendously speed up your development.

BrowserSync also provides handy UI console. In order to see it, open a new tab in your host machine's web browser, pasting your project URL followed by port 3001 (e.g: http://homestead.app:3001)

Summary

Browser Sync is an amazing tool, which can make your life as a developer much easier and more rewarding. It has a few other features I didn't even touch here, so feel free to scan their Browser Sync website yourself.

You can also track the Laravel Mix Browser Sync documentation, however it's not very handy.

Besides Browser Sync, there is another cross-browser synchronization tool out there, which name is LiveReload.

I will dedicate the whole blogpost to it, but if you are really impatient, feel free to check the Laravel Mix Live Reload documentation yourself.