Automatiser les épingles Pinterest pour les sites statiques via RSS et balises méta
Pour intégrer votre site à Pinterest, commencez par vérifier votre domaine. Dans Pinterest Business Hub, choisissez la méthode des balises méta et insérez-la dans le <head> de votre page d'accueil :
<meta name="p:domain_verify" content="12ac6ff1eaa70a3386sg439fda58bbb6"/>
Cela permet à Pinterest d'indexer les pages avec des Rich Pins. Ensuite, ajoutez des balises méta dans le <head> de chaque article :
<meta name="is_article" content="true">
<meta name="pinterest_description" content="Description de l'épingle, 150–200 caractères">
<meta name="pinterest_image" content="https://example.com/image.webp">
<meta name="article_published_at" content="2026-04-03T12:00:00+03:00">
L'image doit être verticale (1000×1500 px), servie via HTTPS et inférieure à 2 Mo. Sans pinterest_image, Pinterest utilise la première <img> de la page, ce qui est souvent sous-optimal.
Générer un flux RSS avec un script Node.js
Pinterest analyse les flux RSS pour créer automatiquement des épingles. Utilisez un script pour scanner les fichiers HTML, extraire les métadonnées et générer rss.xml.
Créez generate-rss.js dans un dossier scripts :
import fs from 'node:fs/promises';
import path from 'node:path';
import * as cheerio from 'cheerio';
// ================== PARAMÈTRES (À PERSONNALISER) ==================
const BASE_URL = 'https://VOTRE_SITE.com';
const ROOT_DIR = path.resolve(process.cwd(), 'dist');
const OUTPUT_RSS_PATH = path.join(ROOT_DIR, 'rss.xml');
const CHANNEL_TITLE = 'Nom de votre blog';
const CHANNEL_DESCRIPTION = 'Description : articles sur le développement, le SEO, le design';
// ================== NE PAS MODIFIER CI-DESSOUS ==================
function escapeXml(value = '') {
return value
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
function getMimeTypeByExt(urlOrPath = '') {
const ext = urlOrPath.split('.').pop()?.toLowerCase();
switch (ext) {
case 'jpg': case 'jpeg': return 'image/jpeg';
case 'png': return 'image/png';
case 'webp': return 'image/webp';
case 'gif': return 'image/gif';
default: return 'image/*';
}
}
function buildArticleUrl(filePath) {
const relativePath = path.relative(ROOT_DIR, filePath).replace(/\\/g, '/');
return `${BASE_URL}/${relativePath}`;
}
function buildImageUrl(src) {
if (!src) return '';
if (/^https?:\/\//i.test(src)) return src;
if (src.startsWith('/')) return `${BASE_URL}${src}`;
return `${BASE_URL}/${src}`;
}
async function collectHtmlFiles(dir) {
const entries = await fs.readdir(dir, { withFileTypes: true });
const files = [];
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
const nested = await collectHtmlFiles(fullPath);
files.push(...nested);
} else if (entry.isFile() && entry.name.endsWith('.html')) {
files.push(fullPath);
}
}
return files;
}
async function parseArticle(filePath) {
const content = await fs.readFile(filePath, 'utf8');
const $ = cheerio.load(content);
const isArticle = $('meta[name="is_article"]').length > 0;
if (!isArticle) return null;
const title = $('h1').first().text().trim() || 'Sans titre';
const pinterestDescription = $('meta[name="pinterest_description"]').attr('content')?.trim() || '';
const pinterestImg = $('meta[name="pinterest_image"]').attr('content');
let firstImgSrc = $('img').first().attr('src') || '';
if (firstImgSrc.endsWith('.svg')) firstImgSrc = '';
const imageUrl = buildImageUrl(pinterestImg || firstImgSrc);
let pubDate;
const articleDateMeta = $('meta[name="article_published_at"]').attr('content');
if (articleDateMeta) {
const parsed = new Date(articleDateMeta);
if (!isNaN(parsed.getTime())) pubDate = parsed;
}
if (!pubDate) {
const stat = await fs.stat(filePath);
pubDate = stat.mtime;
}
return { title, pinterestDescription, url: buildArticleUrl(filePath), imageUrl, pubDate };
}
function buildRssXml(items) {
const itemsXml = items.map(item => {
const enclosure = item.imageUrl ? `\n <enclosure url="${escapeXml(item.imageUrl)}" type="${getMimeTypeByExt(item.imageUrl)}" />` : '';
return `\n <item>\n <title>${escapeXml(item.title)}</title>\n <link>${escapeXml(item.url)}</link>\n <description><![CDATA[${item.pinterestDescription}]]></description>\n <pubDate>${item.pubDate.toUTCString()}</pubDate>${enclosure}\n </item>`;
}).join('\n');
return `<?xml version="1.0" encoding="UTF-8"?>\n<rss version="2.0">\n<channel>\n <title>${escapeXml(CHANNEL_TITLE)}</title>\n <link>${escapeXml(BASE_URL)}</link>\n <description>${escapeXml(CHANNEL_DESCRIPTION)}</description>${itemsXml}\n</channel>\n</rss>`;
}
async function main() {
console.log('🔍 Recherche HTML dans :', ROOT_DIR);
const htmlFiles = await collectHtmlFiles(ROOT_DIR);
console.log(`📄 Fichiers HTML trouvés : ${htmlFiles.length}`);
const articles = [];
for (const filePath of htmlFiles) {
const article = await parseArticle(filePath);
if (article) articles.push(article);
}
console.log(`📰 Articles avec is_article : ${articles.length}`);
if (!articles.length) {
console.warn('⚠️ Aucun article trouvé. RSS non créé.');
return;
}
articles.sort((a, b) => b.pubDate - a.pubDate);
const rssXml = buildRssXml(articles);
await fs.writeFile(OUTPUT_RSS_PATH, rssXml, 'utf8');
console.log(`✅ RSS enregistré : ${OUTPUT_RSS_PATH}`);
}
main().catch(err => {
console.error('❌ Erreur :', err);
process.exit(1);
});
Pour exécuter :
npm install cheerio- Configurez
BASE_URL,ROOT_DIRet les détails du canal. node generate-rss.js
Le script scanne récursivement le HTML, analyse avec Cheerio, échappe le XML, détermine les types MIME par extension et construit des URL absolues. Il trie par pubDate.
Connecter le RSS à Pinterest et automatiser
Sur Pinterest : "Créer" → "Rich Pins" → "Flux RSS" → collez https://votre-site.com/rss.xml. Les épingles se génèrent en 6–24 heures.
Processus :
- Ajoutez un article avec des balises méta.
- Exécutez
node generate-rss.js. - Pinterest analyse le RSS et crée des épingles à partir de
<title>,<description>et<enclosure>.
Pour une automatisation complète, intégrez dans CI/CD (par exemple, GitHub Actions) ou cron : 0 0 * cd /chemin/vers/projet && node scripts/generate-rss.js.
Avantages de cette approche :
- Fonctionne avec les sites statiques (Hugo, Eleventy, HTML simple).
- Aucun CMS ou plugin requis.
- Évolutif jusqu'à des milliers d'articles.
- Pinterest met en cache le RSS, donc les mises à jour en temps réel ne sont pas nécessaires.
Points clés
- Vérifiez votre domaine avec la balise méta
p:domain_verifypour l'indexation. - Utilisez
pinterest_imagepour contrôler les visuels des épingles. - Le script gère les solutions de repli sur
mtimeet la première<img>. - Le RSS inclut
<enclosure>pour les images avec types MIME. - Automatisez via cron ou CI pour la production.
— Editorial Team
Aucun commentaire pour le moment.