vuejs/vue-router · info

<router-link> with to="${this.to}" is trying to use a scoped

Error message

<router-link> with to="${this.to}" is trying to use a scoped slot but it didn't provide exactly one child. Wrapping the content with a span element.

What it means

This is a dev-only deprecation warning: the tag prop of <router-link> is removed in Vue Router 4 and will have no effect going forward. The recommended replacement is the v-slot API, which lets you render any element yourself. The warning fires once (warnedTagProp flag) when tag is found in the component's propsData.

Source

Thrown at src/components/link.js:123

      this.$scopedSlots.default &&
      this.$scopedSlots.default({
        href,
        route,
        navigate: handler,
        isActive: classes[activeClass],
        isExactActive: classes[exactActiveClass]
      })

    if (scopedSlot) {
      if (process.env.NODE_ENV !== 'production' && !this.custom) {
        !warnedCustomSlot && warn(false, 'In Vue Router 4, the v-slot API will by default wrap its content with an <a> element. Use the custom prop to remove this warning:\n<router-link v-slot="{ navigate, href }" custom></router-link>\n')
        warnedCustomSlot = true
      }
      if (scopedSlot.length === 1) {
        return scopedSlot[0]
      } else if (scopedSlot.length > 1 || !scopedSlot.length) {
        if (process.env.NODE_ENV !== 'production') {
          warn(
            false,
            `<router-link> with to="${
              this.to
            }" is trying to use a scoped slot but it didn't provide exactly one child. Wrapping the content with a span element.`
          )
        }
        return scopedSlot.length === 0 ? h() : h('span', {}, scopedSlot)
      }
    }

    if (process.env.NODE_ENV !== 'production') {
      if ('tag' in this.$options.propsData && !warnedTagProp) {
        warn(
          false,
          `<router-link>'s tag prop is deprecated and has been removed in Vue Router 4. Use the v-slot API to remove this warning: https://next.router.vuejs.org/guide/migration/#removal-of-event-and-tag-props-in-router-link.`
        )
        warnedTagProp = true
      }

View on GitHub (pinned to 680ccc68c5)

Solutions

  1. Remove the tag prop and use the v-slot API: <router-link custom v-slot="{ href, navigate }"> and render your own element.
  2. For list items, wrap: <li><router-link to="...">...</router-link></li>, or use v-slot to render the <li> yourself with navigate on click.
  3. Update styling/markup to target the rendered <a> instead of the custom tag.

Example fix

// before
<router-link to="/about" tag="li">About</router-link>
// after
<router-link to="/about" custom v-slot="{ href, navigate }">
  <li :href="href" @click="navigate">About</li>
</router-link>
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Passing tag="li" (or any tag) to <router-link> in a project running a vue-router 3.x beta/next or 4.x-compatible dev build.

Common situations: Upgrading from vue-router 3.x stable (where tag worked) to the 3.x next / 4.x migration path; following old tutorials that style router-links as list items via tag.

Related errors


AI-assisted analysis of vuejs/vue-router@680ccc68c5 (2026-09-02). Data as JSON: /api/errors/251f03a9469c636d. Report an issue: GitHub.