Skip to content

noVueRestrictedCallAfterAwait (JavaScript)

Language JavaScript (and super languages)
biome.json
{
"linter": {
"rules": {
"nursery": {
"noVueRestrictedCallAfterAwait": "error"
}
}
}
}

Disallow calling configured functions after an await in setup().

Some functions, such as useI18n() from vue-i18n, need to know which component is being set up. Vue only keeps track of that while setup() runs without pausing. Once setup() pauses at an await, these functions can no longer find the component, so they fail or behave incorrectly.

This rule reports calls to the functions listed in the functions option that come after an await in a component’s setup() function. It does nothing until you list at least one function.

Code inside <script setup> isn’t checked, because Vue keeps track of the component across each await there.

The examples below use the following configuration:

biome.json
{
"linter": {
"rules": {
"nursery": {
"noVueRestrictedCallAfterAwait": {
"level": "on",
"options": {
"functions": [
{
"module": "vue-i18n",
"path": "useI18n"
}
]
}
}
}
}
}
}
<script>
import { useI18n } from "vue-i18n";
export default {
async setup() {
await fetchUser();
const { t } = useI18n();
return { t };
},
};
</script>
code-block.vue:7:19 lint/nursery/noVueRestrictedCallAfterAwait ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ This call to useI18n() from vue-i18n comes after an await in setup().

5 │ async setup() {
6 │ await fetchUser();
> 7 │ const { t } = useI18n();
│ ^^^^^^^^^
8 │ return { t };
9 │ },

ℹ The setup() function pauses here. After this point, Vue no longer knows which component is being set up.

4 │ export default {
5 │ async setup() {
> 6 │ await fetchUser();
│ ^^^^^
7 │ const { t } = useI18n();
8 │ return { t };

ℹ This function is listed in the functions option because it needs to know which component is being set up. Call it before the first await in setup().

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script>
import { useI18n } from "vue-i18n";
export default {
async setup() {
const { t } = useI18n();
await fetchUser();
return { t };
},
};
</script>

Default: []

The functions that must not be called after an await in setup(). Each entry is an object with these properties:

  • module: The module that exports the function, written the same way as in the import statement. This property is required.
  • path: The name the function is exported as. Use a list of names when the function is a property of an exported object: ["bar", "baz"] matches bar.baz() for import { bar } from "...". Defaults to "default", which matches the module’s default export.
  • message: A custom message to show in place of the default message.
biome.json
{
"linter": {
"rules": {
"nursery": {
"noVueRestrictedCallAfterAwait": {
"level": "on",
"options": {
"functions": [
{
"module": "vue-i18n",
"path": "useI18n"
},
{
"module": "my-store",
"path": [
"store",
"use"
],
"message": "Call store.use() before the first await."
},
{
"module": "my-plugin"
}
]
}
}
}
}
}
}
<script>
import { store } from "my-store";
export default {
async setup() {
await fetchUser();
store.use();
},
};
</script>
code-block.vue:7:5 lint/nursery/noVueRestrictedCallAfterAwait ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ Call store.use() before the first await.

5 │ async setup() {
6 │ await fetchUser();
> 7 │ store.use();
│ ^^^^^^^^^^^
8 │ },
9 │ };

ℹ The setup() function pauses here. After this point, Vue no longer knows which component is being set up.

4 │ export default {
5 │ async setup() {
> 6 │ await fetchUser();
│ ^^^^^
7 │ store.use();
8 │ },

ℹ This function is listed in the functions option because it needs to know which component is being set up. Call it before the first await in setup().

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script>
import usePlugin from "my-plugin";
export default {
async setup() {
await fetchUser();
usePlugin();
},
};
</script>
code-block.vue:7:5 lint/nursery/noVueRestrictedCallAfterAwait ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ This call to default() from my-plugin comes after an await in setup().

5 │ async setup() {
6 │ await fetchUser();
> 7 │ usePlugin();
│ ^^^^^^^^^^^
8 │ },
9 │ };

ℹ The setup() function pauses here. After this point, Vue no longer knows which component is being set up.

4 │ export default {
5 │ async setup() {
> 6 │ await fetchUser();
│ ^^^^^
7 │ usePlugin();
8 │ },

ℹ This function is listed in the functions option because it needs to know which component is being set up. Call it before the first await in setup().

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

  • noVueLifecycleAfterAwait reports Vue lifecycle hooks, such as onMounted(), that are registered after an await in setup().