Skip to content

vue/no-deprecated-slot-attribute conflicts with web component named slots #2710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
2 tasks done
raoufswe opened this issue Mar 7, 2025 · 5 comments
Open
2 tasks done

Comments

@raoufswe
Copy link

raoufswe commented Mar 7, 2025

Checklist

  • I have tried restarting my IDE and the issue persists.
  • I have read the FAQ and my problem is not listed.

Tell us about your environment

  • ESLint version: v9
  • eslint-plugin-vue version: v10.0.0
  • Vue version: v3
  • Node version: v20
  • Operating System: Mac OS

Please show your full configuration:

import pluginVue from 'eslint-plugin-vue'
import globals from 'globals'

export default [
  // add more generic rulesets here, such as:
  // js.configs.recommended,
  ...pluginVue.configs['flat/recommended'],
  // ...pluginVue.configs['flat/vue2-recommended'], // Use this if you are using Vue.js 2.x.
  {
    rules: {
      // override/add rules settings here, such as:
      // 'vue/no-unused-vars': 'error'
    },
    languageOptions: {
      sourceType: 'module',
      globals: {
        ...globals.browser
      }
    }
  }
]

What did you do?

 // my-element is a custom element / web component. 
<my-element>
  <div slot="named">hello</div>
</my-element>

What did you expect to happen?

Vue has a documented limitation when using named slots with web components. If a web component that accepts a named slot is used in a Vue app, the vue/no-deprecated-slot-attribute linting rule conflicts with this behavior.

When passing named slots, use the slot attribute instead of the v-slot directive.

https://vuejs.org/guide/extras/web-components#slots

What actually happened?

Since we must use the native slot attribute when working with named slots in web components and vue, consumers will encounter the following linting error unless it is explicitly disabled:

  11:22  error    `slot` attributes are deprecated vue/no-deprecated-slot-attribute

Repository to reproduce this issue

The issue can be reproduced in this nuxt@3 example

To see the lint error:

Navigate to the nuxt-app directory:

cd nuxt-app

Run the following command and you should be able to see the error:

yarn dlx eslint ./pages/components/button.vue
@FloEdelmann
Copy link
Member

unless it is explicitly disabled

That is exactly what I would recommend in this situation. How would this plugin be able to distinguish web components and Vue components, to allow the slot attribute on the former?

@raoufswe
Copy link
Author

raoufswe commented Mar 7, 2025

Hi @FloEdelmann
Thanks for the quick reply! Yes, it’s a tricky situation, and I was wondering the same thing.
If keeping the rule turned on by default is a must (which I assume it is), I’m happy to document this as a known pitfall for our consumers and suggest to disable it on a case-by-case basis 🤝

@FloEdelmann
Copy link
Member

I think keeping it enabled is most helpful for most users; few people will mix Vue components and web components in their code base. So I'll close this issue as won't fix. But if you think the documentation could be more clear about this case, feel free to open a PR!

@FloEdelmann FloEdelmann closed this as not planned Won't fix, can't repro, duplicate, stale Mar 7, 2025
@trydofor
Copy link

trydofor commented May 11, 2025

I think keeping it enabled is most helpful for most users; few people will mix Vue components and web components in their code base. So I'll close this issue as won't fix. But if you think the documentation could be more clear about this case, feel free to open a PR!

@FloEdelmann

I understand the reasoning behind keeping the rule enabled by default. However, I'd like to propose a more flexible solution for projects that use Web Components alongside Vue, particularly those using the Ionic Framework, which relies on native slot attributes.

Currently, the vue/no-deprecated-slot-attribute rule allows ignore: ['IonButton', 'IonCard'] as an array of component names. This works, but has two limitations:


🧩 Proposed Improvements

1. Support ignore as a RegExp (e.g., /^Ion/)

This would allow users to ignore all components with a common prefix, such as Ion*, without needing to list every component explicitly.

2. Ignore slot attributes used within children of ignored components

This is important for cases where native HTML elements (like <div>) are used inside an Ion* component and need to use the native slot attribute.


✅ Valid use cases (should be ignored):

<IonButton>
  <IonIcon slot="start" />         <!-- Valid: matches RegExp ^Ion -->
</IonButton>

<IonButton>
  <div slot="start">Label</div>    <!-- Valid: <div> is direct child of IonButton -->
</IonButton>

❌ Invalid (should still trigger):

<MyButton>
  <div slot="start">Label</div>    <!-- Invalid: MyButton is not ignored -->
</MyButton>

Supporting either (1) RegExp or (2) parent-based context would greatly improve developer experience for users of Ionic and other Web Component frameworks that require native slot attributes.

If full support for RegExp is too complex, (2) alone—ignoring native slot usage when the parent is in the ignore list—would still solve most real-world issues.

Thanks for considering this!

@FloEdelmann
Copy link
Member

Supporting regexes in the ignore option would be possible, we already do that in many other rules. Would you be willing to submit a PR for that? See e.g. #2734 for a similar change.

@FloEdelmann FloEdelmann reopened this May 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants