vuejs/vue-router · warning

<router-link>'s event prop is deprecated and has been remove

Error message

<router-link>'s event 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

What it means

resolveProps validates the props config of a route component: it may be an object, a function (route)=>props, or a boolean. Anything else (string, number, undefined-with-bad-shape, array) hits the default branch and warns in dev that props in the given route path is of the wrong type. The props are then not passed to the route component.

Source

Thrown at src/components/link.js:143

            `<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
      }
      if ('event' in this.$options.propsData && !warnedEventProp) {
        warn(
          false,
          `<router-link>'s event 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.`
        )
        warnedEventProp = true
      }
    }

    if (this.tag === 'a') {
      data.on = on
      data.attrs = { href, 'aria-current': ariaCurrentValue }
    } else {
      // find the first <a> child and apply listener and href
      const a = findAnchor(this.$slots.default)
      if (a) {
        // in case the <a> is a static node
        a.isStatic = false
        const aData = (a.data = extend({}, a.data))
        aData.on = aData.on || {}

View on GitHub (pinned to 680ccc68c5)

Solutions

  1. Change the route's props config to an object, function, or boolean.
  2. If you meant params-as-props, use props: true (boolean) or props: route => ({ id: route.params.id }).
  3. Log the config at route-creation time to catch bad types early.

Example fix

// before
{ path: '/user/:id', component: User, props: 'true' }
// after
{ path: '/user/:id', component: User, props: true }
Defensive patterns

Strategy: validation

Validate before calling

// validate props config type when defining routes
const VALID = ['object', 'function', 'boolean']
function validateRouteProps (route) {
  if ('props' in route && !VALID.includes(typeof route.props)) {
    throw new TypeError(`route ${route.path}: props must be object, function or boolean`)
  }
}

Type guard

function isValidPropsConfig (c) {
  return ['object', 'function', 'boolean'].includes(typeof c) && c !== null
}

Try / catch

// router-level: normalize at route definition time
{ path: '/user/:id', component: User, props: (route) => ({ id: route.params.id }) }

Prevention

When it happens

Trigger: Defining a route with props set to an invalid value, e.g. props: 'true' (string), props: 123, props: [], or props set via a route record mismatch; then navigating to that route so resolveProps runs with the bad config.

Common situations: Typo like props: 'true' instead of props: true; copying config from Vue Router 4 where boolean props semantics changed; generating routes dynamically and assigning wrong types.

Related errors


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