Tous les articles
ViteHMRlocal developmentlocalhost tunneling

Vite + tunnel : HMR qui fonctionne vraiment

Tunneliser un serveur Vite fonctionne bien — sauf deux trucs qui vous piégeront au premier essai. La page charge mais HMR ne fonctionne pas. Ou la page ne charge pas car Vite refuse votre hostname tunnel. Deux one-liners de config une fois qu'on sait où regarder.

Problème 1 : "Blocked request. This host is not allowed."

Vite 5+ ajoute une protection host-check par défaut. Si vous voyez ce message, c'est lui qui refuse *.portpreview.dev.

export default defineConfig({
  server: {
    host: true,
    allowedHosts: ['.portpreview.dev'],
  },
});

Le point initial est un match de suffixe — pratique car les sessions tunnel changent.

Problème 2 : HMR meurt silencieusement

HMR passe par WebSocket. Vite sert depuis localhost:5173 mais le navigateur charge depuis https://abc123.portpreview.dev. Le client HMR tente de se connecter à l'URL annoncée par le serveur — locale. Le tunnel ne forwarde pas ça, et HMR s'arrête sans bruit.

export default defineConfig({
  server: {
    host: true,
    allowedHosts: ['.portpreview.dev'],
    hmr: {
      clientPort: 443,
      protocol: 'wss',
    },
  },
});

Maintenant le client HMR se connecte à wss://abc123.portpreview.dev, le tunnel forwarde l'upgrade, les éditions se propagent.

Pourquoi tunneliser Vite

  • Tests mobile. Ouvrez l'URL sur un téléphone, même build avec HMR. Voir tests mobile avec tunnel.
  • Partage WIP. Lien à un designer ou PM, ils voient votre branche en live.
  • OAuth et webhooks nécessitant HTTPS. Voir mkcert vs tunnel.

SvelteKit, Astro, SolidStart utilisent Vite

Les configs ci-dessus s'appliquent à tout framework Vite. SvelteKit : même forme dans vite.config.js. Astro : sous vite dans astro.config.mjs. SolidStart, Nuxt 3 via Vite, Qwik City : même pattern.

Les builds de prod sont différents

Tout ce qui précède concerne le serveur de dev. vite preview ou un bundle servi statiquement n'a ni HMR ni host-check — le tunnel forwarde juste des fichiers.

Détails

  • CORS strict. Si votre front appelle une API sur un autre origin, configurez CORS côté API.
  • WebSockets applicatifs. HMR utilise un WebSocket. Si votre app en a un autre (chat, jeu), configurez-le aussi pour utiliser l'URL tunnel.
  • URL tunnel en env. On met l'URL tunnel active dans .env.local comme VITE_PUBLIC_URL.

Étapes

  1. Ajoutez server.host, allowedHosts, hmr à la config Vite.
  2. Redémarrez le dev server.
  3. Exécutez npx portpreview 5173.
  4. Ouvrez l'URL HTTPS dans le navigateur ou un téléphone.
  5. Éditez un composant. Vérifiez le HMR.

Si HMR ne tourne pas, ouvrez la console — Vite logue la tentative WebSocket.

Rejoignez la waitlist PortPreview.

Questions fréquentes

Pourquoi Vite refuse mon URL tunnel avec 'host is not allowed' ?
Vite 5+ ajoute un host-check qui rejette les hostnames inconnus. Ajoutez allowedHosts: ['.portpreview.dev'] (ou votre domaine tunnel) au server config.
Comment faire fonctionner HMR via un tunnel ?
Définissez hmr.clientPort: 443 et hmr.protocol: 'wss' dans vite.config.ts. Le client HMR se connecte via le HTTPS/WSS du tunnel au lieu de tenter localhost depuis l'extérieur.
Cela marche-t-il pour SvelteKit, Astro et Nuxt ?
Oui. Tout framework Vite reprend les mêmes options server.host, allowedHosts et hmr. Astro les imbrique sous vite dans astro.config.mjs ; les autres dans leur config Vite habituelle.