https://github.com/acorcutt/next-multi-host
Multiple domains hosting on next.js
https://github.com/acorcutt/next-multi-host
nextjs
Last synced: 4 months ago
JSON representation
Multiple domains hosting on next.js
- Host: GitHub
- URL: https://github.com/acorcutt/next-multi-host
- Owner: acorcutt
- Created: 2021-04-30T18:15:06.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2021-10-27T12:31:14.000Z (about 4 years ago)
- Last Synced: 2025-03-06T13:02:03.878Z (9 months ago)
- Topics: nextjs
- Language: JavaScript
- Homepage: https://next-multi-host.vercel.app
- Size: 273 KB
- Stars: 56
- Watchers: 3
- Forks: 4
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- jimsghstars - acorcutt/next-multi-host - Multiple domains hosting on next.js (JavaScript)
README
#### ⚠️ [next.js v12+](https://nextjs.org) now supports [middleware](https://nextjs.org/docs/middleware) which can be used for [hostname-rewrites](https://github.com/vercel/examples/tree/main/edge-functions/hostname-rewrites) and more!
---
# Multiple domain hosting on [next.js](https://nextjs.org) using [rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites)
Using rewrites to support multiple hosts with caching, fallbacks and static rendering.
## Example
[Host 1](https://next-multi-host.vercel.app) - [Host 2](https://next-multi-host-acorcutt.vercel.app)
## How it works
It uses [next rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites) to rewrite a url like https://next-multi-host.vercel.app/posts/a to `/pages/hosts/[host]/posts/[id]` style routes so you can use the `:host` parameter in your page routes along with static generation and [ISR](https://nextjs.org/docs/basic-features/data-fetching#incremental-static-regeneration).
## Instructions
Create a page in the format `/pages/hosts/[host]/posts/[id].js` and add the following to your `next.config.js` rewrites section:
```
{
has: [
{
type: 'host',
value: '(?.*)',
},
],
source: '/posts/:id',
destination: '/hosts/:host/posts/:id',
},
```
Use the `:host` parameter in your page just like other dynamic parameters.
```
export async function getStaticProps(context) {
// Available on server render
console.log('getStaticProps', context);
const host = context.params.host;
const id = context.params.id;
return {
props: {
host,
id,
},
revalidate: 10,
};
}
```
Create required static paths with additional host param...
```
export async function getStaticPaths() {
return {
paths: [
// Include host in static params!
{ params: { id: 'a', host: 'localhost' } },
{ params: { id: 'a', host: 'next-multi-host.vercel.app' } },
{ params: { id: 'a', host: 'next-multi-host-acorcutt.vercel.app' } },
],
fallback: 'blocking',
};
}
```
## Testing
### Localhost
Add domains to your hosts file or use localhost subdomains to test your site...
http://localhost:3000/posts/a - http://domain.localhost:3000/posts/a
### Cypress
Cypress has an unsupported option to use localhost subdomains for testing, just add the following to your `cypress.json` file...
```
{
"hosts": {
"*.localhost": "127.0.0.1"
}
}
```
## Limitations
### Wildcard paths do not work too well with other overlapping routes
```
{
has: [
{
type: 'host',
value: '(?.*)',
},
],
source: '/slugs/:slug*',
destination: '/hosts/:host/slugs/:slug*',
},
```
Use a rewrite for every combination of paths where possible or fallback to standard SSR.
### It gets complicated when mixing with other rewrites and headers
You will need to add a rewrite for every combination of paths and headers you use, and not all headers work.
## Tips
For complicated rewrites and multiple headers try combining them into one parameter and decoding the value on the server:
```
{
has: [
{
type: 'host',
value: '(?.*)',
},
{
type: 'query',
key: 'x',
value: '(?.*)',
},
{
type: 'cookie',
key: 'c',
value: '(?.*)',
},
],
source: '/posts/:id',
destination: '/h/:host--:x--:c/posts/:id',
},
```
`/pages/h/[headers]/posts/[id].js`
```
export async function getStaticProps(context) {
const headers = context.params.headers.split('--');
return {
props: {
headers,
id:context.params.id
},
};
}
```