Géolocalisation IP en React : un composant de position du visiteur
Construisez un hook useVisitorGeo réutilisable autour du SDK JavaScript Watch-IP, avec la gestion du chargement, des erreurs et de l'annulation dont un vrai composant React a besoin — y compris pourquoi la requête peut se déclencher deux fois en développement.
Avant de commencer
- Un compte Watch-IP et une clé visiteur publiable dont la liste des origines autorisées inclut l'origine de votre application (développement et production).
- React 18 ou plus récent — le comportement de double invocation de StrictMode décrit ci-dessous est spécifique au mode développement.
- @digitload/watch-ip-sdk installé (npm install @digitload/watch-ip-sdk).
1. Construire un hook useVisitorGeo
Enveloppez l'appel getGeo() du SDK dans un hook qui suit l'état de chargement/résultat/erreur et annule la requête si le composant est démonté avant qu'elle n'aboutisse.
TypeScript
import { useEffect, useState } from "react";
import { WatchIP, type GeoResponse } from "@digitload/watch-ip-sdk";
const client = new WatchIP("YOUR_PUBLISHABLE_KEY");
export function useVisitorGeo() {
const [geo, setGeo] = useState<GeoResponse | null>(null);
const [status, setStatus] = useState<"loading" | "ready" | "error">("loading");
useEffect(() => {
const controller = new AbortController();
client
.getGeo({ signal: controller.signal })
.then((result) => {
setGeo(result);
setStatus("ready");
})
.catch((err) => {
if (err.name !== "AbortError") setStatus("error");
});
return () => controller.abort();
}, []);
return { geo, status };
}2. Pourquoi la requête peut se déclencher deux fois en développement
Le StrictMode de React monte, démonte puis remonte intentionnellement chaque composant une fois en développement pour révéler les effets qui ne se nettoient pas correctement. Cela signifie que l'effet de ce hook s'exécute deux fois, et l'AbortController ci-dessus est important : la première requête est annulée par la fonction de nettoyage avant d'aboutir, si bien qu'un seul appel getGeo() réel se termine réellement. Omettre l'appel à abort ne casserait pas la correction — GET /v1/geo est une lecture — mais laisserait une requête en vol redondante et une mise à jour d'état que la première instance abandonnée n'utilise jamais.
3. Afficher les états de chargement, de résultat et de repli
Utilisez le hook comme n'importe quel autre hook de données, en gardant un état par défaut sensé visible tant que status n'a pas quitté 'loading'.
TypeScript (JSX)
function RegionBanner() {
const { geo, status } = useVisitorGeo();
if (status === "loading") return <p>Détection de votre région…</p>;
if (status === "error" || !geo?.country) return <p>Affichage de la région par défaut</p>;
return <p>Affichage du contenu pour {geo.city ?? geo.country}</p>;
}4. Conserver un choix explicite du visiteur
Même règle que le guide JavaScript pur : vérifiez l'existence d'une préférence enregistrée avant d'appliquer le pays suggéré, et ne vous rabattez sur le résultat du hook que si aucune préférence n'existe encore.
TypeScript
const preferred = localStorage.getItem("preferredCountry");
const country = preferred ?? geo?.country ?? "US";Erreurs et cas limites
Une origine non autorisée échoue avant que votre code ne voie une réponse normale — ajoutez d'abord les URL de développement et de production de l'application aux origines autorisées de la clé. Tous les champs de GeoResponse sauf ip et isEUCountry sont annulables (nullable), donc status === 'ready' ne suffit pas à lui seul ; vérifiez aussi le champ précis que vous vous apprêtez à afficher, comme le fait le repli ci-dessus avec geo?.country.
Étape suivante
Vous utilisez Next.js ? Son modèle de rendu serveur change l'endroit où cette requête peut s'exécuter en toute sécurité — voir le guide Next.js pour la répartition client/serveur et un modèle serveur à clé secrète pour les IP fournies.
Pages associées
- SDK JavaScript@digitload/watch-ip-sdk sur npm.
- Géolocalisation du visiteurAppelez GET /v1/geo depuis le navigateur avec une clé publiable.
- Référence de GET /v1/geoRéférence complète des champs pour le point de terminaison de géolocalisation du visiteur.
- Guide Next.jsChoisir où exécuter votre requête de position en Next.js.