Erreur de contexte avec Nuxt
Sommaire
- Introduction
- Tutoriel vidéo
- Origine du problème
- Pourquoi le contexte est perdu ?
- Solution recommandée
- Conclusion
Introduction
Cet article fait suite à une vidéo où nous explorons une erreur fréquente rencontrée avec Nuxt.js. Si vous avez déjà utilisé des composables intégrés à Nuxt comme useHead
ou d’autres fonctionnalités nécessitant le contexte Nuxt, il est probable que vous ayez vu cette erreur :
“useHead requires a Nuxt instance, but it was called outside of setup or middleware.”
Cet article explique pourquoi cette erreur survient, son impact sur votre application, et les solutions pour la contourner.
Tutoriel vidéo
Origine du problème
Prenons un exemple où vous voulez créer un composable pour récupérer et afficher le nom d’un utilisateur depuis une API publique. Vous utilisez une fonction asynchrone et souhaitez également définir dynamiquement le titre de la page avec useHead
:
export default async function useProfile() {
const username = ref('');
const data = await $fetch$('https://jsonplaceholder.typicode.com/users/1');
username.value = data.name;
useHead({
title: `Profil de ${username.value}`
});
return { username };
}
Lors de l’exécution, une erreur se produit. Pourquoi ? Parce que useHead
n’est pas appelé dans le bon contexte.
Pourquoi le contexte est perdu ?
Lorsque Nuxt exécute un composable, il associe ce dernier à une instance du framework. Les appels aux composables tels que useHead
ou useFetch
nécessitent cette instance active pour fonctionner correctement.
Lorsque vous travaillez avec des fonctions asynchrones dans la Composition API de Vue, il est crucial de comprendre comment Vue gère le contexte des hooks et des effets. Vue utilise une variable globale pour enregistrer l’instance actuelle du composant afin de permettre aux hooks comme onMounted
ou watch
de fonctionner correctement à l’intérieur du setup
. Cependant, ce mécanisme repose sur la nature synchrone de JavaScript.
Lorsqu’une fonction asynchrone (avec await
) est utilisée dans setup
, cela interrompt l’exécution synchronisée, provoquant une perte temporaire du contexte d’instance. Par conséquent :
- Les hooks comme
onMounted
ouonUnmounted
ne fonctionnent plus après unawait
. - Les effets comme
watch
,computed
ouwatchEffect
continuent de fonctionner, mais ne sont plus automatiquement nettoyés à la destruction du composant, entraînant de potentielles fuites mémoire.
Vue contourne cette limitation en associant les hooks à l’instance courante lors de l’exécution synchrone. Cependant, dès qu’un await
intervient, d’autres composants peuvent modifier la variable globale d’instance, rendant impossible le suivi fiable du contexte.
Solution recommandée
Pour pallier ce problème, vous pouvez :
- Éviter d’utiliser des hooks après un
await
et regrouper ces appels avant. - Transformer vos données asynchrones en état réactif via des utilitaires comme
useAsyncState
ouuseFetch
de VueUse. - Lier explicitement l’instance aux hooks grâce à des arguments supplémentaires.
- Utiliser
effectScope
pour encapsuler des effets tout en préservant leur contexte. - Exploiter les fonctionnalités de compilation dans
<script setup>
, qui restaurent automatiquement le contexte après unawait
.
Pour ma part, j’ai décidé d’encapsuler l’appel avec useNuxtApp
:
import { useNuxtApp } from '#app';
export default async function useProfile() {
const { $nuxt } = useNuxtApp();
$nuxt.runWithContext(() => {
useHead({
title: 'Profil de John Doe'
});
});
}
Conclusion
Les erreurs de contexte Nuxt sont courantes, mais elles peuvent être facilement résolues avec une bonne compréhension du cycle de vie et des outils comme onMounted
ou useNuxtApp
. Avec ces corrections, vous pourrez créer des applications Nuxt robustes et efficaces sans perdre de temps sur des problèmes techniques.
Pour plus de détails, n’hésitez pas à consulter la vidéo associée ou à explorer le superbe article d’Antfu à ce sujet.
Restez connectés pour d’autres tutoriels !