I'm sure there's a simple answer to this... I've got a Next.js v14 app running in a container which is exposed on port 6502. I can reach it using http://localhost:6502 and everything works. Now I want to use Apache's reverse proxy to serve up the site but when I do, I get all kinds of problems with the wrong URLs showing up (i.e. paths missing).
Here's an excerpt of my next.config.mjs file (isProd
is already set to true
):
output: "standalone",
assetPrefix: isProd ? "http://mydomain/myapp" : undefined,
// Optional: Change links `/me` -> `/me/` and emit `/me.html` -> `/me/index.html`
trailingSlash: true,
And in my apache config file:
ProxyPreserveHost On
ProxyRequests Off
ProxyPass "/myapp" "http://localhost:6502/"
ProxyPassReverse "/myapp" "http://localhost:6502/"
The docker container is running on the same server that apache is running on.
With this config, when I go to http://mydomain/myapp the page is rendered but without images (which are saved under /public/images in my Next.js project). When I click on a link in that page it should take me to another page in the same app (i.e. /src/app/update/page.tsx) but instead it gets redirected to http://mydomain/update and not http://mydomain/myapp/update. I've played around with assetPrefix
and even basePath
in next.config.mjs to no avail. Instead of continuing to waste hours troubleshooting this I figured I'd ask here.
The main solution to this issue was to remove the domain name from assetPrefix
in next.config.mjs and export it as an environment variable:
const isProd = process.env.NODE_ENV === "production";
assetPrefix: isProd ? "/myapp" : "http://localhost:3000";
const nextConfig = async (phase, { defaultConfig }) => {
return {
env: {
ASSET_PREFIX: assetPrefix, // Assigned at BUILD time
},
assetPrefix: assetPrefix,
...
};
};
export default nextConfig;
Then pass it to my client components as a prop from the page.tsx file which runs on the server side:
"use server";
export default async function Page() {
return Promise.resolve(
<MyComponent assetPrefix={process.env.ASSET_PREFIX} />
};
}
Finally, prepend the prefix to all my hyperlinks in MyComponent
:
<Link href={`${props.assetPrefix}/mypage`}`>Click</Link>`