当您想使用 Link 组件时,外部 link 在 Next.js 中不起作用

External link is not working in Next.js when you want to use Link component

令我感到非常惊讶的是,一个简单的 Link 组件在其中的 Next.js when you want to use an external URL and HTML Button tag 中无法正常工作。

下面你可以看到我是如何尝试解决问题的:

方法数 1:

<Link href="https://whosebug.com/">
  <button>Whosebug</button>
</Link>

方法编号 2(link 无协议):

<Link href="//whosebug.com/">
  <button>Whosebug</button>
</Link>

方法编号 3(link 无协议且 Link 属性 prefetch 设置为 false 甚至 true):

<Link href="//whosebug.com/" prefetch={false}>
  <button>Whosebug</button>
</Link>

重要提示

当然,提到的情况是 URL 是内部的,就像这样:

<Link href="/Whosebug">
  <button>Whosebug</button>
</Link>

或者当我将 HTML 按钮标签更改为 HTML A tag 时,像这样:

<Link href="//whosebug.com/">
  <a>Whosebug</a>
</Link>

就我而言,我想在 Next.js Link 组件中使用 HTML 按钮标签或任何其他 UI 组件。

Link 组件仅用于在您的 Next 应用程序中的页面之间进行链接。传递外部 URL 是不受支持的行为,并且应该给您一个链接到 this page 的错误,其中包括以下部分:

Why This Error Occurred

Next.js provides a router which can be utilized via a component imported via next/link, a wrapper withRouter(Component), and now a hook useRouter(). When using any of these, it is expected they are only used for internal navigation, i.e. navigating between pages in the same Next.js application.

Either you passed a non-internal href to a next/link component or you called Router#push or Router#replace with one.

Invalid hrefs include external sites (https://google.com) and mailto: links. In the past, usage of these invalid hrefs could have gone unnoticed but since they can cause unexpected behavior. We now show a warning in development for them.

如果您在内部呈现 <a>,href 将传递给它并使用本机浏览器行为按预期工作,但其他元素无法使用它,因此您必须自己处理这种情况。

不过,我建议看看您要实现的目标 -- 使用 <a> 标签有什么问题?这似乎是完成这项工作的正确工具。

1. Next.js Link 组件内 UI 组件的解决方案。

我更详细地研究了 Next.js 文档,我发现了一个非常有用的属性,可以为任何内部 UI 组件(Semantic UI, Material UI, Reactstrap 等)创建外部 link .) 在 Link 组件内。

让我们以一个简单的语义UI按钮组件为例。 要将外部 link 添加到 Next.js Link 组件,我们应该使用属性 passHref。默认情况下,此属性设置为 false。此属性强制 Link 将 href 属性 发送给其子项。

import { Button } from 'semantic-ui-react';
import Link from 'next/link';    

const Example = () => (
  <Link href="https://whosebug.com/" passHref={true}>
    <Button>Whosebug</Button>
  </Link>
)

export default Example;

2。 HTML 元素的解决方案(与标签 A 不同)

在 Next.js 文档中,您可以找到以下句子:

External URLs, and any links that don't require a route navigation using /pages, don't need to be handled with Link; use the anchor tag for such cases instead.

而且我必须写的很明显,所以在那种情况下,如果你需要使用任何其他标签,例如 HTML 按钮,你应该在上面使用 onClick 事件没有 Link 组件。 上面的代码将如下所示:

const clickHandle = () => {
  document.location.href = 'https://whosebug.com/';
}

const Example = () => (
  <button onClick={clickHandle}>Whosebug</button>
)

export default Example;

更新: 当然,我同意为外部 link 编写的开发人员的意见,我们不应该使用 Link 组件。这里最好的解决方案是只使用纯 HTML a 标签或 JS 重定向解决方案,如第 2 点所示(或任何类似方式)。值得一提的是,您可以构建自己的组件,并根据传递的 href 属性,您可以在 Link 组件和 HTML a 标签之间切换,如下所示:

  // custom simple smart Link component
  import Link from 'next/link'; 
  
  const SmartLink = (link, url) => {
    const regEx = /^http/;

    return regEx.test(url) ? <Link href={url}>{link}</Link> : <a href={url}>{link}</a>;
  }
  
  export default SmartLink;

  // ways to call the component
  import SmartLink from 'path/to/SmartLink'; // set correct path

  // somewhere inside the render method
  // the below will use HTML A tag
  <SmartLink href="https://whosebug.com" link="external Whosebug website" />
  // the below will use Next.js Link component
  <SmartLink href="/Whosebug" link="internal Whosebug page" />

在我看来,接受的答案是错误的。 passHref<a> 标签不是 <Link> 的子标签时使用。对于外部 URL,只需使用 <a> 而不用 <Link>,见下文。

  const link = props.link.charAt(0) === '/' ? <Link as={stripUrlPlaceholder(props.link)} href="/">
    <a>{image}</a>
  </Link> : <a href={props.link} rel="noreferrer" target="_blank">{image}</a>;

  return <div className="banner">
    {link}
  </div>;

我遇到了同样的问题,不知何故我尝试了上面的答案,但并没有多大帮助。我发现如果你在里面加上https或者HTTP://,肯定会自动让你打开外网。这里有一个示例:

<a href={`https://${Your link}`}> Open external Link </a>

外部链接不需要使用 next/link,因为它仅用于路由之间的客户端转换。 Link 不适用于您的应用外部链接。

简单地说,使用 <a> 标签而不是下一个 <Link>。接下来<Link>用于内部导航。

示例 1.

   <a
     href='https://www.facebook.com/queueunderstop/'
     target={"_blank"}
     rel={"noreferrer"}>
       <Image
         className='gb'
         src='/images/icons/fb.png'
         alt='facebook'
         width={25}
         height={25}
       />
   </a>

这解决了 link 打开新 link 同时关闭主站点的问题。主要需要注意的是属性:

  1. target={"_blank"}
  2. rel={"noreferrer"}

我也尝试了各种组合,并在仔细阅读文档后找到了这个,即使文档没有暗示它。这些文件涵盖了更多的事实,而不是所有的假设。