root@kaus.com:~/blog$ cat github-pages-jekyll-next-trap.md

Deploying a Next.js static export to GitHub Pages: the _next Jekyll trap

2026-07-16 · Lessons · 2 min read

GitHub Pages runs Jekyll by default, which silently drops any folder starting with an underscore, including Next.js's _next/ build output, so a clean-looking page and an empty console can hide a completely dead client bundle.

What happened

The first deploy of the static export to GitHub Pages looked complete. The homepage rendered from the server-rendered HTML shell, the text was all there, and the browser console showed zero errors. By that check, the deploy was done.

The failure underneath

GitHub Pages' legacy build process runs Jekyll by default, and Jekyll silently drops any top-level directory whose name starts with an underscore. Next.js ships a static export's JavaScript, CSS, and font files under _next/, exactly the kind of directory Jekyll ignores. Every file under _next/static/chunks/, the CSS chunk, and the font files came back 404, and nothing in the rendered page said so.

Client-side hydration depends on those files loading. With them gone, hydration never ran, and every client component on the site stayed dead: the projects grid's filter buttons, the search box, the grid/timeline toggle. The server-rendered shell those components attach to still looked complete, so the page read as working right up until someone tried to click something.

The fix

The fix is one empty file, .nojekyll, placed at the published root. Its presence tells GitHub Pages to skip Jekyll processing entirely, so _next/ and every other underscore-prefixed path ships untouched. It now lives at public/.nojekyll in this repo, so every static export carries it into out/ automatically. No manual step is needed, and no separate deploy script has to remember it.

The verification lesson

A clean-looking page and an empty console are not proof a static deploy works. Both checks passed here, and the client bundle was still completely broken. The failure only showed up in requests nobody had checked yet.

The actual check is the network tab: after any static deploy, look for 404s under the build-output path, _next/ for Next.js, or the equivalent for another framework. A server-rendered shell can look finished and still ship a client bundle that never loads a single file.

← All writing

>_ Kbit · writing · 1/3

The article is the primary path.

Read top to bottom; figures and code-linked examples stay inside the narrative.