Back to Blog
Think First, Then AI

Think First, Then AI

The AI gave me the wrong answer. I almost used it.

By Emily Mirabella
April 11, 2026
Next.js, Firebase, React, AI tools, Debugging

I was staring at a 404 that had no business existing. The route was there. The file was there. I had just deployed. Everything looked fine until it wasn't.

This is that story — and the fix that actually worked.

---

## Some context

My portfolio runs on **Next.js with `output: 'export'` enabled**. That means a fully static build: HTML, CSS, JS, dropped into Firebase Hosting like files in a folder. No server. No edge functions. Nothing clever happening at runtime.

Blog posts live in Firestore. Each one has a dynamic route: `/blog/[slug]`.

When I pushed to production and clicked a blog link, I got this:

```

Error: Page "/blog/[slug]" is missing "generateStaticParams()"

so it cannot be used with "output: export" config.

```

Fine. Okay. I didn't know what that meant yet, but the error was at least pointing somewhere. So I did what you do when you're stuck and slightly embarrassed to be stuck — I asked an AI.

What every tool told me ?

GitHub Copilot. Claude. A couple others. Different interfaces, same answer:

Problem: this is a server component using async/await.

Static export mode has no server — this breaks at build.

New Firestore posts need a full rebuild to appear.

```

It looked right. It was formatted well. It had the kind of confidence that makes you want to just paste it in and move on.

I almost did.

---

## Why it's wrong? (and why the AI doesn't know that)

Here's the thing about `output: 'export'` — it means exactly what it says. You get a static export. Pure files. When someone loads your site, there is no Node.js process waiting to do anything. No server. Nothing running. Just a file being served.

`generateStaticParams` works in hybrid Next.js apps because there's a server involved at some point. In static export mode, it only pre-generates pages for slugs that exist **at build time**. Write a new post? Add it to Firestore? Great. It 404s until you rebuild and redeploy the entire site.

The AI wasn't lying. It just didn't know my constraint. It pattern-matched to the most common answer for dynamic routes in Next.js and that answer is usually correct. Just not here!

This is the part that stuck with me: it's not that the tools are broken.

It's that they're optimistic. The best/worst sort of cheerleader. They see "dynamic route" and they know the fix. They don't always notice the one flag in your config that changes everything.

That's on me to catch. And now I know to catch it.

---

## What actually works?

The fix is to stop fighting the static export and just work with it. Make the page a **client component**, use `useParams()` to read the slug, and fetch from Firestore at runtime in a `useEffect`. The HTML shell gets built statically — Firebase serves it — and the content loads after hydration.

Works: no server needed, route resolves at runtime.

Bonus: new Firestore posts appear instantly, no rebuild.

```

And there's an upside I didn't expect: because the data fetches at runtime instead of build time, new posts show up the moment they're in Firestore. No rebuild. No redeploy. The "limitation" of static export accidentally made the blog more live than it would have been with the server-component approach.

That felt really good. The kind of good that's specific to fixing something you were confused about for longer than you'd like to admit.

### The Firebase Hosting piece

One more thing — Firebase Hosting needs to know that any path under `/blog/` should serve the static shell, even if it doesn't recognize the slug. Add this rewrite to your `firebase.json`:

Example :

```json

{

"hosting": [{

"site": "your-site-id",

"public": "out",

"cleanUrls": true,

"rewrites": [{

"source": "/blog/**",

"destination": "/blog/[slug].html"

}]

}]

}

```

Without this, Firebase returns a 404 before your client-side code ever gets a chance to run. The shell never loads. Nothing works. It's a quiet failure, which is the worst kind.....

## What I took from this

AI tools are genuinely useful.. However, they're working from patterns, and sometimes your project has a constraint that breaks the pattern, a flag in a config file, a deployment target, a decision you made three weeks ago that you've half-forgotten about.

The tools won't always catch that. You have to!

Which means the skill isn't really "know all the answers."

It's "know enough to recognize when the answer you were just handed doesn't fit your situation."

I'm still building that skill. This was one rep.

![Image description]gs://portfolio-website-5b2f4.firebasestorage.app/blog/content/rookiemove2.png