A story of solving a hair pulling bug or How to make nested URLs in Next.js work properly on Netlify

Apr 11, 2021 · Updated: Jul 12, 2021 · by Tim Kamanin

Me and a team I work with just lost three days trying to solve a bizarre bug in a Next.JS project hosted on Netlify.

The bug caused an incomplete styling of a page that was under a dynamic nested route. The route itself was pretty straightforward, nothing fancy: blog/[slug]. Everything was done according to Next.js docs, and we were sure there's no mistake in our implementation. However, we clearly saw that the page behind that nested route was losing a bundle. It seemed like something wasn't loading, but there were no error messages or dead network connections to help us.

Perfect situation, right?

So I started digging and found out that in one of the JavaScript files that were loaded on the page, there was the following comment:

console output
/* No file found for /next/static/chunks/pages/blog/%5bslug%5d-5c8dfa3bff2a18911f75.js */

It means the file had been lost somewhere during the bundling process. But what was even more surprising is that, in the network inspector, I could clearly see that a file with the same name /next/static/chunks/pages/blog/%5Bslug%5D-5c8dfa3bff2a18911f75.js had been successfully loaded.

Even better…

After taking a closer look at the file name, I noticed a little difference between the name the file that wasn't found and the name of the loaded file. The difference was very subtle, but it still was there. Could you spot it?

Yes, it's the %5bslug%5d vs. %5Bslug%5D. In the latter case, the %5B was capitalized. %5B and %5D are HTML encodings of [ and ] respectively. The square brackets! In Next.js, square brackets define the dynamic part of a route.

So now I had a clue. There was something about the square brackets. And I started googling, but nothing.

Hmm… that's strange that no one had encountered the same bug. So maybe it's our code then?

But our code was ok; I even replaced square brackets with other square brackets, just in case; nope, that didn't help.

And then I thought, since the bug wasn't happening on the local machine or in a docker container, there had to be something with Netlify. But I couldn't believe that a bug with such a standard functionality, like dynamic routes, could had happened on Netlify. They would have fixed it by now, I thought.

My last resort was to try our project closer to its home and deploy it to Vercel, which stands behind the Next.js framework. If the bug didn't happen there, then Netlify was the cause of the issue.

Git clone. Deploy—page refresh. Hold your breath. Wooot? It works on Vercel! Shoot, give me a gun!

Ok, now we had the main suspect. Unfortunately, we couldn't move to Vercel because the client was with Netlify. Thus we had to make it work with Netlify.

I knew that Netlify should be doing something with files once the project is built. And sure enough, it turned out that in the Netlify panel, under Site settings > Build & deploy there's a Post processing menu. I opened it up and saw this:

Bundle JS Concatenate consecutive JS files together to reduce HTTP requests.

Epiphany, tears of joy, and the thrill of victory!

Netlify bundles JavaScript on top of already bundled JavaScript, which is bundled by the Next.JS export. And that breaks things!

So the solution was to disable JavaScript bundling in Netlify postprocess settings!

I could either uncheck this box, or, even better, I added the following line to the netlify.toml configuration file, which should be placed at the root of a next.js project:

  bundle = false

I saved the file, pushed the branch to Netlify, and sure enough, it worked!

Three days of banging heads against the wall have ended with those two lines of configuration

I don't know, my friend, whether you're reading this for entertainment, but if you're looking for a solution for that same bug, I know what you feel. Congratulations, the pain is over. Go push the branch and take a rest. And let me know on Twitter or by mailing me if this write-up was helpful. Peace.

P.S. To Netlify's defense, I must say that all optimization settings under Post processing are off when you create a new project. So someone should have turned them on before we jumped on the project. But who wouldn't enable the Bundle JS optimization? Netlify positions itself as the best platform for the JAMstack with lots of niceties included, so why wouldn't you enable that feature when you deploy a Next.js project? Yeah, I know... And now you know too, so be cautious.

Hey, if you've found this useful, please share the post to help other folks find it:

There's even more:

Subscribe for updates

  • via Twitter: @timonweb
  • old school RSS:
  • or evergreen email ↓ ↓ ↓