From df1d44190f46549ff9b94b4396fa549bdc689dca Mon Sep 17 00:00:00 2001 From: Alex Liu Date: Fri, 17 Jan 2025 19:50:05 +0800 Subject: [PATCH] docs: add description for prefetch and other details of `NuxtLink` (#30614) --- docs/3.api/1.components/4.nuxt-link.md | 167 +++++++++++++++++++++---- 1 file changed, 140 insertions(+), 27 deletions(-) diff --git a/docs/3.api/1.components/4.nuxt-link.md b/docs/3.api/1.components/4.nuxt-link.md index d21b798345..afdef5bd74 100644 --- a/docs/3.api/1.components/4.nuxt-link.md +++ b/docs/3.api/1.components/4.nuxt-link.md @@ -16,19 +16,24 @@ links: In this example, we use `` component to link to another page of the application. +::code-group ```vue [pages/index.vue] ``` +```html [(Renders as) index.html] + +About page +``` +:: + ### Passing Params to Dynamic Routes In this example, we pass the `id` param to link to the route `~/pages/posts/[id].vue`. +::code-group ```vue [pages/index.vue] ``` +```html [(Renders as) index.html] +Post 123 +``` +:: + ::tip Check out the Pages panel in Nuxt DevTools to see the route name and the params it might take. :: -### Handling 404s +### Handling Static File and Cross-App Links -When using `` for `/public` directory files or when pointing to a different app on the same domain, you should use the `external` prop. +By default, `` uses Vue Router's client side navigation for relative route. When linking to static files in the `/public` directory or to another application hosted on the same domain, it might result in unexpected 404 errors because they are not part of the client routes. In such cases, you can use the `external` prop with `` to bypass Vue Router's internal routing mechanism. -Using `external` forces the link to be rendered as an `a` tag instead of a Vue Router `RouterLink`. +The `external` prop explicitly indicates that the link is external. `` will render the link as a standard HTML `` tag. This ensures the link behaves correctly, bypassing Vue Router’s logic and directly pointing to the resource. + +#### Linking to Static Files + +For static files in the `/public` directory, such as PDFs or images, use the `external` prop to ensure the link resolves correctly. ```vue [pages/index.vue] ``` -The external logic is applied by default when using absolute URLs and when providing a `target` prop. +#### Linking to a Cross-App URL + +When pointing to a different application on the same domain, using the `external` prop ensures the correct behavior. + +```vue [pages/index.vue] + +``` + +Using the `external` prop or relying on automatic handling ensures proper navigation, avoids unexpected routing issues, and improves compatibility with static resources or cross-application scenarios. ## External Routing @@ -71,40 +96,126 @@ In this example, we use `` component to link to a website. ``` -## `target` and `rel` Attributes +## `rel` and `noRel` Attributes -A `rel` attribute of `noopener noreferrer` is applied by default to absolute links and links that open in new tabs. +A `rel` attribute of `noopener noreferrer` is applied by default to links with a `target` attribute or to absolute links (e.g., links starting with `http://`, `https://`, or `//`). - `noopener` solves a [security bug](https://mathiasbynens.github.io/rel-noopener/) in older browsers. - `noreferrer` improves privacy for your users by not sending the `Referer` header to the linked site. These defaults have no negative impact on SEO and are considered [best practice](https://developer.chrome.com/docs/lighthouse/best-practices/external-anchors-use-rel-noopener). -When you need to overwrite this behavior you can use the `rel` and `noRel` props. +When you need to overwrite this behavior you can use the `rel` or `noRel` props. ```vue [app.vue] +``` + +A `noRel` prop can be used to prevent the default `rel` attribute from being added to the absolute links. + +```vue [app.vue] + ``` +::note +`noRel` and `rel` cannot be used together. `rel` will be ignored. +:: + +## Prefetch Links + +Nuxt automatically includes smart prefetching. That means it detects when a link is visible (by default), either in the viewport or when scrolling and prefetches the JavaScript for those pages so that they are ready when the user clicks the link. Nuxt only loads the resources when the browser isn't busy and skips prefetching if your connection is offline or if you only have 2g connection. + +```vue [pages/index.vue] +About page not pre-fetched +About page not pre-fetched +``` + +### Custom Prefetch Triggers + +We now support custom prefetch triggers for `` after `v3.13.0`. You can use the `prefetchOn` prop to control when to prefetch links. + +```vue + +``` + +- `visibility`: Prefetches when the link becomes visible in the viewport. Monitors the element's intersection with the viewport using the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API). Prefetching is triggered when the element is scrolled into view. +- `interaction`: Prefetches when the link is hovered or focused. This approach listens for `pointerenter` and `focus` events, proactively prefetching resources when the user indicates intent to interact. + +You can also use an object to configure `prefetchOn`: + +```vue + +``` + +That you probably don't want both enabled! + +```vue + +``` + +This configuration will observe when the element enters the viewport and also listen for `pointerenter` and `focus` events. This may result in unnecessary resource usage or redundant prefetching, as both triggers can prefetch the same resource under different conditions. + +### Enable Cross-origin Prefetch + +To enable cross-origin prefetching, you can set the `crossOriginPrefetch` option in your `nuxt.config`. This will enabled cross-origin prefetch using the [Speculation Rules API](https://developer.mozilla.org/en-US/docs/Web/API/Speculation_Rules_API). + +```ts [nuxt.config.ts] +export default defineNuxtConfig({ + experimental: { + crossOriginPrefetch: true, + }, +}) +``` + +### Disable prefetch globally + +It's also possible to enable/disable prefetching all links globally for your app. + +```ts [nuxt.config.ts] +export default defineNuxtConfig({ + experimental: { + defaults: { + nuxtLink: { + prefetch: false, + }, + }, + }, +}) +``` + ## Props ### RouterLink @@ -113,16 +224,16 @@ When not using `external`, `` supports all Vue Router's [`RouterLink` - `to`: Any URL or a [route location object](https://router.vuejs.org/api/#RouteLocation) from Vue Router - `custom`: Whether `` should wrap its content in an `` element. It allows taking full control of how a link is rendered and how navigation works when it is clicked. Works the same as [Vue Router's `custom` prop](https://router.vuejs.org/api/interfaces/RouterLinkProps.html#Properties-custom) -- `exactActiveClass`: A class to apply on exact active links. Works the same as [Vue Router's `exact-active-class` prop](https://router.vuejs.org/api/interfaces/RouterLinkProps.html#Properties-exactActiveClass) on internal links. Defaults to Vue Router's default `"router-link-exact-active"`) +- `exactActiveClass`: A class to apply on exact active links. Works the same as [Vue Router's `exactActiveClass` prop](https://router.vuejs.org/api/interfaces/RouterLinkProps.html#Properties-exactActiveClass) on internal links. Defaults to Vue Router's default (`"router-link-exact-active"`) +- `activeClass`: A class to apply on active links. Works the same as [Vue Router's `activeClass` prop](https://router.vuejs.org/api/interfaces/RouterLinkProps.html#Properties-activeClass) on internal links. Defaults to Vue Router's default (`"router-link-active"`) - `replace`: Works the same as [Vue Router's `replace` prop](https://router.vuejs.org/api/interfaces/RouteLocationOptions.html#Properties-replace) on internal links -- `ariaCurrentValue`: An `aria-current` attribute value to apply on exact active links. Works the same as [Vue Router's `aria-current-value` prop](https://router.vuejs.org/api/interfaces/RouterLinkProps.html#Properties-ariaCurrentValue) on internal links -- `activeClass`: A class to apply on active links. Works the same as [Vue Router's `active-class` prop](https://router.vuejs.org/api/interfaces/RouterLinkProps.html#Properties-activeClass) on internal links. Defaults to Vue Router's default (`"router-link-active"`) +- `ariaCurrentValue`: An `aria-current` attribute value to apply on exact active links. Works the same as [Vue Router's `ariaCurrentValue` prop](https://router.vuejs.org/api/interfaces/RouterLinkProps.html#Properties-ariaCurrentValue) on internal links ### NuxtLink - `href`: An alias for `to`. If used with `to`, `href` will be ignored -- `noRel`: If set to `true`, no `rel` attribute will be added to the link -- `external`: Forces the link to be rendered as an `a` tag instead of a Vue Router `RouterLink`. +- `noRel`: If set to `true`, no `rel` attribute will be added to the external link +- `external`: Forces the link to be rendered as an `` tag instead of a Vue Router `RouterLink`. - `prefetch`: When enabled will prefetch middleware, layouts and payloads (when using [payloadExtraction](/docs/api/nuxt-config#crossoriginprefetch)) of links in the viewport. Used by the experimental [crossOriginPrefetch](/docs/api/nuxt-config#crossoriginprefetch) config. - `prefetchOn`: Allows custom control of when to prefetch links. Possible options are `interaction` and `visibility` (default). You can also pass an object for full control, for example: `{ interaction: true, visibility: true }`. This prop is only used when `prefetch` is enabled (default) and `noPrefetch` is not set. - `noPrefetch`: Disables prefetching. @@ -159,6 +270,8 @@ export default defineNuxtConfig({ exactActiveClass: 'router-link-exact-active', prefetchedClass: undefined, // can be any valid string class name trailingSlash: undefined // can be 'append' or 'remove' + prefetch: true, + prefetchOn: { visibility: true } } } }