Checklist de lancement

Avant d'annoncer le site : robots.txt et sitemap.xml générés par Next.js, les fichiers les plus lourds allégés, et tout ce que les pages précédentes ont mis en place vérifié depuis l'extérieur — redirections, 404, certificat, en-têtes, IPv6, HTTP/3, performance — avec un script qui affiche PASS ou FAIL.

débutant~30 min de manipulation
#launch#seo#robots#sitemap#tls#hsts#performance#nextjs

Pas encore validée de bout en bout — sois le premier.Signaler un problème

Brouillon — pas encore exécuté de bout en bout. Cette page est écrite mais son auteur ne l'a pas encore déroulée sur une vraie machine. Des commandes peuvent être fausses : lis avant de lancer, et dis-nous ce qui casse.

En un coup d'œilLe site, vu de l'extérieur
Ton VPS chez OVH
openscancurl · opensslcrawl
Ton portablecurl · dig · openssl
Testeurs publicsSSL Labs · securityheaders · Lighthouse
https://${DOMAIN}Caddy · static files
Moteurs de rechercheGoogle · Bing

Ton portable et quelques testeurs publics vérifient https://${DOMAIN} comme un visiteur l'atteint : redirections, certificat, en-têtes, IPv6, vitesse. Les moteurs de recherche lisent robots.txt et sitemap.xml sur le même serveur.

Le site est en ligne. Avant d'en parler à qui que ce soit, cette page ajoute les deux fichiers qu'un export statique ne produit pas tout seul — robots.txt et sitemap.xml —, allège les fichiers qui ralentissent les pages, puis vérifie depuis l'extérieur, comme le voient un visiteur ou un robot d'indexation, tout ce que les pages 4 à 7 ont mis en place. Elle se termine par les moteurs de recherche et une courte liste pour le jour de l'annonce.

Avant de commencer

Le site est déployé avec le script de la page 6 et répond sur son domaine. Tout ce qui suit se fait sur ton Mac, depuis le dossier du projet, sauf les modifications HSTS sur le serveur. Prévois deux amis comme testeurs externes pour la fin : un en données mobiles, un sur le Wi-Fi d'un autre opérateur. D'abord, la page d'accueil répond :

Vérification
$curl -s -o /dev/null -w '%{http_code}' https:///
Retour attendu
200

Ajouter robots.txt et sitemap.xml

output: "export" n'écrit que ce que l'application déclare. Next.js a deux fichiers de métadonnées pour ça : app/robots.ts et app/sitemap.ts. Au build, chacun devient un fichier ordinaire dans out/.

Règle d'abord le choix d'indexation dans le panneau. Laisse-le désactivé tant que le site contient encore des exemples ou des fonctions qui font semblant de marcher, comme un formulaire de contact qui simule l'envoi : les robots les indexeraient tels quels. Active-le, et redéploie, le jour du lancement.

Dans un terminal sur ton Mac, va dans le dossier du projet, puis copie chaque bloc de fichier ci-dessous et colle-le dans le terminal : chacun écrit son fichier.

Mac
$cd
Macécrit un fichierapp/robots.ts
import type { MetadataRoute } from "next";
export const dynamic = "force-static";
const SITE = "https://";
export default function robots(): MetadataRoute.Robots {
return {
rules: { userAgent: "*", allow: "/" },
sitemap: SITE + "/sitemap.xml",
};
}
Macécrit un fichierapp/sitemap.ts
import type { MetadataRoute } from "next";
export const dynamic = "force-static";
const SITE = "https://";
const ROUTES = [
"/", "/bio/", "/bookmarks/", "/chess/", "/clippings/", "/contact/",
"/endeavor/", "/how-i-want-to-live/", "/journey/", "/lately/", "/library/",
"/own/", "/pearl/", "/picture/", "/support/", "/thought/", "/travel/", "/writing/",
];
export default function sitemap(): MetadataRoute.Sitemap {
const now = new Date();
return ROUTES.map((path) => ({ url: SITE + path, lastModified: now }));
}

