2 applications in 1 project(with route groups) served on 2 domains on vercel
Answered
Broad-snouted Caiman posted this in #help-forum
Broad-snouted CaimanOP
I have question for the nextjs and vercel gurus ..
Is it possible for me to deploy a sub directory of an app to vercel(with a custom sub domain e.g form.example.com) while still having the rest of the same application on the main domain(e.g example.com)?
I need to build 2 applications that are kinda related but I don’t want to have to spin up 2 separate nextjs projects to do so, and I need both hosted / served on different domains
Is it possible for me to deploy a sub directory of an app to vercel(with a custom sub domain e.g form.example.com) while still having the rest of the same application on the main domain(e.g example.com)?
I need to build 2 applications that are kinda related but I don’t want to have to spin up 2 separate nextjs projects to do so, and I need both hosted / served on different domains
Answered by Broad-snouted Caiman
I have added a condition and seems to work now, but will still test around to make sure
export function middleware(request: NextRequest) {
const pathname = request.nextUrl.pathname;
console.log("pathname", pathname);
if (pathname.startsWith("/_next")) {
return NextResponse.rewrite(
new URL(`http://localhost:3000/${pathname}`, request.url)
);
} else {
return NextResponse.rewrite(
new URL(`http://localhost:3000/payment-link/${pathname}`, request.url)
);
}
}
41 Replies
Reproducing my answer in general:
Yes, that’s a multi tenant app.
You have the forms at example.com/forms/:path for example, then rewrite from form.example.com/:path to example.com/:path
Yes, that’s a multi tenant app.
You have the forms at example.com/forms/:path for example, then rewrite from form.example.com/:path to example.com/:path
Broad-snouted CaimanOP
Could you please explain the last part? ie the rewrite path
Broad-snouted CaimanOP
here’s what I’m kinda cunning for;
app/(main)/…
app/(form)/[id]
I need pretty much the rest of the application ie things inside (main) to run on the main domain eg example.com and example-app.vercel.app
Then the (form) part would then just run on a sub domain like form.example.com such that when a request comes in like form.example.com/randomuniqueID it can map to app/(form)/[id].tsx
app/(main)/…
app/(form)/[id]
I need pretty much the rest of the application ie things inside (main) to run on the main domain eg example.com and example-app.vercel.app
Then the (form) part would then just run on a sub domain like form.example.com such that when a request comes in like form.example.com/randomuniqueID it can map to app/(form)/[id].tsx
How can I accomplish this?
so i assume you have set up (or know how to set up) the /forms/:path routes
then you have two choices:
1. deploy to a wildcard domain (*.example.com), then you can [check for the hostname of the request](https://github.com/vercel/platforms/blob/29e20e790eaf17d4d5051c23a69636dce724c174/middleware.ts#L21-L23), then [rewrite/redirect to the subpath accordingly if the subdomain is
this requires you to deploy to a deployment hosting platform supporting wildcard domains though. vercel is one of them, but many services don't support hosting webapps to wildcard domains
2. deploy a separate app to
then you have two choices:
1. deploy to a wildcard domain (*.example.com), then you can [check for the hostname of the request](https://github.com/vercel/platforms/blob/29e20e790eaf17d4d5051c23a69636dce724c174/middleware.ts#L21-L23), then [rewrite/redirect to the subpath accordingly if the subdomain is
form
](https://github.com/vercel/platforms/blob/29e20e790eaf17d4d5051c23a69636dce724c174/middleware.ts#L71-L72) using middlewarethis requires you to deploy to a deployment hosting platform supporting wildcard domains though. vercel is one of them, but many services don't support hosting webapps to wildcard domains
2. deploy a separate app to
form.example.com
that perform the rewrite. that app can be a tiny nextjs app with the rewrite rule handled in next.config.js
, but can be written in a separate framework too. this only works if you have a limited number of subdomains, so things like [username].example.com
won't work, but form.example.com
will workyes so rename
(form)
to form
so all pages in form.example.com
live under a subpath /form
then do this
and rewrite requests to form.example.com to example.com/form
Broad-snouted CaimanOP
Wouldn’t this rewrite change the url?
Oh never mind, rewrites don’t change the url
Alright, thanks
no thats a redirect. [rewrites dont change the url](https://nextjs.org/docs/app/api-reference/next-config-js/rewrites)(
yes
Broad-snouted CaimanOP
If I have further questions or need some more insights can I contact you here or in dm?
ping me here
Broad-snouted CaimanOP
Ok then
Broad-snouted CaimanOP
@joulev
Hey, got on update on my lil problem
So I spun up another nextjs app, in that app, added the following rewrite to the config
I started this second app in dev mode on port 4000, while I have my main app running on 3000
The main app have the following file structure;
app
(main)
[id]
form
[id]
The rewrite works, how ever I noticed that styles don’t apply when I run the app from the form app(ie where the rewrite is)
Hey, got on update on my lil problem
So I spun up another nextjs app, in that app, added the following rewrite to the config
async rewrites() {
return [
{
source: "/:path*",
destination: "http://localhost:3000/form/:path*",
},
];
},
I started this second app in dev mode on port 4000, while I have my main app running on 3000
The main app have the following file structure;
app
(main)
[id]
form
[id]
The rewrite works, how ever I noticed that styles don’t apply when I run the app from the form app(ie where the rewrite is)
This is what page looks like on the main app
url: localhost:3000/form/:something
url: localhost:3000/form/:something
This is what it looks like on the rewrite side
localhost:4000/:something
localhost:4000/:something
No styles seem to be applied
Correct yep, you need to handle static bundle files separately:
If the pathname starts with /_next (indicating a bundled file), rewrite without the subpath (like /payment-link). Else add the subpath to the rewrite
If the pathname starts with /_next (indicating a bundled file), rewrite without the subpath (like /payment-link). Else add the subpath to the rewrite
I think you might need middleware for this, the rewrites() in the config file might not be versatile enough
Broad-snouted CaimanOP
Could u give an example of what I could add to middleware?
So firstly can you rewrite this to a middleware?
This one
Broad-snouted CaimanOP
I have created a middleware.ts file in the rewrite application and added the following code
ran the app again, and got a 404 error
export function middleware(request: NextRequest) {
const pathname = request.nextUrl.pathname;
return NextResponse.rewrite(
new URL(`http://localhost${pathname}`, request.url)
);
}
// See "Matching Paths" below to learn more
export const config = {
matcher: "/:path*",
};
ran the app again, and got a 404 error
oh wait
i have updated the code
still did'nt work
return NextResponse.rewrite(
new URL(`http://localhost:3000/${pathname}`, request.url)
);
still did'nt work
I know I’m probably doing something wrong but not sure what it is
@joulev
Broad-snouted CaimanOP
Got it to work… thanks 🙂
Oh you got it working? Glad to know, sorry for not being able to help with specific code yet because I’ve been away from my laptop all day
Broad-snouted CaimanOP
Actuality it didn’t work exactly as intended
Still getting no styles if I rewrite to
but if I rewrite to
styles work, and thats the wrong place to rewrite to
Still getting no styles if I rewrite to
http://localhost:3000/payment-link/${pathname}
but if I rewrite to
http://localhost:3000/${pathname}
styles work, and thats the wrong place to rewrite to
Broad-snouted CaimanOP
I have added a condition and seems to work now, but will still test around to make sure
export function middleware(request: NextRequest) {
const pathname = request.nextUrl.pathname;
console.log("pathname", pathname);
if (pathname.startsWith("/_next")) {
return NextResponse.rewrite(
new URL(`http://localhost:3000/${pathname}`, request.url)
);
} else {
return NextResponse.rewrite(
new URL(`http://localhost:3000/payment-link/${pathname}`, request.url)
);
}
}
Answer
yes it looks good to me. that should work yes
pathname
already starts with /
so you might want to use http://localhost:3000${pathname}
and http://localhost:3000/payment-link${pathname}
instead(ping)
Broad-snouted CaimanOP
Oh; ok got it
btw (obviously) don't forget to change
localhost:3000
to your actual domain when deploying. you probably want to check for process.env.NODE_ENV
hereBroad-snouted CaimanOP
Yea already did that too… I just introduced a new env variable called BASEHOST, and then I use that in place of hardcoding localhost
That way when we deploy on vercel we can also just add the vercel application domain there and it should just work
That way when we deploy on vercel we can also just add the vercel application domain there and it should just work
West African Lion
Could you help me on my question ? about middleware ?