fix(nuxt): prevent fallthrough attributes on custom NuxtLink
#19379
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
π Linked issue
Resolves: #19375
β Type of change
π Description
In #19309 we enabled the forwarding of the
rel
prop ofNuxtLink
as an attribute to internal links.This resurfaced an issue we faced in the past (#14897) where the
custom
API ofNuxtLink
(fromRouterLink
) cannot handle such fallthrough attributes1. This seems to happen because Vue slot API cannot assume that the slot content strictly is a VNode (as it could also be a fragment or text node), so it has to consider all cases.2I think this is not really an upstream issue (
vue-router
actually tries to let those attribute fallthrough as it's Vue default behavior, causing the warning) but a limitation of the slot API (again, it cannot just assume it will be a VNode).Given those considerations we (mainly) have two choices:
v-bind="$attrs"
systematically when using thecustom
APIcustom
API is usedI think nΒ°2 makes more sense. Should someone use the
custom
API, it makes more sense for them to just apply those extra attributes on their slot content themselves rather than providing them to the link component which might eventually apply them to their slotted template. This comes with the tradeoff of not being able to programmatically define attributes to be applied on our end (like the prefetching class)3This PR also refactors the way
RouterLink
props are defined to be more readable (otherwise we would have multiple inline ternaries when defining the object).The type of
routerLinkProps
isRecord<string, any>
, defined after Vue's internalRawProps
type which is not exported by Vue (with reasons I assume)π Checklist
Footnotes
Vue documentation on fallthrough attributes behavior: https://vuejs.org/guide/components/attrs.html β©
For reference, this also happens with
RouterLink
directly: https://stackblitz.com/edit/github-stiici-ukvew6 β©vue-router
seems to be doing the same tradeoff, albeit booleans used to define active classes and such are exposed to the slot: https://github.com/vuejs/router/blob/6b7b25a74e89f1dde534bf86d19cfcdbce25092b/packages/router/src/RouterLink.ts#L214-L230 β©