Déploie avec le script de la page 6, qui construit avant d'envoyer, puis vérifie que les deux fichiers ont bien été générés :

Mac
$cd
$./scripts/deploy.sh
$ls out/robots.txt out/sitemap.xml
Vérification
$curl -s https:///robots.txt | head -1
Retour attendu
User-Agent: *
Si le build échoue ou si out/robots.txt manque

Un public/robots.txt ou public/sitemap.xml entre en conflit avec celui qui est généré : supprime celui de public/. Une erreur qui cite dynamic ou revalidate sur /robots.txt veut dire que la ligne force-static manque. Un projet organisé en src/app/ prend les deux fichiers à cet endroit.

Alléger les fichiers les plus lourds

Un WAV de 50 Mo sur une page, c'est 50 Mo à télécharger sur un téléphone. Liste tout ce que le site sert au-delà de 5 Mo :

Mac
$cd
$find out -type f -size +5M -exec ls -lh {} \; | sort -k5 -h

L'audio : convertis chaque WAV en Opus, ou en MP3 pour les navigateurs les plus anciens, puis change la référence dans le code.

Mac
$brew install ffmpeg
$ffmpeg -i public/audio/track.wav -c:a libopus -b:a 128k public/audio/track.opus
$ffmpeg -i public/audio/track.wav -c:a libmp3lame -q:a 2 public/audio/track.mp3
$grep -rn '\.wav' app components lib 2>/dev/null

Les images : rien sur une page web n'a besoin de plus de 2400 px sur le grand côté.

Mac
$cd
$cp -R public ../public-before-resize
$find public -iname '*.jp*g' -size +1M -exec sips -Z 2400 {} \;
$du -sh ../public-before-resize public

Vérifier depuis l'extérieur

Redirections et codes de statut

Mac
$curl -sI http:/// | grep -iE '^(HTTP|location)'
$curl -sI https://www./ | grep -iE '^(HTTP|location)'
$curl -s -o /dev/null -w '%{http_code}\n' https:///no-such-page/
Sortie attendue
HTTP/1.1 308 Permanent Redirect
Location: https:///
HTTP/2 301
location: https:///
404
Vérification
$curl -s -o /dev/null -w '%{http_code}' https:///no-such-page/
Retour attendu
404

TLS

Ouvre le test SSL Labs pour ton domaine. Il prend environ deux minutes. Vise A ; A+ demande un max-age HSTS d'au moins six mois, que l'étape qui suit ces vérifications met en place.

Mac
$open "https://www.ssllabs.com/ssltest/analyze.html?d="
$curl -sv -o /dev/null https:/// 2>&1 | grep -E 'issuer|expire date'
Vérification
$echo | openssl s_client -connect :443 -servername  2>/dev/null | openssl x509 -noout -issuer | grep -o 'Let.s Encrypt'
Retour attendu
Let's Encrypt

En-têtes de sécurité

Mac
$open "https://securityheaders.com/?q=https:///&followRedirects=on"
$curl -sI https:/// | grep -iE '^(strict-transport|x-content-type|x-frame|referrer|permissions|content-security)'

Attends-toi à strict-transport-security, x-content-type-options: nosniff, referrer-policy et ce que la page 5 a ajouté d'autre. L'absence de content-security-policy est normale à ce stade : elle coûte une note, pas une sécurité que tu avais déjà.

IPv6 et HTTP/3

Mac
$dig +short AAAA
$curl -6 -sI https:/// | head -1
$curl -sI https:/// | grep -i '^alt-svc'

Usurpation d'adresse mail

Si tu as indiqué en page 4 que le domaine n'envoie pas de mail, vérifie que les enregistrements « pas de mail » sont publiés, pour que personne ne puisse envoyer du hameçonnage en ton nom :

Mac
$dig +short TXT _dmarc.
$dig +short TXT | grep spf1

Performance

