首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将Vercel/Nextjs项目作为不同Vercel/Nextjs项目的子目录挂载问题

将Vercel/Nextjs项目作为不同Vercel/Nextjs项目的子目录挂载问题
EN

Stack Overflow用户
提问于 2022-09-05 10:01:54
回答 3查看 413关注 0票数 5

我有两个项目-- webdocs。每一个都是他们自己的Vercel项目,web项目安装在https://example.comdocs安装在https://docs.example.com。所有这些都如预期的那样工作。

现在,我希望docs项目可以在https://example.com/docs上使用。在web项目中,我在vercel.json文件中设置了以下重写。

代码语言:javascript
运行
复制
{
  "rewrites": [
    {
      "source": "/docs/:match*",
      "destination": "https://docs.example.com/:match*"
    },
    { "source": "/(.*)", "destination": "/" }
  ]
}

这适用于主索引文件,但是所有对应的css和js文件都会导致404。浏览器在下一首查找那些不正确的文件,应该是查看下一首

我该怎么做呢?

EN

回答 3

Stack Overflow用户

发布于 2022-09-12 06:58:22

rewriteredirect

让我们先了解一下这个区别。

重写是只发生在服务器上的事情。服务器将重写已请求的URL并搜索该重写URL的内容。客户对此一无所知。例如,如果/a.html被重写为/b.html,客户端将在两个URL上接收相同的内容。客户端将不知道是否有两次相同的文件,或者是否有一个请求(或两个请求)被重写到其他资源。

另一方面,重定向涉及客户端(即浏览器)。如果服务器需要一个应该被重定向的URL,它将用重写的目标URL回复到客户机/浏览器。然后,客户端将为新URL发送另一个请求,并通过更改导航栏中的地址使其对最终用户可见。如果/a.html被重定向到/b.html,则在请求a.html时,客户端将不会收到b.html的实际内容,但是浏览器将更新地址到b.html并发送新请求。

在你的案例中重写有什么问题?

HTML包含对使用绝对路径的其他资源的引用,例如:

代码语言:javascript
运行
复制
<script src="/_next/static/..."></script>

如果这个文件应该被用作docs.example.comexample.com/docs (例如使用重写),那么实际的HTML不会改变。因此,浏览器将尝试分别访问docs.example.com/_next/static/...example.com/_next/static/...。这适用于第一种情况(docs.example.com),但不适用于第二种情况。你已经注意到了。

您可以将next的basePath更改为/docs。然后HTML将包含<script src="/docs/_next/...">。这将分别使浏览器请求docs.example.com/docs/_next/...example.com/docs/_next/...。这将适用于第二种情况,但不适用于第一种情况。你可以用更多的重写规则来治愈第一个病例,但我建议一个吻解决方案。

这次又是什么?

正如评论中提到的,将完全相同的内容放在两个不同的地址并不是好的做法。你可以看到,这也导致了随后的困难。(更别提搜索引擎对重复内容的处罚了。)

一个好的解决方案是决定在哪里存储内容。这应该是docs.example.comexample.com/docs,而不是两者兼而有之。

使用docs.example.com将example.com/docs/转发给docs.example.com

我建议(并假设在本节中)采取docs.example.com有一个明确的关注点分离。

所以在Vercel,你会建立两个项目。一个用于“主”下一个实例,另一个用于"docs“下一个实例。(两者都可以来自同一个回购,这并不重要。)

然后将域分配给两个项目,例如,www.example.com分配给“主”项目,docs.example.com分配给"docs“项目。example.comdocs.example.com现在应该都在工作。example.com/docs/应该会产生404错误。

然后添加重定向(而不是重写!)为您的“主”项目添加如下所示的vercel.json

代码语言:javascript
运行
复制
{
  "redirects": [
    { "source": "/docs/:path*", "destination": "https://docs.example.com/:path*" }
  ]
}

现在,如果在浏览器中输入example.com/docs/foo,则应该重定向到docs.example.com/foo,并且页面应该正确加载。

仅使用example.com/docs/

如果您决定只在example.com/docs/上使用docs内容,则解决方案如下:

  • basePath: '/docs'添加到docs下一个项目的next.config.js中。不要向此vercel项目添加域。
  • 在“主”下一个项目中添加一个vercel.json,并进行如下重写:
代码语言:javascript
运行
复制
{
  "rewrites": [
    { "source": "/docs", "destination": "https://$domain-of-docs-project.vercel.app/docs" },
    { "source": "/docs/:path*", "destination": "https://$domain-of-docs-project.vercel.app/docs/:path*" }
  ]
}

请评论,如果你有额外的问题或这不能解决问题。

票数 4
EN

Stack Overflow用户

发布于 2022-09-12 01:09:13

我认为您可以这样使用vercel.json

代码语言:javascript
运行
复制
{
  "rewrites": [
    {
      "source": "/:path*",
      "has": [
        {
          "type": "host",
          "value": "docs.example.com"
        }
      ],
      "destination": "/docs/:path*"
    }
  ]
}

票数 0
EN

Stack Overflow用户

发布于 2022-09-13 18:14:31

接下来给出了一个具体的例子。

您的"web“项目应该处理重写,如这里所示。next.config.js:

代码语言:javascript
运行
复制
const { DOCS_URL } = process.env //this should be the vercel URL NOT docs.example.com

/** @type {import('next').NextConfig} */
module.exports = {
  async rewrites() {
    return [
      {
        source: '/:path*',
        destination: `/:path*`,
      },
      {
        source: '/docs',
        destination: `${DOCS_URL}/docs`,
      },
      {
        source: '/blog/:path*',
        destination: `${BLOG_URL}/docs/:path*`,
      },
    ]
  },
}

您的"docs“应用程序需要设置一个基本路径,如这里所示。next.config.js:

代码语言:javascript
运行
复制
    module.exports = {
      basePath: '/docs',
    }

然后,为了确保docs.example.com不再为文档提供服务,我只需删除DNS记录即可。相反,您将只有一个vercel URL,您将在重写中使用"web“。无需从docs.example.com指向该服务器。

多区域的Nextjs文档

具有多个区域的Nextjs示例

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73607646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档