How to Fix an Error When Using a Custom Domain with Next.js on Heroku

When I first deployed my Next.js app to Heroku, everything worked perfectly on the default Heroku domain. But as soon as I added my custom domain, things went downhill quickly. Instead of my shiny new app, I got slapped with a confusing React error:

Minified React error #32
Invariant Violation

If you’ve run into this, you know the pain. Let me walk you through how I solved it step by step.

First Given Code

This was the basic setup of my Head component in Next.js:

import Head from 'next/head';

export default function MetaHead() {
  return (
    <Head>
      <title>Weboost</title>
      <link
        href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
        rel="stylesheet"
      />
      <meta name="viewport" content="initial-scale=1.0, width=device-width" />
      <meta name="robots" content="noindex, nofollow" />
    </Head>
  );
}

With this code, the site worked fine on:

Default Heroku domain: https://weboost.herokuapp.com/

But it broke with my custom domain:

Custom domain: https://search.weboost.com/

The Error and Why It Happen

That cryptic React error (#32) comes from a hydration failure. In plain English:

The HTML that Next.js renders on the server doesn’t match what React expects on the client side. When React tries to hydrate the page, it panics.

But why only on the custom domain?

Here are the most common culprits I discovered:

  • Domain or redirect setup issues
    Maybe the app was still serving content with references to herokuapp.com instead of my custom domain.
  • Mismatched protocols (HTTP vs HTTPS)
    If one part of your app expects https:// but the other tries to use http://, hydration fails.
  • Next.js assetPrefix misconfiguration
    If your assets (JS/CSS bundles) are loaded from the wrong domain, React can’t do its job.
  • Heroku proxy behavior
    Sometimes Heroku sets headers differently for the default domain vs. your custom one.

How I Fix It

Here’s what worked for me, step by step:

Add Domain Awareness in next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  trailingSlash: false,
  assetPrefix: process.env.NODE_ENV === 'production'
    ? 'https://search.weboost.com'
    : '',
};

module.exports = nextConfig;

This tells Next.js to serve static assets from my custom domain in production.

Properly Add the Custom Domain in Heroku

I had to make sure Heroku knew about my domain:

heroku domains:add search.weboost.com

Then I updated my DNS provider with the CNAME target provided by Heroku (something like weboost.herokuapp.com).

Finally, I forced HTTPS so all traffic used the right protocol:

heroku certs:auto:enable

Debug Hydration Locally

To make sure there were no hidden hydration mismatches, I ran the app in production mode locally:

npm run build
npm run start

This let me see warnings that don’t always show in development mode. I fixed any mismatched markup before deploying again.

Adding More Practice Functionality

Once the error was fixed, I decided to improve my Head component for SEO and flexibility. Here’s the upgraded version:

import Head from 'next/head';

export default function MetaHead({ title = "Weboost", description = "Boost your web presence" }) {
  return (
    <Head>
      <title>{title}</title>
      <meta name="description" content={description} />
      <link
        href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
        rel="stylesheet"
      />
      <meta name="viewport" content="initial-scale=1.0, width=device-width" />
      <meta name="robots" content="index, follow" />
      <link rel="icon" href="/favicon.ico" />
      <meta property="og:title" content={title} />
      <meta property="og:description" content={description} />
      <meta property="og:type" content="website" />
      <meta property="og:url" content="https://search.weboost.com/" />
      <meta property="og:image" content="/preview.png" />
    </Head>
  );
}

Now I can set dynamic titles and descriptions for each page:

<MetaHead title="About Us - Weboost" description="Learn more about Weboost" />

This makes the site way more SEO-friendly and flexible.

Final Thought

At first, seeing “Minified React error #32” scared me I thought something was seriously wrong with my app. But in the end, it wasn’t React’s fault at all. It was a simple mismatch between domains, assets, and how Heroku handled my custom setup. By properly setting the assetPrefix, configuring Heroku, and debugging hydration locally, I fixed the issue and even improved my project along the way.

Related blog posts