SwLink

SwLink is the framework's unified link component. It automatically distinguishes resource file links from route links — no need to manually decide between <a> and <NuxtLink>:

  • Resource file extensions (pdf / zip / mp4 / apk, etc.) → renders a native <a href>, handled by the browser for download/preview
  • All other paths → renders <NuxtLink>, going through Nuxt's routing system

Security attributes are also handled automatically: target="_blank" adds rel="noopener noreferrer"; external links (https://) additionally get nofollow.

For page / resource navigation, default to SwLink (renders a real <a href>, friendly to SEO / crawlers / a11y). Only reach for something else when you hit one of these named exceptions:

CaseUse
Trusted external link that should pass SEO weight (dofollow)Native <a href rel="noopener"> (SwLink forces nofollow on https external links)
Need NuxtLink custom slot for fully custom rendering<NuxtLink custom v-slot>
Same-page anchor #idNative <a href="#id">
Pure interaction with no URL navigation (toggle / dialog / submit)SwButton (that's not a link)

Anti-patterns: ① @click + router.push / navigateTo for a page navigation that could be <a href> → loses SEO; ② <a @click> (no href) for pure interaction → loses a11y. See the framework dev standards "Link / navigation selection" for the full guide.

Basic Usage

Basic Link

加载中...

External / new-window (rel auto-managed)

加载中...

Disabled state

Disabled state (business class)

加载中...

Pass a path with a resource extension — the component automatically renders as a native <a>:

<!-- Auto-renders as <a href="/files/guide.pdf" target="_blank"> -->
<SwLink to="/files/guide.pdf" target="_blank">Download PDF</SwLink>

<!-- Video file, browser plays/downloads directly -->
<SwLink to="/video/intro.mp4" target="_blank">Watch Video</SwLink>

Two params shapes (object / string)

加载中...

Pass query parameters via the params prop:

<!-- Object form → /search?kw=nuxt&page=1 -->
<SwLink to="/search" :params="{ kw: 'nuxt', page: 1 }">Search</SwLink>

<!-- String form → /player?url=https://... -->
<SwLink to="/player" params="https://cdn.example.com/video.m3u8">Play</SwLink>

Default visual & overrides

Override the default look (color / underline / button-like)

加载中...

SwLink ships a default text-link look: primary color (var(--primary)) + no underline + hover brightness feedback (filter: brightness(0.92), the house style).

To change the link color, set the CSS variable --sw-link-color (on the link or any ancestor) — it applies via the custom-property cascade, independent of rule specificity / load order:

<style scoped>
/* ✅ Recolor via the variable: muted footer links, white links on a dark banner, etc. */
.sw-app-footer {
  --sw-link-color: var(--muted-foreground);
}
/* or set it on the link element itself */
.my-link {
  --sw-link-color: var(--primary-foreground);
}
</style>

⚠️ Do not override color with .sw-link { color: … } — it ties the framework default .sw-link rule at specificity (0,2,0), so the winner depends on CSS source order, which differs between nuxt dev (HMR) and nuxt build (Vite bundling) → the same code flips link color between dev and prod (framework#170). Always recolor via --sw-link-color.

Other visual overrides (e.g. an always-on underline for links inside long prose, WCAG 1.4.1) need higher specificity in your scoped CSS to avoid the same specificity tie:

<style scoped>
.my-article .sw-link {
  text-decoration: underline;
}
</style>

Button-looking navigation stays out of the component: apply your own button class (consistent with SwButton's zero-visual philosophy).

Props

NameTypeRequiredDefaultDescription
tostring''Target URL or route path
target'_self' | '_blank''_self'How the link opens
titlestring''Native title attribute (tooltip on hover)
paramsRecord<string, string | number | boolean> | string''Query params; string wraps as query.url, object as query
trackLinkTrackPropundefinedBuilt-in tracking (opt-in, zero behavior when omitted) — see "Built-in tracking" below

Built-in tracking (:track)

Exposure and click tracking for content cards / nav items can be reported automatically — the business side only fills in business fields:

<SwLink to="/movie/123" :track="{
  exposure: { event: 'appPageitemExposure', payload: { item_id: '123', item_type: 'video', item_name: 'Title', parent_item_id: '', page_key: 'home', page_name: 'Home' } },
  click:    { event: 'appPageitemClick',    payload: { item_id: '123', item_type: 'video', item_name: 'Title', parent_item_id: '', position: 1, page_key: 'home', page_name: 'Home' } },
}">
  <MovieCard :movie="movie" />
</SwLink>
FieldTimingTypical events
track.exposureOnce on viewport entry (IntersectionObserver ≥50% visible, via useExposure)appPageitemExposure / recommendListView
track.clickOn click (fire-and-forget, never blocks navigation)appPageitemClick / recommendListClick / navigation
  • event is constrained to the WebSdkEvent union (typos caught by TS) and explicitly chosen by the business — the same card uses recommendList* in a recommendation feed and appPageitem* in a plain list; the component never guesses semantics.
  • payload is passed through as-is; reporting goes through useTracker (silent no-op when the tracker gate is off).
  • Escape hatch: with your own tracking SDK, skip :track — native click events still fall through, and exposure timing is available via useExposure.

Slots

NameDescription
defaultLink text or custom content

Notes

  • Resource extension detection: pdf / zip / rar / docx / xlsx / pptx / jpg / png / gif / svg / xml / m3u8 / ts / key / mp4 / mp3 / webm / apk / json / gz / tar / mobileprovision / txt / exe. Matched extensions render as <a href>; everything else uses <NuxtLink>.
  • Auto rel handling: target="_blank" automatically adds rel="noopener noreferrer"; external links (https://) additionally get nofollow — no manual setup needed.
  • External route links: For https:// URLs, <NuxtLink> natively supports external navigation. SwLink handles these correctly — resource extension detection takes priority over external-link detection.