import { Link } from "@cloudflare/kumo";

export function LinkBasicDemo() {
  return (
    <div className="grid gap-x-6 gap-y-4 text-base md:grid-cols-3">
      <Link href="#">Default inline link</Link>
      <Link href="#" variant="current">
        Current color link
      </Link>
      <Link href="#" variant="plain">
        Plain inline link
      </Link>
    </div>
  );
}

安装

桶式导入

import { Link } from "@cloudflare/kumo";

子路径导入

import { Link } from "@cloudflare/kumo/components/link";

用法

基础链接

默认的 Link 组件渲染带下划线、主色样式的锚点链接。

import { Link } from "@cloudflare/kumo";

export default function Example() {
  return (
    <p>
      Read our <Link href="/docs">documentation</Link> for more details.
    </p>
  );
}

外部链接

使用 Link.ExternalIcon 子组件来标识会在新标签页中打开的链接。

import { Link } from "@cloudflare/kumo";

export default function Example() {
  return (
    <Link
      href="https://cloudflare.com"
      target="_blank"
      rel="noopener noreferrer"
    >
      Visit Cloudflare <Link.ExternalIcon />
    </Link>
  );
}

框架集成(LinkProvider)

要实现全应用的路由集成,请在应用根部配置 LinkProvider。你的包装组件 接收 href,负责桥接到你所用路由器的 API。这让工程师可以在任何地方使用 <Link href="...">,而无需关心路由内部实现。

import { forwardRef } from "react";
import { LinkProvider } from "@cloudflare/kumo";
import { Link as RouterLink } from "react-router-dom";

// Your app's wrapper maps href to the router's navigation prop
// and handles external URLs with a plain <a>
const AppLink = forwardRef(({ href, to, ...rest }, ref) => {
  const destination = href ?? to;
  const isExternal =
    destination?.startsWith("http") &&
    new URL(destination).origin !== window.location.origin;

  if (isExternal) {
    return <a ref={ref} href={destination} {...rest} />;
  }
  return <RouterLink ref={ref} to={destination} {...rest} />;
});

// Wrap your app once
export function App() {
  return (
    <LinkProvider component={AppLink}>
      {/* All <Link href="..."> calls go through AppLink */}
      <YourApp />
    </LinkProvider>
  );
}

使用 render 属性组合

在需要直接控制所渲染元素的特殊场景下,可使用 render 属性。这会完全绕过 LinkProvider,其余所有属性(hreftargetclassName 等)会自动 合并到所提供的元素上。

import { Link } from "@cloudflare/kumo";
import { Link as RouterLink } from "react-router-dom";

export default function Example() {
  return (
    <>
      {/* Force a specific router link (bypasses LinkProvider) */}
      <Link render={<RouterLink to="/dashboard" />} variant="inline">
        Dashboard
      </Link>

      {/* Force a plain anchor (bypasses LinkProvider) */}
      <Link render={<a />} href="https://example.com" target="_blank" rel="noopener noreferrer">
        External Site <Link.ExternalIcon />
      </Link>
    </>
  );
}

示例

段落内联

链接在段落文本中自然排布,下划线偏移量恰当。

This is a paragraph with an inline link that flows naturally with the surrounding text. Links maintain proper underline offset for readability.

import { Link } from "@cloudflare/kumo";

export function LinkInParagraphDemo() {
  return (
    <p className="mx-auto max-w-md text-base leading-relaxed text-kumo-default">
      This is a paragraph with an <Link href="#">inline link</Link> that flows
      naturally with the surrounding text. Links maintain proper underline
      offset for readability.
    </p>
  );
}

带图标的外部链接

使用 Link.ExternalIcon 从视觉上标识跳转到站外的链接。

import { Link } from "@cloudflare/kumo";

export function LinkExternalDemo() {
  return (
    <Link
      href="https://cloudflare.com"
      target="_blank"
      rel="noopener noreferrer"
      className="text-base"
    >
      Visit Cloudflare <Link.ExternalIcon />
    </Link>
  );
}

current 变体(颜色继承)

current 变体会从父级继承颜色,适用于 alerts 等彩色情境中的链接。

This error message contains a link that inherits the red color from its parent.

import { Link } from "@cloudflare/kumo";

export function LinkCurrentVariantDemo() {
  return (
    <p className="text-base text-kumo-danger">
      This error message contains a{" "}
      <Link href="#" variant="current">
        link
      </Link>{" "}
      that inherits the red color from its parent.
    </p>
  );
}

使用 render 属性组合

render 属性让你能将 Link 样式应用到任意元素上,从而实现与框架路由组件的集成。

import { Link } from "@cloudflare/kumo";

export function LinkRenderDemo() {
  return (
    <div className="flex flex-col gap-x-6 gap-y-4 text-base md:flex-row">
      <Link render={<CustomRouterLink href="/dashboard" />} variant="inline">
        Dashboard (via render)
      </Link>
      <Link
        render={
          <CustomRouterLink
            href="https://developers.cloudflare.com"
            target="_blank"
            rel="noopener noreferrer"
          />
        }
        variant="inline"
      >
        Cloudflare Docs <Link.ExternalIcon />
      </Link>
    </div>
  );
}

API 参考

继承所有原生锚点元素属性。

属性类型默认值描述
variant

“inline” | “current” | “plain"

"inline”视觉样式变体
renderReactElement-

要渲染的元素,Link 属性会合并到其上

hrefstring-

链接目标 URL。所有链接(内部和外部)都应使用此属性。可配置 LinkProviderhref 桥接到你的路由器。

tostring-

已弃用。请改用 href。该属性将在 未来主版本中移除。

classNamestring-额外 CSS 类
childrenReactNode-链接内容

变体

变体描述使用场景
inline主色带下划线行内文本链接的默认选择
current

继承父级文本颜色并带下划线

彩色情境中的链接(alerts、错误提示)

plain主色不带下划线导航链接、菜单、页脚

Link.ExternalIcon

用于标识外部链接的 SVG 图标组件,接受所有 SVG 元素属性。

<Link href="https://example.com" target="_blank" rel="noopener noreferrer">
  External Site <Link.ExternalIcon />
</Link>

设计指南

何时使用各变体

  • inline:正文内链接的默认选择

  • current:位于 alerts、banners 或其他彩色容器内的链接

  • plain:导航菜单、页脚,或下划线会造成干扰的场景

外部链接标识

  • 对于在新标签页打开的链接,始终使用 Link.ExternalIcon
  • 出于安全考虑,设置 target="_blank"rel="noopener noreferrer"

  • 该图标为用户离开当前网站的视觉提示

框架集成

  • 在应用根部配置 LinkProvider,以集成你的客户端路由器

  • 你的包装组件接收 href,并将其映射到路由器的导航属性 (例如 React Router 的 to

  • 包装组件应通过渲染普通 &lt;a&gt; 来处理外部 URL,而不是交给路由处理

  • 对于需要直接控制所渲染元素的特殊情况,可将 render 属性作为逃生舱

  • to 属性已弃用,所有链接目标请使用 href

无障碍

  • 链接默认可通过键盘聚焦
  • 外部图标带有 aria-hidden="true",请为屏幕阅读器添加描述文本

  • 确保所有变体都具有足够的颜色对比度
  • 使用描述性链接文本(避免“点击此处”)