Visibilité du site : métadonnées SEO et plan du site
Pour un site web axé sur le contenu, l'optimisation pour les moteurs de recherche (SEO) est essentielle. Elle permet aux utilisateurs de trouver et d'accéder à votre contenu via des moteurs de recherche tels que Google ou Bing, ce qui est l'objectif de ce blog. Si ce n'est pas votre objectif, n'hésitez pas à sauter cet article.
Note
L'optimisation pour les moteurs de recherche (SEO) améliore la qualité et la quantité du trafic sur un site web provenant des moteurs de recherche. Elle se concentre sur le trafic organique plutôt que sur le trafic direct ou payé.
Les Fondamentaux
Commençons par intégrer des métadonnées de base dans notre site web.
Dans un premier temps, nous devons spécifier la langue de notre site web en ajoutant la clé lang
dans le fichier config.mts
:
import { defineConfig } from 'vitepress'
export default defineConfig({
lang: 'fr-FR',
})
Ensuite, nous établissons le titre et la description de notre site web en insérant les clés title
et description
dans le fichier config.mts
:
import { defineConfig } from 'vitepress'
export default defineConfig({
// ...
title: 'Garabit',
description: 'Un lieu qui reflète mes pensées et mes idées',
})
Le titre servira également de suffixe pour le titre de chaque page. Par exemple, le titre de la page de blog sera Blog | Garabit
.
Nous pouvons vérifier ces ajouts en examinant le code HTML généré dans le répertoire .vitepress/dist
.
<!DOCTYPE html>
<html lang="fr-FR" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Blog | Garabit</title>
<meta name="description" content="Les derniers articles, tutoriels et ressources sur le développement web, la programmation et plus encore.">
<meta name="generator" content="VitePress v1.4.1">
<!-- ... -->
</head>
</html>
Note
VitePress intègre ses propres métadonnées dans le code HTML généré, ce qui entraîne plus de balises meta
que celles que nous avons ajoutées manuellement.
Métadonnées Statistiques
Ajoutons maintenant quelques métadonnées statiques pour améliorer les capacités SEO. Ces métadonnées s'appliquent uniformément à toutes les pages du site web.
Pour ajouter des métadonnées statiques, insérons la clé head
dans le fichier config.mts
:
import { defineConfig } from 'vitepress'
export default defineConfig({
// ...
head: [
['meta', { name: 'twitter:site', content: '@soubiran_' }], // Veuillez changer cela avant de déployer
['meta', { name: 'twitter:card', content: 'summary_large_image' }],
['meta', { property: 'og:image:width', content: '1200' }],
['meta', { property: 'og:image:height', content: '630' }],
['meta', { property: 'og:image:type', content: 'image/png' }],
['meta', { property: 'og:site_name', content: 'Garabit' }],
['meta', { property: 'og:type', content: 'website' }],
[
'meta',
{ property: 'og:url', content: 'https://garabit.barbapapazes.dev' }, // Veuillez changer cela avant de déployer
],
],
})
Ces métadonnées sont utilisées par des réseaux sociaux comme Twitter et Facebook pour afficher un aperçu du site web lorsqu'il est partagé. Le préfixe og
indique Open Graph, un protocole qui permet aux pages web de devenir des objets riches dans un réseau social.
Note
Les futurs articles exploreront la génération automatique d'images Open Graph pour les articles de blog.
Métadonnées Dynamiques
Pour un SEO optimal, chaque page devrait comporter un titre Open Graph, une description et une URL canonique. Ce sont des métadonnées dynamiques et varient selon chaque page.
Nous avons deux méthodes pour ajouter des métadonnées dynamiques à notre site :
- Dans le frontmatter de chaque fichier Markdown : Bien que simple, cette méthode n'est pas la plus maintenable. L'ajout de nouvelles métadonnées nécessite de mettre à jour chaque fichier Markdown et d'écrire du YAML avec des tableaux imbriqués, ce qui peut être fastidieux.
---
title: Mon Article de Blog Génial
description: Un article de blog qui changera votre vie
head:
- - meta
- property: og:title
content: Mon Article de Blog Génial
- - meta
- property: og:description
content: Un article de blog qui changera votre vie
---
En raison de la redondance et de la complexité, je souhaite éviter cette méthode.
Heureusement, une seconde méthode existe :
- Dans le fichier
config.mts
: Une solution plus maintenable consiste à utiliser l'optiontransformPageData
pour insérer des métadonnées dynamiques dans chaque page, en modifiant les données avant le rendu.
import { defineConfig } from 'vitepress'
export default defineConfig({
// ...
transformPageData: (page) => {
// Initialiser le frontmatter `head` s'il n'existe pas.
pageData.frontmatter.head ??= []
// Ajouter les balises meta de base au frontmatter.
pageData.frontmatter.head.push(
['meta', { property: 'og:title', content: pageData.title }],
['meta', { name: 'twitter:title', content: pageData.title }],
['meta', { property: 'og:description', content: pageData.description }],
['meta', { name: 'twitter:description', content: pageData.description }],
)
},
})
Cette approche est efficace, permettant l'ajout de multiples métadonnées dynamiques sans modifier chaque fichier Markdown ou dupliquer les métadonnées.
Note
Si vous souhaitez ajouter plus de métadonnées dynamiques, vous pouvez le faire de la même manière que les métadonnées Open Graph en utilisant cette technique.
URL Canonique
L'URL canonique spécifie la version préférée d'une page web, empêchant ainsi les problèmes de contenu dupliqué. Sans cela, les moteurs de recherche peuvent avoir du mal à identifier la même page, quelles que soient les variations d'URL, ce qui peut retarder l'indexation. Cette situation peut se produire plus fréquemment que nous le pensons. Par exemple, un article de blog partagé dans une newsletter pourrait inclure un paramètre de suivi, conduisant le moteur de recherche à indexer l'URL avec le paramètre au lieu de l'URL originale, ou pire, pas du tout. Il est donc crucial d'ajouter une URL canonique à chaque page.
Dans la fonction transformPageData
, nous pouvons accéder au path
de la page pour inférer l'URL canonique.
Tout d'abord, installons le package ufo, une bibliothèque de manipulation d'URL par UnJS :
pnpm add -D ufo
Ensuite, utilisons ce package pour créer l'URL canonique :
import { joinURL, withoutTrailingSlash } from 'ufo'
import { defineConfig } from 'vitepress'
export default defineConfig({
// ...
transformPageData: (page) => {
// Initialiser le frontmatter `head` s'il n'existe pas.
pageData.frontmatter.head ??= []
// ...
// Créer l'URL canonique
pageData.frontmatter.head.push([
'link',
{
rel: 'canonical',
href: joinURL(
'https://garabit.barbapapazes.dev', // Modifiez cela avant le déploiement
withoutTrailingSlash(pageData.filePath.replace(/(index)?\.md$/, '')),
),
},
])
},
})
La fonction joinURL
combine l'URL de base du site avec le chemin de la page, évitant le /
pour prévenir les //
dans l'URL. La fonction withoutTrailingSlash
supprime le slash final du chemin de la page. Si vous préférez un slash final, la fonction withTrailingSlash
peut être utilisée alternativement. De plus, index.md
ou .md
doit être retiré du chemin pour générer une URL propre.
Chaque page dispose désormais d'une URL canonique. Inspectons le code HTML généré pour vérifier l'implémentation.
<!DOCTYPE html>
<html lang="fr-FR" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Mon Article de Blog Génial | Garabit</title>
<meta name="description" content="Un article de blog qui changera votre vie">
<meta name="twitter:site" content="@soubiran_">
<meta name="twitter:card" content="summary_large_image">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:type" content="image/png">
<meta property="og:site_name" content="Garabit">
<meta property="og:type" content="website">
<meta property="og:url" content="https://garabit.barbapapazes.dev">
<meta property="og:title" content="Mon Article de Blog Génial">
<meta name="twitter:title" content="Mon Article de Blog Génial">
<meta property="og:description" content="Un article de blog qui changera votre vie">
<meta name="twitter:description" content="Un article de blog qui changera votre vie">
<link rel="canonical" href="https://garabit.barbapapazes.dev/mon-article-de-blog-genial">
<!-- ... -->
</head>
</html>
Concernant les URL propres, vous pourriez remarquer l'extension .html
à la fin des URL. VitePress génère des fichiers HTML pour chaque fichier Markdown, facilitant le déploiement puisque le chemin /mon-article-genial.html
correspond directement au fichier mon-article-genial.html
. Cependant, ce n'est pas très bon pour le SEO ni esthétiquement agréable. En définissant cleanUrls
sur true
dans le fichier config.mts
, nous pouvons éliminer l'extension .html
de l'URL :
import { defineConfig } from 'vitepress'
export default defineConfig({
// ...
cleanUrls: true,
})
Lorsque ce paramètre est activé, le serveur doit être configuré pour servir l'URL /mon-article-genial
avec le fichier mon-article-genial.html
, sans redirection. La plupart des services de déploiement comme Cloudflare Pages, Vercel ou Netlify s'y prêtent. Les serveurs personnalisés peuvent nécessiter des ajustements de configuration de proxy inverse.
Warning
Veuillez toujours vous assurer que l'URL canonique correspond à l'URL servie par le serveur. Si vous choisissez de ne pas activer ce paramètre, ajoutez l'extension .html
à l'URL canonique.
Plan du Site
Un plan du site aide les moteurs de recherche à indexer un site web. C'est un fichier XML énumérant toutes les URL du site web, permettant aux moteurs de recherche de découvrir efficacement de nouvelles URL sans avoir à explorer entièrement le site.
VitePress simplifie la génération de plans du site. Il suffit d'ajouter trois lignes de code dans le fichier config.mts
:
import { defineConfig } from 'vitepress'
export default defineConfig({
// ...
sitemap: {
hostname: 'https://garabit.barbapapazes.dev', // Veuillez changer cela avant de déployer
},
})
Cela produira un fichier sitemap.xml
dans le répertoire .vitepress/dist
lors de la construction du site avec pnpm run build
. Vous pouvez soumettre ce fichier à la console SEO de votre moteur de recherche préféré.
<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
<url>
<loc>https://garabit.barbapapazes.dev/blog.html</loc>
</url>
<url>
<loc>https://garabit.barbapapazes.dev/blog/getting-started-with-vue3-and-vite.html</loc>
</url>
<url>
<loc>https://garabit.barbapapazes.dev/blog/getting-started-with-laravel.html</loc>
</url>
<url>
<loc>https://garabit.barbapapazes.dev/</loc>
</url>
</urlset>
Et voilà, le plan du site est prêt à être inclus dans la console SEO de votre choix.
Automatisation de la Mise en Page
Pour conclure cette section, simplifions la mise en page des articles de notre blog. Auparavant, nous devions définir manuellement la clé layout
sur blog-show
dans le frontmatter de chaque article. Bien que ce ne soit pas difficile, cette étape est oubliable et répétitive à travers les articles, tout comme les métadonnées.
Pour automatiser cela, réutilisons l'option transformPageData
pour insérer la clé layout
dans le frontmatter de chaque article, en vérifiant si le filePath
se trouve dans le répertoire src/blog
.
import { defineConfig } from 'vitepress'
export default defineConfig({
// ...
transformPageData: (page) => {
// Définir la mise en page pour les articles de blog
if (pageData.filePath.startsWith('blog/')) {
pageData.frontmatter.layout = 'blog-show'
}
},
})
Cette approche permet de retirer la clé layout
du frontmatter de chaque article, réduisant ainsi les risques d'oubli et minimisant la redondance. Cela illustre la force de l'automatisation !