From 46dc25f1aa47e4c8e78a2b63094845036a3f493a Mon Sep 17 00:00:00 2001 From: ache Date: Fri, 11 Aug 2023 10:59:02 +0200 Subject: Improve SEO: basis --- package.json | 4 +++- src/build/i18n.mjs | 8 ++++++-- src/build/index.mjs | 32 +++++++++++++++++++++++++++----- src/build/utils.mjs | 10 ++++++++++ src/templates/header.tmpl | 2 +- 5 files changed, 47 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 531dc9f..3cc65c2 100644 --- a/package.json +++ b/package.json @@ -39,12 +39,13 @@ "hast-util-raw": "^7.2.1", "hast-util-select": "^5.0.1", "hast-util-to-text": "^3.1.1", + "html-minifier": "^4.0.0", "mkdirp": "^1.0.4", "mustache": "^4.2.0", "rehype-autolink-headings": "^6.1.1", "rehype-highlight": "^5.0.2", - "rehype-picture": "^4.0.2", "rehype-katex": "^6.0.2", + "rehype-picture": "^4.0.2", "rehype-raw": "^6.1.1", "rehype-slug": "^5.0.1", "rehype-stringify": "^9.0.3", @@ -57,6 +58,7 @@ "remark-slug": "^7.0.1", "remark-toc": "^8.0.1", "rss": "^1.2.2", + "sitemap": "^7.1.1", "terser": "^5.12.1", "toml": "^3.0.0", "unist-builder": "^3.0.0", diff --git a/src/build/i18n.mjs b/src/build/i18n.mjs index 8ba4511..b8d01f0 100644 --- a/src/build/i18n.mjs +++ b/src/build/i18n.mjs @@ -23,7 +23,9 @@ const i18n = { 'quick_description': 'Programmation, Algorithmique, Système, *pick you poison*', 'description': `Ceci est un flux RSS à destination des agrégateurs de contenu.
\nEn tant qu'être humain vous cherchez certainement mon site web.` }, - toc_keyword: "Sommaire" + toc_keyword: "Sommaire", + tag_desc: "Liste des articles ayant le tag", + index_desc: "Blog personnel à propos de programmation, logiciel libre et autohébergement. Essayons de rendre le monde meilleur.", }, en: { intro: { @@ -45,7 +47,9 @@ const i18n = { 'title': 'ache: Personal blog', 'description': `This is a RSS feed for content agreagator.
\nAs a human being, you are certainly looking for my website.` }, - toc_keyword: "Table of contents" + toc_keyword: "Table of contents", + tag_desc: "List of articles with the tag", + index_desc: "Personal blog about programming, free software and self-hosting. Let's try to make the world a better place.", } } diff --git a/src/build/index.mjs b/src/build/index.mjs index ad126a8..fa5f450 100644 --- a/src/build/index.mjs +++ b/src/build/index.mjs @@ -7,6 +7,10 @@ import loadMD from './loadMD.mjs'; import {cmpArticles} from './article.mjs'; import i18n from './i18n.mjs'; import {addDescription} from './i18n.mjs'; +import {minifyHTML} from './utils.mjs'; + +import { SitemapStream, streamToPromise } from 'sitemap' +import { Readable } from 'stream' const leftPanelTmpl = fs.readFileSync('src/templates/left.tmpl', 'utf8'); const likesTmpl = fs.readFileSync('src/templates/likes.tmpl', 'utf8'); @@ -27,6 +31,8 @@ const partials = { // Load global variables const svg = loadSVG(); +let links = []; + for (const lang in i18n) { const tagsArticle = new Map(); const filter = process.argv.slice(2); @@ -45,11 +51,13 @@ for (const lang in i18n) { title: i18n[lang].title, metaData: article.metaData, alt_lang: addDescription(article.metaData.alt_lang), + description: i18n[lang].intro, }; const output = mustache.render(articleTmpl, context, partials); console.log(`Create : ${article.title}`); - fs.writeFileSync(`articles/${article.name}.html`, output); + fs.writeFileSync(`articles/${article.name}.html`, minifyHTML(output)); + links.push({url: context.canonical, changefreq: 'yearly', priority: 0.6, img: [{url: context.metaData.imageUrl}]}) for (const tag of article.metaData.tags) { if (tagsArticle.has(tag)) { @@ -61,7 +69,6 @@ for (const lang in i18n) { } // Set of pages language dependant - try { fs.mkdirSync(`${lang}/tag`, {recursive: true}); } catch { @@ -81,15 +88,18 @@ for (const lang in i18n) { lang, tag, articles, + description: `${i18n[lang]['tag_desc']} ${tag}.`, }; const output = mustache.render(tagTmpl, context, partials); - fs.writeFileSync(`${lang}/tag/${tag}.html`, output); + fs.writeFileSync(`${lang}/tag/${tag}.html`, minifyHTML(output)); + links.push({url: `${baseUrl}${lang}/tag/${tag}`, changefreq: 'monthly', priority: 0.3}) } console.log(`Create RSS Flux: ${lang}/rss.xml`); const xmlFeed = getRSS(articles, baseUrl, lang); fs.writeFileSync(`${lang}/rss.xml`, xmlFeed); + links.push({url: `${baseUrl}${lang}/rss.xml`, changefreq: 'monthly', priority: 0.3}) { const alt_lang = { @@ -107,14 +117,26 @@ for (const lang in i18n) { title: i18n[lang].title, intro: i18n[lang].intro, lang, - canonical: baseUrl, + canonical: `${baseUrl}${lang}`, svg, articles, alt_lang: [alt_lang[lang]], + description: i18n[lang].index_desc, }; console.log(`Create : Home page ${lang}`); const output = mustache.render(indexTmpl, context, partials); - fs.writeFileSync(`${lang}/index.html`, output); + fs.writeFileSync(`${lang}/index.html`, minifyHTML(output)); + links.push({url: `${baseUrl}${lang}`, changefreq: 'monthly', priority: 0.7, img: [{url: "https://ache.one/res/ache.svg"}]}) } } + +console.log(`Create: sitemap.xml`); +// Create a stream to write to +const stream = new SitemapStream({hostname: 'https://ache.one'}) + +// Return a promise that resolves with your XML string +streamToPromise(Readable.from(links).pipe(stream)).then((data) => + data.toString() +).then(sitemapXML => fs.writeFileSync("sitemap.xml", sitemapXML)); + diff --git a/src/build/utils.mjs b/src/build/utils.mjs index e69de29..fa85ee6 100644 --- a/src/build/utils.mjs +++ b/src/build/utils.mjs @@ -0,0 +1,10 @@ +import { minify } from 'html-minifier'; + +export const minifyHTML = (html) => minify(html, { + removeAttributeQuotes: true, + removeComments: true, + minifyJS: true, + minifyCSS: true, + collapseWhitespace: true, + collapseBooleanAttributes: true, +}) diff --git a/src/templates/header.tmpl b/src/templates/header.tmpl index 6085192..e92da4a 100644 --- a/src/templates/header.tmpl +++ b/src/templates/header.tmpl @@ -8,6 +8,6 @@ - + -- cgit v1.2.3