@fast-link/next

中文文档
0.0.2发布于 2026/11/03MITTypeScriptES Module构建来源已验证近 30 天下载 1万

Early mouse navigation for Next.js App Router links

原始使用文档
文档目录18 节
  1. Requirements
  2. Install the package
  3. Choose an interface
  4. Configure one link
  5. Add Fast Link to a navigation region
  6. Configure a Next.js base path
  7. Leave one region link on its normal path
  8. Understand navigation and click behavior
  9. Pending state
  10. Route links across application boundaries
  11. Build a custom renderer
  12. API reference
  13. Options shared by links, regions, and hooks
  14. FastLink
  15. FastLinkRegion
  16. useFastLink
  17. Navigation policy types
  18. Exports

▲ @fast-link/next

@fast-link/next starts eligible primary-mouse navigation on pointerdown in a Next.js App Router application. It provides components for existing link regions and individual links, plus a hook for custom renderers.

For press timing and opt-outs, see when to use Fast Link.

Install · Choose an interface · One link · Regions and base paths · Navigation and pending state · Routing policies · Custom renderers · API reference

Sites requiring WCAG Level A or AA conformance should leave Fast Link disabled. See the accessibility limitation.

Requirements

Supports Node.js 22 or later, with Next.js 16 (>=16 <17) and React 19 (>=19 <20). Requires the Next.js App Router.

Install the package

npm install @fast-link/next

The Fast Link agent skill is included at skills/fast-link/SKILL.md.

Choose an interface

InterfaceUse it for
FastLinkOne App Router link with its own Link options
FastLinkRegionExisting links sharing one navigation policy
useFastLinkA custom component that renders the anchor

Use FastLink when one link needs its own Next.js behavior:

import { FastLink } from '@fast-link/next';

export function AccountLink() {
  return (
    <FastLink href="/account" replace scroll={false}>
      Account
    </FastLink>
  );
}
  • Supports Next Link options, including object href.
  • Preserves Next Link prefetching and native activation.
  • Keeps its own options and policy inside a FastLinkRegion, even when disabled.

Wrap existing next/link or anchor elements that share one navigation policy:

import { FastLinkRegion } from '@fast-link/next';
import Link from 'next/link';

export default function Navigation() {
  return (
    <FastLinkRegion>
      <nav>
        <Link href="/overview">Overview</Link>
        <Link href="/pricing">Pricing</Link>
      </nav>
    </FastLinkRegion>
  );
}
  • Use FastLink for per-link options. It keeps its own options and policy inside a region.

  • Regions cannot read Next Link options from ordinary rendered anchors.

  • Server Components can pass the link subtree as children.

  • The wrapper is a display: contents div, with no layout box. Keep a semantic element such as nav inside it.

Configure a Next.js base path

Match the basePath configured in next.config:

import { FastLinkRegion } from '@fast-link/next';
import Link from 'next/link';

export function DocsNavigation() {
  return (
    <FastLinkRegion basePath="/docs">
      <nav>
        <Link href="/overview">Overview</Link>
      </nav>
    </FastLinkRegion>
  );
}
  • Next Link renders /docs/overview.
  • The region passes /overview to App Router, which adds /docs back.
  • Omitting the region's configured base path can produce /docs/docs/overview.
  • One exact prefix is removed. /docs becomes /; /docs-extra stays unchanged.
  • Plain anchors need the base path in their href for native navigation.
  • No app base path: omit the prop (default '').
  • FastLink uses its authored destination; it has no basePath prop.

Add data-no-fast-link when an ordinary link's click-time behavior or Link options must run:

import Link from 'next/link';

export function AccountLink() {
  return (
    <Link href="/account" data-no-fast-link replace scroll={false}>
      Account
    </Link>
  );
}
  • Opt out for click-time guards or Link options the region cannot read.
  • Descendant onPointerDownCapture can prevent or stop the press before the region listener. Bubble handlers run too late to cancel early navigation.
  • Define callbacks in a Client Component.

Understand navigation and click behavior

  • Click-time guards: opt out if they must run before navigation.
  • API routes or another application's pages: choose an explicit routing policy or opt out. See application boundaries.

For an accepted primary mouse press, a managed link calls Next.js Link's onNavigate prop before selecting navigation. Ordinary region links skip that callback.

ConditionNavigation
Managed onNavigate calls preventDefault()Cancel early navigation; skip policy and onFastNavigate.
No navigationPolicyUse the current App Router.
Policy chooses { kind: 'router' }Use Next's destination and history method, with an optional scroll override.
Policy chooses { kind: 'document', method }Load the validated URL using document assign or replace.
  • For uncanceled navigation, onFastNavigate(intent, decision) observes the selected decision before navigation is attempted.
  • Policy cannot cancel navigation or rewrite the router destination or history method.
  • The matching follow-up pointer click is default-prevented, even after managed onNavigate cancellation. It cannot trigger default navigation but still propagates to mounted link and ancestor handlers.
  • A route may unmount handlers before release. Dragging away may navigate without producing a click.
  • An onPointerDown bubble guard runs after early navigation. Use synchronous onNavigate cancellation for press-time validation; opt out for release-time validation.

Native behavior remains for:

  • Touch, pen, keyboard, modified and non-primary clicks.
  • Downloads, external or hash-only URLs, non-_self targets, nested controls, and data-no-fast-link opt-outs.

See core's eligibility rules. Use enabled={false} to disable a component's early navigation.

Other integration rules:

  • Keyboard and touch activation skip navigationPolicy; preserve the application's normal routing for those inputs.
  • With as or legacyBehavior, FastLink stays on the normal Link path. Legacy behavior attaches no controller to the anchor; add data-no-fast-link when that anchor needs native handling inside a region.
  • Committed option updates preserve pending click suppression. Removing or replacing the root destroys the old controller and clears pending suppression.

Pending state

  • useLinkStatus().pending does not update. Public App Router calls cannot set Next Link's pending state.
  • Use route-level loading UI, or manage pending state in your app.
  • Start app-owned state in onFastNavigate. It reports an attempt, not completion.
  • Clear it on completion. Reset it on failure, cancellation, and unmount.

Supply a policy when the current App Router does not own every same-origin destination. Bind the policy once in reusable Client Component wrappers:

navigationPolicy handles accepted early mouse navigation. Preserve the application's normal routing across application boundaries for keyboard and touch activation too.

'use client';

import {
  FastLink,
  FastLinkRegion,
  type FastLinkProps,
  type FastLinkRegionProps,
  type FastNavigationPolicy,
} from '@fast-link/next';
import { forwardRef } from 'react';

const ownedPaths = new Set(['/overview', '/pricing']);

const navigationPolicy: FastNavigationPolicy = (intent, proposed) => {
  const route = new URL(proposed.destination, intent.url);
  return ownedPaths.has(route.pathname)
    ? { kind: 'router' }
    : { kind: 'document', method: 'assign' };
};

export const AppLink = forwardRef<
  HTMLAnchorElement,
  Omit<FastLinkProps, 'navigationPolicy'>
>(function AppLink(props, ref) {
  return <FastLink {...props} ref={ref} navigationPolicy={navigationPolicy} />;
});

export function AppRegion(
  props: Omit<FastLinkRegionProps, 'navigationPolicy'>,
) {
  return <FastLinkRegion {...props} navigationPolicy={navigationPolicy} />;
}

Both wrappers use the same navigation policy. AppLink forwards the caller's ref and Link options. AppRegion forwards region props, including basePath, enabled, and onFastNavigate.

Fast Link does not infer ownership from paths or metadata. Classify foreign or unknown ownership as document navigation. An ordinary link inside AppRegion uses the region policy, while AppLink uses its own policy and Link options.

Link onNavigate runs before the policy. Cancellation skips policy, observation, and navigation. A link that needs a click-time guard must opt out before pointerdown; a policy cannot return control to the original click.

A throwing policy or invalid decision attempts document assign to the captured URL, then surfaces the policy error. Extra decision properties are ignored. Observer errors still permit navigation. Router errors surface without a document fallback. If navigation also throws after a policy or observer error, the navigation error takes precedence.

Build a custom renderer

Prefer FastLink for reusable wrappers that forward refs and Link props. Use useFastLink when an existing renderer must control the anchor, prefetching, click handlers, or pending state:

'use client';

import { useFastLink, type UseFastLinkOptions } from '@fast-link/next';
import Link from 'next/link';
import { forwardRef, type ComponentPropsWithoutRef } from 'react';

type AppLinkProps = ComponentPropsWithoutRef<typeof Link> &
  Pick<UseFastLinkOptions, 'enabled'>;

