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

dojqjjoe  于 2023-01-08  发布在  React
关注(0)|答案(6)|浏览(191)

我想使用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>
hrysbysz

hrysbysz1#

你不能将一个Next.js应用程序拆分到不同的子域名,原因有很多。根据经验,我有一个类似的需求(3个区域),我开始将一个应用程序拆分为3个(使用子路径)
1.资产(css,js libs)在"区域"之间泄漏。
1.一个包含3个区域的大型应用程序意味着,每次更改都需要重新部署所有区域(一个大型可部署应用程序)
1.建造时间,要建造3个区域会长得多。
1.每个区域可能会引入不同的需求,例如,管理区域的UI组件,但"前端"区域的自定义UI组件、身份验证、翻译等
最终有3个独立的Next.js应用程序,它们在Yarn工作区内部管理,并由特定区域部署。
在我解释了我的经验之后,您可以在下一个应用程序中使用反向代理(如nginx)实现子域到子路径的Map。
假设您有3个区域,前台、管理员和用户。
www.domain.com/some-page =〉应Map到localhost:3000/front/some-pageusers.domain.com/some-page =〉应Map到localhost:3000/users/some-pageadmin.domain.com/some-page =〉应Map到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.您还需要重写静态资产。

wvt8vs2t

wvt8vs2t2#

我设法使用一个自定义的快速服务器创建子域。这是一个没有资产的空白应用程序,我还没有在一个真实的的应用程序上尝试过资产(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}`)
  })
})

请参阅回购协议以了解这方面的实际情况。
回购:https://github.com/dcangulo/nextjs-subdomain-example

uelo1irk

uelo1irk3#

下面是一个使用Next.js的i18 n系统在同一个Next.js站点托管多个域名(同时保持多种语言和静态站点生成/SSG)的示例:
https://github.com/tomsoderlund/nextjs-multi-domain-locale
Vercel现在支持通配符域(*.mysite.com),这很酷!

3duebb1j

3duebb1j4#

从现在开始,您应该可以使用Vercel的Next.js多租户中间件实现这一点。要了解更多信息,请访问https://vercel.com/guides/nextjs-multi-tenant-application
边注:Next.js的版本12及更高版本提供了中间件。

pprl5pva

pprl5pva5#

如果您现在托管在Vercel上,则可以使用它们的通配符子域,并让客户端React代码挂载与子域相关的组件树。

jdzmm42g

jdzmm42g6#

检查来自Next路由器的pathname是否以预定义的允许子路径列表开始
例如:

const subdomainPaths = {
  request: '/request',
  company: '/company',
};

const isSubdomainRoute = () => {
  const paths = Object.values(subdomainPaths).filter((path) => router.pathname.startsWith(path));
  return !!paths.length;
};

if (window.location.host.includes('subdomain.mysite') && !isSubdomainRoute()) {
  // show 404 or redirect somewhere else
  return <div>404 - not found</div>;
}

完整示例:

export const isSSR = typeof window === 'undefined';

export default function App(props: Props) {
  const { Component, pageProps } = props;
  const router = useRouter();

  const subdomainPaths = {
    request: '/request',
    company: '/company',
  };

  const isSubdomainRoute = () => {
    const paths = Object.values(subdomainPaths).filter((path) => router.pathname.startsWith(path));
    return !!paths.length;
  };

  if (!isSSR) {
    if (window.location.host.includes('subdomain.mysite') && !isSubdomainRoute()) {
      // show 404 or redirect somewhere else
      return <div>404 - not found</div>;
    }
  }

  // otherwise fallthrough to the normal Next.js return

  return (
    <>
      <Head>
        <title>My Site</title>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
      </Head>
      <AllTheProviders>
        <Component {...pageProps} />
      </AllTheProviders>
    </>
  );
}

相关问题