Afficher ses avis
Afficher les avis Google sur un site Next.js (App Router, rendu serveur)
Intégrez vos avis Google dans un site Next.js en Server Component : fragment HTML ou API JSON, cache revalidate, clé API côté serveur, lisible par les IA.
Mis à jour le
Sommaire
Vous avez un site Next.js et vous voulez y afficher vos avis Google sans perdre ce qui fait l'intérêt de Next : le rendu serveur. La bonne nouvelle, c'est que l'App Router est fait pour ça. Un Server Component récupère vos avis côté serveur, les met en cache, et les envoie dans le HTML de la page.
Quelle méthode choisir dans Next.js ?
Deux méthodes gardent vos avis lisibles par Google et les IA ; une troisième est à éviter.
| Méthode | Avis dans le HTML initial | Lisible par les IA | Clé API | Plan Revys | Contrôle du design |
|---|---|---|---|---|---|
Fragment HTML (/api/embed/ID/html) dans un Server Component | Oui | Oui | Non | Free et Pro | Mise en page réglée dans Revys |
API JSON (/api/v1/reviews) rendue en React côté serveur | Oui | Oui | Oui | Pro | Total, vos propres composants |
Snippet JavaScript ou useEffect | Non | Non | Non | Free et Pro | Iframe Revys |
Le fragment HTML est le plus rapide à mettre en place : une dizaine de lignes, et vous gardez les cinq mises en page du widget d'avis Google (grille, liste, carrousel, mur, badge). L'API JSON convient si votre design system impose vos propres composants.
Méthode 1 : le fragment HTML dans un Server Component
C'est la méthode que le tableau de bord Revys vous propose pour un site Next.js : l'assistant Mettre sur mon site reconnaît Next.js et présélectionne « Next.js (App Router) » sous « Votre site est fait avec… ». Revys renvoie le widget déjà rendu : le HTML des avis, un CSS limité au widget et le JSON-LD, sans aucun JavaScript.
Récupérer l'ID public du widget
Dans Revys, ouvrez Mes établissements › votre établissement › Sur mon site, cliquez sur Mettre sur mon site et saisissez l'adresse de votre site. Revys reconnaît Next.js (sinon, choisissez Next.js sous « Ce n'est pas ça ? ») et présélectionne « Next.js (App Router) ». Le code affiché contient déjà l'URL avec votre ID.
Créer le composant serveur
Créez
components/revys-reviews.tsx. Pas de directive"use client": c'est un Server Component.// components/revys-reviews.tsx (Server Component) export async function RevysReviews() { try { const res = await fetch("https://revys.io/api/embed/VOTRE_ID_WIDGET/html", { next: { revalidate: 3600 }, signal: AbortSignal.timeout(2000), }); if (!res.ok) return null; return <div dangerouslySetInnerHTML={{ __html: await res.text() }} />; } catch { return null; } }Placer le composant dans une page
Importez-le où les avis doivent apparaître :
// app/page.tsx import { RevysReviews } from "@/components/revys-reviews"; export default function Page() { return ( <main> <h1>Mon entreprise</h1> <RevysReviews /> </main> ); }Vérifier le HTML servi
Après un build de production, lancez
curl -s https://votre-site.fr/ | grep -c "revys-w"ou affichez le code source de la page : le texte de vos avis doit y figurer.
Trois choix dans ce code ne sont pas décoratifs :
next: { revalidate: 3600 }met la réponse en cache une heure. Selon la documentation Next.js, c'est la durée de vie maximale de la ressource, en secondes. Revys récupère vos avis Google environ toutes les heures, donc un cache plus court n'apporte rien.AbortSignal.timeout(2000)coupe l'appel au bout de deux secondes. Votre page ne doit jamais attendre Revys.return nullen cas d'erreur : si Revys ne répond pas, la page s'affiche sans les avis plutôt que de planter.
L'utilisation de dangerouslySetInnerHTML est ici voulue : le fragment ne contient ni script exécutable ni gestionnaire d'événement, et le texte des avis y est échappé par Revys. Vous faites confiance à une seule source, revys.io, que vous écrivez en dur.
Avec cacheComponents activé (Next.js 16)
Si votre projet active cacheComponents dans next.config.ts, le cache se déclare avec la directive "use cache" et cacheLife, stabilisé en Next.js 16. Le profil "hours" revalide toutes les heures :
// lib/revys.ts
import { cacheLife } from "next/cache";
export async function getRevysHtml() {
"use cache";
cacheLife("hours");
const res = await fetch("https://revys.io/api/embed/VOTRE_ID_WIDGET/html", {
signal: AbortSignal.timeout(2000),
});
return res.ok ? res.text() : "";
}
Le composant appelle alors getRevysHtml() dans un try/catch et rend le HTML de la même façon.
Méthode 2 : l'API JSON rendue en React côté serveur
L'API GET /api/v1/reviews renvoie vos avis, la note moyenne et un objet schemaOrg prêt à l'emploi. Elle est incluse dans le plan Pro (10 000 appels par mois et par fiche) et s'authentifie par une clé API.
Créer une clé API
Dans Revys, ouvrez API & développeurs (menu de gauche) et créez une clé. Elle a la forme
rv_<préfixe>_<secret>et n'est affichée qu'une fois.La ranger côté serveur
Ajoutez-la à
.env.local(et aux variables d'environnement de votre hébergeur), avec l'ID public du widget :REVYS_API_KEY=rv_xxx_... REVYS_WIDGET_ID=VOTRE_ID_WIDGETPas de préfixe
NEXT_PUBLIC_: la documentation Next.js précise que ces variables sont intégrées au JavaScript envoyé au navigateur.Écrire le composant
Installez le garde-fou
server-only(npm install server-only) : le build échoue si ce fichier est importé par erreur dans un composant client.// components/revys-reviews.tsx (Server Component) import "server-only"; type RevysReview = { id: string; authorName: string; rating: number; text: string | null; reviewedAt: string | null; ownerReply: string | null; }; type RevysData = { reviews: RevysReview[]; aggregate: { count: number; average: number }; schemaOrg: Record<string, unknown>; }; async function getRevysReviews(): Promise<RevysData | null> { try { const res = await fetch( `https://revys.io/api/v1/reviews?widget=${process.env.REVYS_WIDGET_ID}`, { headers: { Authorization: `Bearer ${process.env.REVYS_API_KEY}` }, next: { revalidate: 3600 }, signal: AbortSignal.timeout(2000), }, ); if (!res.ok) return null; const json = (await res.json()) as { data: RevysData }; return json.data; } catch { return null; } } export async function RevysReviews() { const data = await getRevysReviews(); if (!data || data.reviews.length === 0) return null; const { reviews, aggregate, schemaOrg } = data; return ( <section aria-labelledby="avis-titre"> <h2 id="avis-titre">Avis de nos clients</h2> <p> {aggregate.average.toFixed(1)}/5 sur {aggregate.count} avis Google </p> <ul> {reviews.map((r) => ( <li key={r.id}> <p> <strong>{r.authorName}</strong>{" "} <span aria-label={`${r.rating} sur 5`}> {"★".repeat(r.rating)} {"☆".repeat(5 - r.rating)} </span> {r.reviewedAt ? ( <time dateTime={r.reviewedAt}> {" "}· {new Date(r.reviewedAt).toLocaleDateString("fr-FR")} </time> ) : null} </p> {r.text ? <p>{r.text}</p> : null} {r.ownerReply ? ( <p> <em>Réponse du propriétaire :</em> {r.ownerReply} </p> ) : null} </li> ))} </ul> <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaOrg).replace(/</g, "\\u003c"), }} /> </section> ); }
Quelques détails de l'API utiles en production :
?widget=applique les filtres du widget (note minimale, nombre d'avis) ; les avis arrivent du plus récent au plus ancien, sans les avis que vous avez masqués.aggregateest calculé sur tous les avis de la fiche : la moyenne correspond à votre vraie note Google, même si le widget n'affiche que les 4 et 5 étoiles.schemaOrgest un objetOrganizationsansaggregateRating, conforme à la règle de Google sur les avis auto-servis. Le.replace(/</g, "\\u003c")suit la recommandation de la documentation Next.js contre l'injection de balises.- Si le quota mensuel est dépassé, l'API renvoie la dernière réponse réussie pour la même cible (en-tête
X-Revys-Quota: exceeded) : vos avis restent affichés.
Avec revalidate: 3600, chaque instance de serveur fait au plus 24 appels par jour, soit environ 720 par mois.
Pourquoi éviter le snippet client dans Next.js ?
Parce qu'il annule l'avantage du rendu serveur. Un useEffect qui appelle une API, ou le snippet JavaScript de Revys, ajoute les avis après le chargement. Le HTML initial ne les contient pas.
- Les robots IA lisent le HTML brut. L'analyse de Vercel (décembre 2024) n'a trouvé aucun grand robot IA qui exécute le JavaScript.
- Google exécute le JavaScript, mais dans une file de rendu distincte du premier passage, comme l'explique sa documentation sur le SEO JavaScript.
- Le snippet Revys insère une iframe qui pointe vers
revys.io: le contenu n'est pas sur votre domaine.
Un appel côté client exposerait aussi votre clé API à n'importe quel visiteur. Pour aller plus loin sur ce que les moteurs IA lisent, voir avis clients et IA : être cité par ChatGPT.
Et pour Astro, Node ou PHP ?
Le même fragment HTML s'intègre dans n'importe quel serveur. Le tableau de bord donne le code pour Astro, Node.js/Express, Python, Ruby et un Cloudflare Worker ; la page PHP, HTML et autres CMS détaille PHP et le cas des sites statiques. Sur WordPress, préférez le plugin WordPress. Pour comparer toutes les méthodes, lisez le guide afficher les avis Google sur son site, et consultez les tarifs pour le plan Pro.
Questions fréquentes
Faut-il une clé API pour afficher les avis dans Next.js ?
Non pour le fragment HTML : l'URL /api/embed/ID/html est publique et fonctionne dès le plan Free. Oui pour l'API JSON /api/v1/reviews, incluse dans le plan Pro et appelée avec un en-tête Authorization: Bearer.
Où mettre la clé API Revys dans un projet Next.js ?
Dans une variable d'environnement serveur, par exemple REVYS_API_KEY dans .env.local, lue uniquement dans un Server Component. Ne la préfixez jamais par NEXT_PUBLIC_, sinon Next.js l'intègre au JavaScript envoyé au navigateur.
Pourquoi ne pas charger les avis avec useEffect ou un script client ?
Parce que les avis n'existent alors pas dans le HTML initial. Les grands robots IA n'exécutent pas le JavaScript, et le snippet Revys passe par une iframe hébergée sur revys.io, donc les avis ne sont pas attribués à votre site.
Combien d'appels API consomme un cache d'une heure ?
Au plus 24 appels par jour et par instance de serveur, soit environ 720 par mois, très en dessous du quota Pro de 10 000 appels par mois et par fiche.
Ça marche avec le Pages Router ?
Oui : faites le même appel dans getStaticProps avec revalidate: 3600 (régénération incrémentale), et passez le HTML ou les avis à la page en props.
Les avis affichés donnent-ils des étoiles dans Google ?
Non. Google n'affiche pas d'étoiles pour les avis qu'une entreprise publie sur son propre site. Revys fournit donc un JSON-LD Organization conforme, sans AggregateRating.
Sources
- fetch : options.next.revalidate (documentation Next.js)
- How to implement JSON-LD in your Next.js application (documentation Next.js)
- Environment Variables (documentation Next.js)
- cacheLife (documentation Next.js)
- Notions de base du SEO JavaScript (Google Search Central)
- The rise of the AI crawler (Vercel, décembre 2024)
Dans le même thème
- Alternative à Elfsight pour les avis Google : comparatif honnêteElfsight ou Revys pour afficher vos avis Google ? Prix, limite de vues, rendu HTML ou JavaScript testé, réponse IA : comparatif vérifié le 19 octobre 2026.Lire
- Alternative à EmbedSocial pour les avis Google : comparatif honnêteEmbedSocial ou Revys pour vos avis Google ? Prix par source, limite de vues, iframe testée, réponse IA : comparatif vérifié le 19 octobre 2026.Lire
- Alternative à Trustindex : comparatif honnête (prix, rendu HTML, réponse IA)Trustindex ou Revys ? Prix publics, plateformes, réponse IA, avis lisibles par Google et les IA : comparatif testé et vérifié le 19 octobre 2026.Lire
- Meilleurs widgets d'avis Google en 2026 : 7 outils testésTrustindex, Elfsight, EmbedSocial, Smash Balloon, Featurable, Guest Suite, Revys : prix vérifiés, plan gratuit, rendu HTML ou JS testé le 19 octobre 2026.Lire
- Widget d'avis Google lisible par Google et les IAWidget d'avis Google gratuit pour 1 fiche : 5 mises en page, avis dans le HTML de votre site, JSON-LD conforme, mise à jour chaque nuit via l'API officielle.Lire
- Afficher les avis Google sur son site : les méthodes comparéesCopier-coller, widget JavaScript, plugin, include serveur ou API : quelle méthode pour afficher vos avis Google, à jour et lisibles par Google et les IA.Lire