export const AppLink = forwardRef<HTMLAnchorElement, AppLinkProps>(
  function AppLink({ enabled, ...props }, forwardedRef) {
    const attach = useFastLink({
      ...props,
      enabled,
      forwardedRef,
    });

    return <Link {...props} {...attach} />;
  },
);

The renderer must forward both bindings to its anchor or fallback element. Pass its capture handler into the hook and spread the bindings last so it runs after suppression. The renderer keeps its normal Link props and forwarded ref. Add onFastNavigate to maintain application pending state when route-level loading UI is not enough.

API reference

OptionTypeDefaultBehavior
enabledbooleantrueControls whether new pointerdowns can start navigation
navigationPolicyFastNavigationPolicyNoneSelects App Router or document navigation
onFastNavigate(intent, decision) => voidNoneObserves the frozen decision before navigation

onFastNavigate cannot change the selected action. Its return value is ignored, and navigation is still attempted if it throws.

FastLinkProps includes every prop accepted by next/link plus the shared options above. href remains required.

Fast navigation preserves replace, scroll, and transitionTypes options. transitionTypes follows the installed next/link types; it is omitted from hook options on Next versions that do not declare it. onNavigate can cancel Fast Link before policy evaluation, observation, or navigation.

FastLinkRegion

PropTypeDefaultBehavior
childrenReactNodeRequiredSupplies the existing link subtree
basePathstring''Removes one matching prefix before router.push
enabledbooleantrueControls early navigation for ordinary links in the region
navigationPolicyFastNavigationPolicyNoneSelects App Router or document navigation
onFastNavigate(intent, decision) => voidNoneObserves the selected decision before navigation

Nested regions retain outer-first capture ordering. A managed FastLink or useFastLink anchor owns its press before every containing region.

useFastLink(options) returns stable { ref, onClickCapture } bindings for an application-owned anchor or optional-href element. Spread both on the same DOM element after other props. It accepts:

  • href, as, legacyBehavior, replace, scroll, onNavigate, and transitionTypes from next/link
  • The shared enabled, navigationPolicy, and onFastNavigate options
  • forwardedRef for composing the caller's ref
  • onClickCapture, called after suppression even when the click is prevented

A missing href, a supplied as, legacyBehavior={true}, or a non-anchor root leaves navigation on its normal path. Option updates preserve a pending follow-up click. Replacing the root or unmounting destroys the controller and cleans up composed refs.

Navigation policy types

FastNavigationPolicy(intent, proposed) runs synchronously and returns a FastNavigationDecision. FastRouterProposal describes the route the adapter would take without policy:

Proposal fieldTypeValue
destinationstringThe computed App Router destination
method'push' | 'replace'The proposed history method
scrollboolean | undefinedThe proposed scroll behavior
DecisionAction
{ kind: 'router' }Use the proposed route and scroll behavior
{ kind: 'router', scroll: false }Use the proposed route and preserve scroll position
{ kind: 'document', method: 'assign' }Load the validated URL with a new history entry
{ kind: 'document', method: 'replace' }Load the validated URL and replace the current history entry

A policy can override only router scroll behavior. It cannot replace the destination, history method, or transition settings.

Exports

@fast-link/next exports FastLink, FastLinkRegion, useFastLink, FastLinkProps, FastLinkRegionProps, UseFastLinkOptions, FastRouterProposal, FastNavigationPolicy, FastNavigationDecision, and FastLinkIntent.

版本与发布记录

@fast-link/next 共发布 4 个版本,首次发布于 2026/10/07;过去 12 个月发布了 4 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.0.2latest2026/11/0311 天前
0.0.12026/10/2717 天前
0.0.02026/10/071 个月前
0.0.0-stage2026/10/071 个月前

关于 @fast-link/next 的常见问题

@fast-link/next 是什么?

Early mouse navigation for Next.js App Router links

如何安装 @fast-link/next?

在项目目录运行 npm install @fast-link/next,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:next(>=16 <17)、react(>=19 <20)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@fast-link/next 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@fast-link/next 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@fast-link/next 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@fast-link/next 可以商用吗?

@fast-link/next 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@fast-link/next 的下载量有多少?

根据 npm 官方下载统计,@fast-link/next 在 2026/10/15 – 2026/11/13 这 30 天内被下载 10,238 次,日均约 341 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@fast-link/next 还在维护吗?

最新版本 0.0.2 发布于 2026/11/03(11 天前);至今共发布 4 个版本,其中过去 12 个月发布了 4 个;首次发布于 2026/10/07。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。