HMR not working on clean install of Sage

Sage never injects changes on save. I always need to save the file I’m editing, then manually refresh the browser to see changes. I have my domain “parked” by Laravel Valet at https://bedrock.test, and everything seems to work as expected except for HMR.

Running yarn build compiles styles and scripts and the changes are visible after a full page refresh. If I run this after every change I make, I can see the styles changing after a full refresh. Running yarn dev compiles styles as well, and I only have to run it once, but I still need to manually refresh the browser to see the changes.

So essentially, I can’t get HMR working. I’ve been stuck on this a while as I try to figure out my workflow with Sage/Bedrock/Valet.

Here’s part of my bud.config.js which may be the problem:


export default async (app) => {
  /**
   * Application assets & entrypoints
   *
   * @see {@link https://bud.js.org/docs/bud.entry}
   * @see {@link https://bud.js.org/docs/bud.assets}
   */
  app
    .entry('app', ['@scripts/app', '@styles/app'])
    .entry('editor', ['@scripts/editor', '@styles/editor'])
    .assets(['images'])

  /**
   * Set public path
   *
   * @see {@link https://bud.js.org/docs/bud.setPublicPath}
   */
  app.setPublicPath('/app/themes/[this is my theme name]/public/');

  /**
   * Development server settings
   *
   * @see {@link https://bud.js.org/docs/bud.setUrl}
   * @see {@link https://bud.js.org/docs/bud.setProxyUrl}
   * @see {@link https://bud.js.org/docs/bud.watch}
   */
  app
    .setUrl('https://localhost:3000')
    .setProxyUrl('https://bedrock.test')
    .watch(['resources/views', 'app'])

Note that, again, I’m accessing my local site at bedrock.test and not https://localhost:3000. When I visit localhost:3000, I get “Safari can’t open page”. I figured I should be seeing the changes on the proxy URL I specified.

Thank you for any help you can provide. I’m struggling to find documentation and resources that address this. Since this I’m working with a clean install of Sage / Bedrock, I feel I’m missing something basic here.

I’ve also tried installing the latest development version of Sage and switching to that new theme to see if that makes a difference - it did not. I’m still experiencing the same issue of styles not being injected.

At this point should I give up on using Laravel Valet and give Trellis a shot? I thought this set up would be fast and straight-forward but I’m struggling here :sweat_smile:

Hi @graham,

In order for HMR to work, you must access the site via the HMR server, running on port 3000 in your case.

It looks like you may be trying to access the HMR server via SSL, when SSL isn’t enabled. The browser will then be unable to negotiate the protocol.

If you change your setUrl() call to setUrl('http://localhost:3000'), and then visit the (plain HTTP) HMR URL, does Safari behave?

To enable SSL for the HMR server, check out the examples for bud.serve(). You’ll need to handle certificates yourself though.

FWIW - I have Valet projects running fine here!

Tom.

2 Likes

Thanks for the response, Tom. That’s great to hear you’ve got valet sites running fine, because I do want to get this method working.

I did another fresh install with bedrock to see if that would make a difference, and made the changes you suggested. Using both Chrome and Safari with caches and cleared (and also incognito mode and restarted computer for good measure) http://localhost:3000 simply redirects to what I’ve renamed https://roots.test (with SSL despite my attempts to view the site as http).

My bud.config.js now:

app
    .setUrl('http://localhost:3000')
    .setProxyUrl('http://roots.test')
    .watch(['resources/views', 'app']);

I’m just changing the background-color back and forth to see when HMR starts working.

I’ll try to work with bud.serve() to see if enabling SSL will solve the problem. Thanks for the direction. I’ll report back.

Hi @graham,

Looks like you’re almost there! The redirect you’re experiencing now is coming from Valet.

Because your Valet site is secured, your upstream configuration needs to be HTTPS. Otherwise you’ll be redirected outside of the HMR server by Valet / Nginx. For example:

app
    .setUrl('http://localhost:3000')
    .setProxyUrl('https://roots.test')
    .watch(['resources/views', 'app']);

HMR SSL is optional, and it doesn’t really matter whether it’s enabled or disabled in terms of hot reloading.

The key things to remember are:

  • Bud’s HMR is proxying your local dev server. You set the upstream URL with setProxyUrl()
  • Bud’s HMR will rewrite any resources matching your setProxyUrl() to setUrl() (or setPublicProxyUrl() in non-standard configurations)
  • If your dev server is sending a HTTP → HTTPS redirect, this rewriting won’t take effect, and you’ll end up outside of the HMR server.

Hopefully that’ll get you up and running!

Tom

1 Like

You’re right, I’m so close now. Changing those settings did work did stop the redirection. I appreciate the explanation.

I’m now able to visit http://localhost:3000/ and every change I make to styling triggers the appearance of a glowing blue circle in the lower-left corner of the screen. That must be HMR at work!

One last problem is that the styles still aren’t being injected, which looks to be a CORS issue:

Acess to fetch at ‘https://roots.test/web/app/themes/sage/runtime.3695a362123c1cca.hot-update.json/’ (redirected from ‘http://localhost:3000/web/app/themes/sage/runtime.3695a362123c1cca.hot-update.json’) from origin ‘http://localhost:3000’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

I’ll research this more later and see if there’s a solution, but it’s looking promising so far.

1 Like

Finally got HMR working with no errors! Thank you again for you help, @talss89. MUCH APPRECIATED :grinning:

I found this solution to fix the CORS issue on valet.

When working on a project with subdomains, you can run into CORS issues locally when using Laravel Valet when your assets are on the main domain.

You can solve this by creating a file at ~/.config/valet/Nginx/cors.conf that contains the following:

# CORS Rules
add_header Access-Control-Allow-Origin *;
# END of CORS Rules #
~/.config/valet/Nginx/cors.conf

Don’t forget to restart nginx after

valet restart nginx
1 Like