Manually reload redirect rules?

I’m using metalsmith to build my site.

My development command looks like this:

netlify dev & nodemon --exec 'npm run build'

Which basically runs metalsmith which builds all my static files to ./build and then runs the Netlify dev server on that directory.

Whenever I make changes, nodemon re-runs my build (with metalsmith) which rebuilds all my files and sticks them in ./build

The problem is: my redirect rules in _redirects don’t get re-loaded by the netlify dev server. Or rather, they do get loaded but at the wrong time. They seem get loaded before metalsmith has a chance to rebuild my site.

For example, whenever I make a change to a file, I’ll see netlify and metalsmith log their output, which usually looks something like this:

[nodemon] restarting due to changes...
[nodemon] starting `npm run build`

> build
> node src/metalsmith.js

  metalsmith start; building +0ms
◈ Reloading redirect rules from [ 'netlify.toml' ]
  plugin-render-templates start +0ms
  plugin-render-templates finish +29ms
  metalsmith finish: processed 172 files +194ms

Note how netlify dev is reloading redirect rules, but not from my __redirects file. I assume this is because, at that point in time, it hasn’t detected that file exists? Or at least, nothing has changed. But often it has, I just need netlify to wait until my build has finished to then reload the redirect rules (which will be in ./build/__redirects)

Anybody else have this issue? I’m trying to think of the best way to get this working, where netlify’s dev server will reload rules but only once the build of static files has finished (as my __redirects rule has dynamic rules in it).

That, or is there someway to manually trigger it? That way I could just have the nodemon command be like npm run build && netlify dev:exec --reload or something?

hi there, before we dig in, did you see this brand new guide on debugging redirects?

I strongly suggest you give it a thorough read through and see if this fixes your problem:

Unfortunately I don’t see any resolution in there.

My problem is not with production. In fact, it’s not even with development. The _redirects work, but only when they get loaded. The problem is, they don’t always get loaded first.

I’m wondering if A) there’s a way to ensure that netlify dev tries to load them only after the build has run, or B) there’s a way to manually trigger netlify dev to try reloading the redirects.

Edit: After looking at the CLI code, it appears this chunk of code is doing the magic. It’s checking in the configured dist folder for a _redirects file and, in my case, that code is running before the build is done so it finds nothing and reloads no rules.

Hi, Thanks for that additional context. You have a few options:

A) You can modify your build process. By default, Netlify Dev uses the dist folder to serve the site. You can configure your build tool to generate the _redirects file in the dist folder as the last step of your build process. This way, when Netlify Dev starts, the redirects file will be available for it to load.

B) To manually trigger Netlify Dev to try reloading the redirects, you can use a file watcher or a task runner that monitors changes in your project files. When any file changes, you can trigger the rebuild process that generates the _redirects file. From there, Netlify Dev will automatically detect the changes and reload the redirects.

Here are a few resources to manually trigger:

https://gulpjs.com/

A) the _redirects file is being generated correctly, the problem is that the netlify CLI reloads the redirects before the build is done generating _redirects, so it doesn’t notice that the file changed (even though it has, just like 1 second too late)

B) I’m already use nodemon to watch for file changes, the _redirects file is being re-generated correctly, but netlify dev is not picking up the file change. Again, I’m guessing this is because it’s watching dist and noticing that files changed and reloading them, but that is happening concurrently with the build process rebuilding files, so netlify is reloading the redirect rules too late.

I believe this is what’s happening:

  • nodemon triggers restart
  • build process begins generating new files
  • netlify reloads redirects (doesn’t notice a _redirect file)
  • build processes finishes generating all files (including the _redirects file)

I don’t want to restart netlify dev every time a file changes, but I do need some way of telling netlify dev “don’t try reloading files in dist until the SSG is finished generating stuff in dist

This doesn’t sound like an issue other people run into often. And there doesn’t appear to be a way to tell netlify dev, when it’s already running, “ok, reload any redirects”.

Is it possible to write the redirects to a temp file first and once they’re all generated add them to _redirects? If that’s achievable looks like the problem can be solved?

Actually yes, that does appear to work! TY.


For anybody interested, here’s what I learned:

I am using metalsmith and i’m using their .clean() API which deletes the build directory each time it runs. This causes netlify to look for a dist/ folder with a _redirects file when changes are made and it doesn’t find them because the folder has been deleted (albeit for just a few seconds while the build runs).

Previous code:

Metalsmith(__dirname)
  .source("./src")
  .destination("./dist")
  // Deletes the ./dist folder
  .clean(true)
  // SSG logic that builds a bunch of files in memory
  // (takes a couple seconds)
  .use(...)
  // Write those files to disk at ./dist
  .build(...);

To fix this, as soon as .clean() runs, I immediately generate a new .dist/ folder with a blank _redirects file in it. Netlify seems to pick this up and knows where to look for redirects, and when Metalsmith finishes it’s build, it puts the whole _redirects file in .dist/ with all my redirects

Metalsmith(__dirname)
  .source("./src")
  .destination("./dist")
  .clean(true)
  // Immediately create the new ./dist folder
  .use(() => {
    // Only run in dev mode
    if (process.env.NODE_ENV !== 'production') {
      fs.mkdirSync("./dist");
      fs.writeFileSync("./dist/_redirects", "");
    }
  })
  .use(...)
  .build(...);

This fixes the issue and seemingly allows netlify to know there’s going to be a _redirects file in the ./dist folder once the build finishes.

Wow awesome! Thanks for your detailed explanation. This will help users who stumble upon this thread in the future. Great work. :partying_face: