139 lines
3.6 KiB
Markdown
139 lines
3.6 KiB
Markdown
---
|
|
title: Site statique et requêtes GraphQL avec Nuxt.js
|
|
subtitle: Le client graphql est roi.
|
|
lang: fr
|
|
slug: "nuxt-graphql-static"
|
|
createdAt: "2022-06-08T14:24:06.000Z"
|
|
updatedAt: "2022-09-08T13:43:33.000Z"
|
|
excerpt: Quand le module gql le plus utilisé ne fonctionne pas…
|
|
tags: ["nuxt.js"]
|
|
---
|
|
|
|
## Le problème
|
|
|
|
Je me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client [nuxt apollo](https://github.com/nuxt-community/apollo-module "Dépôt github du module nuxt apollo (nouvel onglet)").
|
|
Après quelques recherches, voici [le bug constaté par quelqu'un d'autre](https://github.com/nuxt-community/apollo-module/issues/339 "Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)") sur github.
|
|
|
|
Il semblerait que le module en l'état ne gère pas correctement la génération statique avec `nuxt generate`.
|
|
|
|
Je trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les `<nuxt-link>` ne fonctionnait pas.
|
|
|
|
## La solution 🙌
|
|
|
|
Heureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !
|
|
|
|
[Nuxt graphql request à la rescousse !](https://github.com/gomah/nuxt-graphql-request "Dépôt github du module (nouvel onglet)")
|
|
|
|
### La conf
|
|
|
|
```javascript
|
|
// nuxt.config.js
|
|
buildModules: [
|
|
'nuxt-graphql-request',
|
|
],
|
|
graphql: {
|
|
clients: {
|
|
default: {
|
|
endpoint: 'http://API_URL/graphql',
|
|
options: {
|
|
headers: {
|
|
authorization: 'Bearer API_TOKEN',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
```
|
|
|
|
### La requête
|
|
|
|
La meilleure méthode à ce jour est d'utiliser `asyncData` dans les pages et `fetch` dans les composants. Utiliser `fetch` dans les pages ne fonctionne pas bien du tout avec `nuxt generate`.
|
|
|
|
J'installe également le paquet `graphql-tag` (uniquement en `devDependencies`) afin de pouvoir importer directement des fichiers `.gql`
|
|
|
|
Exemple de fichier :
|
|
|
|
```graphql
|
|
# homepage.gql
|
|
query {
|
|
homepage {
|
|
title
|
|
subtitle
|
|
hero {
|
|
id
|
|
alt
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Dans une page
|
|
|
|
```javascript
|
|
// index.vue
|
|
<script>
|
|
import homepageQuery from '~/graphql/queries/singles/homepage'
|
|
|
|
export default {
|
|
async asyncData({ $graphql }) {
|
|
const data = await $graphql.default.request(homepageQuery)
|
|
return { data }
|
|
},
|
|
}
|
|
</script>
|
|
```
|
|
|
|
#### Dans un composant
|
|
|
|
Il est plus prudent d'attendre que `fetch` ait reçu une réponse avant d'afficher quoi que ce soit. On peut utiliser `$fetchState` afin d'être tranquille ([documentation](https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch "Documentation sur la méthode fetch (nouvel onglet)")).
|
|
|
|
```javascript
|
|
// Header.vue
|
|
<template>
|
|
<header v-if="!$fetchState.pending">
|
|
…
|
|
</header>
|
|
</template>
|
|
|
|
<script>
|
|
import headerQuery from '~/graphql/queries/singles/header'
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
data: {},
|
|
}
|
|
},
|
|
async fetch() {
|
|
try {
|
|
const data = await this.$graphql.default.request(headerQuery)
|
|
this.data = data
|
|
} catch (error) {
|
|
console.error(JSON.stringify(error, undefined, 2))
|
|
}
|
|
},
|
|
}
|
|
</script>
|
|
```
|
|
|
|
### Les options
|
|
|
|
Pour passer des options à la requête, par exemple pour une version multilingue avec [nuxt/i18n](https://i18n.nuxtjs.org/ "Documentation de nuxt i18n (nouvel onglet)") et/ou un paramètre d'url dans le cadre d'une page dynamique :
|
|
|
|
```javascript
|
|
// _slug.vue
|
|
<script>
|
|
import articleQuery from '~/graphql/queries/articles'
|
|
|
|
export default {
|
|
async asyncData({ $graphql, app, params }) {
|
|
const locale = app.i18n.localeProperties.iso
|
|
const data = await $graphql.default.request(articleQuery, {
|
|
code: locale,
|
|
slug: params.slug,
|
|
})
|
|
return { data }
|
|
},
|
|
}
|
|
</script>
|
|
```
|