一个 Next.js 路由中的两个不同子域

IT技术 javascript reactjs react-router next.js
2021-05-03 03:18:31

我想使用Next.jsReact.jsReact-router构建一个新平台会有两个空格。一个前端用于用户,另一个用于所有者,允许他们管理所有用户。我想将两个区域分成两个子域,如下所示:

front.domain.com panel.domain.com

React-router 不支持子域路由,所以我尝试寻找另一种方法。我发现了类似的东西,但我不确定这是我想要的。请指教。

<BrowserRouter>
  <Route path="/" render={props => {
    const [subdomain] = window.location.hostname.split('.');
    if (subdomain === 'panel') return <PanelLayout {...props}/>;
    return <FrontLayout {...props}/>;
  }}/>
</BrowserRouter>
4个回答

出于多种原因,您不能在子域之间拆分 1 个 Next.js 应用程序。根据经验,我有一个类似的要求(3 个区域),我从一个应用程序开始,将其拆分为 3 个(使用子路径)

  1. 资产(css、js 库)在“区域”之间泄漏。
  2. 一个包含 3 个区域的大应用意味着,每次更改都需要重新部署所有区域(一个大的可部署区域)
  3. 建造时间,建造3个区域会更长。
  4. 每个区域可能会引入不同的需求,例如,管理区域的 UI 组件,但“前端”区域的自定义 ui 组件、身份验证、翻译等等

最终得到 3 个独立的 Next.js 应用程序,这些应用程序在纱线工作区内部进行管理并由特定区域部署。

在我解释了我的经验之后,您可以使用反向代理(例如nginx)实现设置,以将子域映射到下一个应用程序中的子路径。

假设您有 3 个区域,前台、管理员、用户。

www.domain.com/some-page=> 应该映射到localhost:3000/front/some-page. users.domain.com/some-page=> 应该映射到localhost:3000/users/some-page. admin.domain.com/some-page=> 应该映射到localhost:3000/admin/some-page.

// www.domain.com.conf 

server {
    listen       80;
    server_name  www.domain.com;
    access_log   /var/log/nginx/access.log  main;
    root         html;
 
    location / {
      proxy_pass   http://127.0.0.1:3000/front/; // <-- the last slash is important
    }

  }
// users.domain.com.conf

server {
    listen       80;
    server_name  users.domain.com;
    access_log   /var/log/nginx/access.log  main;
    root         html;
 
    location / {
      proxy_pass   http://127.0.0.1:3000/users/; // <-- the last slash is important
    }

  }

注意

  1. 您还需要重写静态资产。

我设法使用自定义快速服务器创建子域。这是一个没有资产的空白应用程序,我还没有在带有资产(CSS、图像等)的真实应用程序上尝试过

我有以下页面文件夹结构:

pages/
├── admin/
│   ├── index.js
│   └── sample-page.js
└── member/
    ├── index.js
    └── accounts/
        └── dashboard.js

当您使用next dev默认值时。这将产生以下路线:

但是使用自定义server.js文件并使用node server.js运行我们的开发服务器将产生以下路由:

我们server.js文件的内容

const express = require('express')
const next = require('next')
const vhost = require('vhost')

const port = process.env.PORT || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  const mainServer = express()
  const adminServer = express()
  const memberServer = express()

  adminServer.get('/', (req, res) => {
    return app.render(req, res, '/admin', req.query)
  })

  adminServer.get('/*', (req, res) => {
    return app.render(req, res, `/admin${req.path}`, req.query)
  })

  adminServer.all('*', (req, res) => {
    return handle(req, res)
  })

  memberServer.get('/', (req, res) => {
    return app.render(req, res, '/member', req.query)
  })

  memberServer.get('/*', (req, res) => {
    return app.render(req, res, `/member${req.path}`, req.query)
  })

  memberServer.all('*', (req, res) => {
    return handle(req, res)
  })

  mainServer.use(vhost('admin.lvh.me', adminServer))
  mainServer.use(vhost('lvh.me', memberServer))
  mainServer.use(vhost('www.lvh.me', memberServer))
  mainServer.listen(port, (err) => {
    if (err) throw err

    console.log(`> Ready on http://lvh.me:${port}`)
  })
})

请参阅 repo 以查看此操作。

回购:https : //github.com/dcangulo/nextjs-subdomain-example

这是在同一个 Next.js 站点上托管多个域的示例(同时维护多种语言和静态站点生成/SSG),使用 Next.js 的 i18n 系统:

https://github.com/tomsoderlund/nextjs-multi-domain-locale

Vercel 现在支持通配符域(*.mysite.com),这很酷!

如果您在 Now 上托管,那么您可以使用他们的通配符域,并让您的客户端react代码相应地挂载与子域相关的组件树。