Dans Chrome, ouvre le site en navigation privée, puis DevTools → Lighthouse → Mobile → Analyze page load. Ou passe par PageSpeed Insights, qui lance le même test depuis les serveurs de Google :

Mac
$open "https://pagespeed.web.dev/report?url=https:///"

Passer HSTS à un an

La page 5 a démarré l'en-tête HSTS à un jour. Une fois toutes les vérifications ci-dessus au vert, passe-le à un an, sur le serveur :

Mac
$ssh vps
Serveur·
$sudo sed -i 's/max-age=86400"/max-age=31536000"/' /etc/caddy/Caddyfile
$sudo -u caddy caddy validate --config /etc/caddy/Caddyfile && sudo systemctl reload caddy
Vérification
$curl -sI https:/// | grep -i '^strict-transport-security'
Retour attendu
strict-transport-security: max-age=31536000

Moteurs de recherche

Dis à Google et à Bing que le site existe et où se trouve le sitemap.

  1. Dans Google Search Console, ajoute une propriété de type Domaine avec . Google affiche un enregistrement TXT qui commence par google-site-verification=.
  2. Dans le Manager Infomaniak, Zone DNS du domaine (comme en page 4), ajoute cet enregistrement TXT sur le domaine lui-même, puis clique sur Valider dans Search Console. Ça peut prendre quelques minutes.
  3. Dans Search Console → Sitemaps, saisis sitemap.xml et envoie.
  4. Dans Bing Webmaster Tools, connecte-toi et choisis l'import depuis Google Search Console : il reprend le site et le sitemap.
Mac
$dig +short TXT | grep google-site-verification

Annoncer

Un dernier coup d'œil avant de publier le lien et de demander à tes testeurs externes d'ouvrir le site sur leur téléphone :

  • Favicon : /favicon.ico répond 200 (commande ci-dessous). Next.js sert app/favicon.ico ou app/icon.png.
  • Image d'aperçu des liens : un JPEG de 1200 × 630 en app/opengraph-image.jpg (Next.js ajoute les balises meta) et metadataBase réglé sur https:// dans le layout racine, pour que l'URL de l'image soit absolue. Exporte-la depuis les originaux de photos-26-og/ ; eux restent hors du site. Colle le lien dans un message à toi-même pour voir l'aperçu.
  • Page 404 : mise en forme, avec un chemin vers l'accueil.
  • Fonctions en attente : le formulaire de contact et la sauvegarde des parties d'échecs n'ont pas encore de backend ; cache-les ou marque-les « bientôt ».
  • Surveillance : la sonde de disponibilité de la page 7 est au vert et ses alertes arrivent à .
  • Après le lancement : les flux RSS de /lately notés dans le TODO du projet peuvent attendre ; un flux ajouté la semaine prochaine marche pareil.
Mac
$curl -s -o /dev/null -w '%{http_code}\n' https:///favicon.ico
$curl -s https:/// | grep -o '<meta property="og:image"[^>]*>'

Terminé

La série est complète : un site Next.js construit sur ton Mac, servi en HTTPS par Caddy depuis ton propre VPS Debian chez OVH, sur un domaine géré chez Infomaniak, déployé de façon atomique, sauvegardé, surveillé et vérifié depuis l'extérieur, avec Google et Bing qui savent où trouver le sitemap. Le script Automatique de cette page sert aussi de test rapide après chaque gros changement.

Une page à venir, pas encore écrite — la page 9 — donnera un backend au formulaire de contact et aux sauvegardes d'échecs sur le même VPS : un petit service Node derrière Caddy, avec SQLite.

Tout a fonctionné ?

Si tu as suivi cette page jusqu'au bout sur une vraie machine, dis-le. Ta validation est datée et enregistre ta stack : le prochain lecteur sur le même chemin sait que ça marche toujours.

Cette copie est en lecture seule. Pour dire que ça marche, ou que ça ne marche pas, ouvre une issue

Seuls tes choix de stack sont enregistrés, jamais tes valeurs. Le pseudo reste sur ce navigateur.