From 99ef7634e3ee9fed897c3d7021bfb55f7f2f4c4c Mon Sep 17 00:00:00 2001 From: nico Date: Fri, 27 Dec 2024 08:55:12 +0100 Subject: [PATCH 01/16] update to v5 + remove unmaintained i18n lib --- .gitignore | 3 +++ astro.config.mjs | 20 ++++-------------- bun.lockb | Bin 225821 -> 210419 bytes package.json | 15 ++++++------- src/components/EditorialContent.astro | 6 +++--- src/{content/config.ts => content.config.ts} | 4 ++++ .../articles/{[slug].astro => [id].astro} | 2 +- src/pages/en/articles/[slug].astro | 15 ------------- src/pages/en/articles/index.astro | 6 ------ src/pages/en/index.astro | 6 ------ src/pages/en/sitemap.astro | 6 ------ src/pages/en/snippets/[slug].astro | 15 ------------- src/pages/en/snippets/index.astro | 6 ------ src/pages/en/veille/index.astro | 6 ------ src/pages/en/work/index.astro | 6 ------ .../fragments/{[slug].astro => [id].astro} | 2 +- src/pages/index.astro | 17 +++++++++------ src/pages/veille/index.astro | 4 +++- tsconfig.json | 2 ++ 19 files changed, 38 insertions(+), 103 deletions(-) rename src/{content/config.ts => content.config.ts} (86%) rename src/pages/articles/{[slug].astro => [id].astro} (95%) delete mode 100755 src/pages/en/articles/[slug].astro delete mode 100755 src/pages/en/articles/index.astro delete mode 100755 src/pages/en/index.astro delete mode 100755 src/pages/en/sitemap.astro delete mode 100755 src/pages/en/snippets/[slug].astro delete mode 100755 src/pages/en/snippets/index.astro delete mode 100755 src/pages/en/veille/index.astro delete mode 100755 src/pages/en/work/index.astro rename src/pages/fragments/{[slug].astro => [id].astro} (95%) diff --git a/.gitignore b/.gitignore index 02f6e50..6691182 100755 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,6 @@ pnpm-debug.log* # macOS-specific files .DS_Store + +# i18n +astro_tmp_pages_* \ No newline at end of file diff --git a/astro.config.mjs b/astro.config.mjs index f52259f..f3c1ce1 100755 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,8 +1,5 @@ import { defineConfig } from "astro/config"; -// https://github.com/alexandre-fernandez/astro-i18n -import i18n from "astro-i18n"; - // https://astro.build/config import mdx from "@astrojs/mdx"; import sitemap from "@astrojs/sitemap"; @@ -10,24 +7,15 @@ import sitemap from "@astrojs/sitemap"; // https://astro.build/config export default defineConfig({ site: "https://www.nardu.in", + build: { + format: "directory", + }, image: { domains: ["assets.nardu.in"], remotePatterns: [{ protocol: "https" }], }, - markdown: { - syntaxHighlight: "prism", - }, integrations: [ - i18n(), mdx(), - sitemap({ - i18n: { - defaultLocale: "fr", // All urls that don't contain `en` - locales: { - fr: "fr-FR", // The `defaultLocale` value must present in `locales` keys - en: "en-US", - }, - }, - }), + sitemap(), ], }); diff --git a/bun.lockb b/bun.lockb index bb95c92f1e70f020b41aef25b57d8da116bbaeaf..6519f634b8c3ee17add6c61fbf601145b8299768 100755 GIT binary patch literal 210419 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

;uC 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 literal 225821 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�GG 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

    +
      { - // create a list of available alternative locale - availableLocales.map((locale) => ( + Object.entries(languages).map(([lang, label]) => (
    • - - {localeName(locale)} - + {label}
    • )) } diff --git a/src/i18n/ui.ts b/src/i18n/ui.ts new file mode 100644 index 0000000..e83786c --- /dev/null +++ b/src/i18n/ui.ts @@ -0,0 +1,150 @@ +export const languages = { + en: 'English', + fr: 'Français' +} + +export const defaultLang = 'fr' + +export const ui = { + en: { + accueil: 'home', + tagline: 'Freelance web developer specialized in accessibility.', + copyright: '(re)Made with Astro', + contact: { + title: 'contact', + email: 'Send me an email (open in application).', + tel: 'Call or text me (open in application).', + contenuVide: 'Soon: really nice content.' + }, + header: { + skipLink: 'Skip to content', + mainNav: 'Main menu', + homeLink: 'Back to homepage' + }, + sitemap: 'Site map', + prevNext: { + contenus: 'Similar content', + precedent: 'Previous', + suivant: 'Next' + }, + article: { + titre: 'articles', + tagline: 'I blog, sometimes.', + published: 'Published on {datetime|date(options)}' + }, + meta: { + publication: 'Published on', + modification: 'Last updated on', + credit: 'Image by' + }, + fragments: { + titre: 'snippets', + tagline: 'School with Nicool.' + }, + references: { + titre: 'work', + slug: 'work', + cta: 'Visit website', + tagline: 'Some work.' + }, + veille: { + titre: 'Around the web', + tagline: 'Some links that interested me.' + }, + erreur: { + introuvable: 'Sorry, page not found.', + autre: 'Oups… sorry about that.', + lienRetour: 'Back to the home page' + }, + seo: { + meta: { + description: + 'Web developer specialized in accessibility and eco-design in Toulouse, France. Development of custom websites, RGAA compliance, maintenance, etc.' + }, + article: { + title: 'Articles', + description: + 'A few articles about graphic design and front-end development.' + }, + code: { + title: 'Snippets', + description: 'Snippets of fresh, easy and accessible code.' + }, + references: { + title: 'Work', + description: 'A few case studies I worked on as a front-end developer.' + } + } + }, + fr: { + accueil: 'accueil', + tagline: 'Développeur web spécialisé en accessibilité.', + copyright: '(re)Fait avec Astro', + contact: { + title: 'contact', + email: 'Envoyez-moi un mail (ouverture du logiciel automatique).', + tel: 'Contactez-moi par téléphone (ouverture du logiciel automatique).' + }, + contenuVide: 'Bientôt ici : du contenu de qualité', + header: { + skipLink: 'Accéder au contenu', + mainNav: 'Menu principal', + homeLink: 'Accueil du site' + }, + sitemap: 'Plan du site', + prevNext: { + contenus: 'Contenus similaires', + precedent: 'Précédent', + suivant: 'Suivant' + }, + article: { + titre: 'articles', + tagline: 'Je blog, un peu.', + published: 'Publié le {datetime|date(options)}' + }, + meta: { + publication: 'Publié le', + modification: 'Mis à jour le', + credit: 'Image par' + }, + fragments: { + titre: 'fragments', + tagline: 'Les tutos de Nico mdr.' + }, + references: { + titre: 'références', + slug: 'references', + cta: 'Consulter le site', + tagline: 'Quelques références.' + }, + veille: { + titre: 'veille', + tagline: 'Des liens, en vrac.' + }, + erreur: { + introuvable: 'Page introuvable', + autre: 'Oups… désolé pour cette erreur.', + lienRetour: 'Retour à l’accueil' + }, + seo: { + meta: { + description: + 'Développeur web spécialisé en accessibilité numérique et éco-conception à Toulouse. Création de sites web sur mesure, mise en conformité RGAA, maintenance, etc.' + }, + article: { + title: 'Articles', + description: + "Quelques articles sur le développement web front-end et l'informatique à Toulouse." + }, + code: { + title: 'Fragments', + description: 'Fragments de codes stylés, faciles et accessibles.' + }, + references: { + title: 'Références', + description: + 'Quelques travaux réalisés en tant que et développeur web front-end à Toulouse.' + } + } + } +} as const diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 0fd0d5e..6ea25eb 100755 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -1,6 +1,5 @@ --- -import { astroI18n } from "astro-i18n"; -astroI18n.init(Astro); +const locale = Astro.currentLocale; import "../styles/style.css"; @@ -11,7 +10,7 @@ import Footer from "../components/Footer.astro"; const { pageTitle } = Astro.props; --- - +
      diff --git a/src/layouts/MarkdownPostLayout.astro b/src/layouts/MarkdownPostLayout.astro index eb46a29..8e747d9 100755 --- a/src/layouts/MarkdownPostLayout.astro +++ b/src/layouts/MarkdownPostLayout.astro @@ -1,33 +1,27 @@ --- -import { l, t, astroI18n } from "astro-i18n"; -// import AstroImage from "../components/AstroImage.astro"; -import BaseLayout from "../layouts/BaseLayout.astro"; +import BaseLayout from '../layouts/BaseLayout.astro' +import { getLangFromUrl, useTranslations } from '../utils/i18n' -const { frontmatter, image, title } = Astro.props; -const publishedDate = new Date(frontmatter.pubDate); -const localizedDate = new Intl.DateTimeFormat(astroI18n.langCode, { - dateStyle: "long", -}).format(publishedDate); +const locale = getLangFromUrl(Astro.url) +const t = useTranslations(locale) + +const { frontmatter, image, title } = Astro.props +const publishedDate = new Date(frontmatter.pubDate) +const localizedDate = new Intl.DateTimeFormat(locale, { + dateStyle: 'long' +}).format(publishedDate) ---

      - Publié le :

      -

      - { - t("article.published", { - datetime: frontmatter.pubDate, - options: { dateStyle: "long" }, - }) - } -

      -
      +
      { frontmatter.tags.map((tag) => ( -

      +

      {tag}

      )) diff --git a/src/pages/index.astro b/src/pages/index.astro index 7382c51..340c8b9 100755 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,8 +1,5 @@ --- -// init i18n -import { getLocale } from "astro-i18n-aut"; - -const locale = getLocale(Astro.url); +const locale = Astro.currentLocale; // import stuff import BaseLayout from "../layouts/BaseLayout.astro"; diff --git a/src/utils/i18n.ts b/src/utils/i18n.ts new file mode 100644 index 0000000..0b3fc69 --- /dev/null +++ b/src/utils/i18n.ts @@ -0,0 +1,28 @@ +import { defaultLang, ui } from '../i18n/ui' + +export function getLangFromUrl(url: URL) { + const [, lang] = url.pathname.split('/') + if (lang in ui) return lang as keyof typeof ui + return defaultLang +} + +type NestedKeyOf = { + [K in keyof T]: T[K] extends object + ? `${K & string}.${NestedKeyOf & string}` + : K & string +}[keyof T] + +export function useTranslations(lang: keyof typeof ui) { + return function t(key: NestedKeyOf<(typeof ui)[typeof defaultLang]>) { + const keys = key.split('.') + let value = ui[lang] + let fallback = ui[defaultLang] + + for (const k of keys) { + value = value?.[k] + fallback = fallback?.[k] + } + + return value || fallback + } +} diff --git a/tsconfig.json b/tsconfig.json index e71eb5a..fb16021 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,18 @@ { - "extends": "astro/tsconfigs/base", - "include": [".astro/types.d.ts", "**/*"], + "extends": "astro/tsconfigs/base", + "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"], - "compilerOptions": { - "strictNullChecks": true - } + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@components/*": ["src/components/*"], + "@layouts/*": ["src/layouts/*"] + }, + "strictNullChecks": true, + "plugins": [ + { + "name": "@astrojs/ts-plugin" + } + ] + } } -- 2.45.2 From b2b6887fdf98dcd506e253c8bc68c0f5364f2848 Mon Sep 17 00:00:00 2001 From: nico Date: Sun, 29 Dec 2024 12:33:22 +0100 Subject: [PATCH 03/16] v5 migration + remove i18n --- .astro/collections/HPsections.schema.json | 48 ++ .astro/collections/articles.schema.json | 61 +++ .astro/collections/fragments.schema.json | 61 +++ .astro/collections/references.schema.json | 61 +++ .astro/collections/veille.schema.json | 32 ++ .astro/content-assets.mjs | 1 + .astro/content-modules.mjs | 18 + .astro/content.d.ts | 206 ++++++++ .astro/data-store.json | 1 + .astro/settings.json | 5 + .astro/types.d.ts | 485 +----------------- .vscode/settings.json | 11 +- package.json | 53 +- src/components/AstroImage.astro | 28 +- src/components/CardEditorial.astro | 35 +- src/components/EditorialContent.astro | 27 +- src/components/Footer.astro | 28 +- src/components/Head.astro | 24 +- src/components/Header.astro | 14 +- src/components/LangSwitcher.astro | 13 - src/components/ListCards.astro | 8 +- src/components/ListTags.astro | 7 +- src/components/MetaDate.astro | 45 +- src/components/Navigation.astro | 39 +- src/components/QuickAccessCard.astro | 20 +- src/components/TOC.astro | 21 +- src/content.config.ts | 172 +++++-- src/content/articles/en/2022.md | 6 +- src/content/articles/en/2023.md | 8 +- .../articles/en/after-effects-expressions.mdx | 40 +- src/content/articles/en/faq.md | 6 +- src/content/articles/en/gratuiste.md | 6 +- src/content/articles/en/sci-hub-blocage.mdx | 58 +-- src/content/articles/en/the-day-I-jamd.mdx | 26 +- src/content/articles/en/video-compression.mdx | 42 +- src/content/articles/fr/2022.md | 6 +- src/content/articles/fr/2023.md | 8 +- .../articles/fr/after-effects-expressions.md | 6 +- src/content/articles/fr/faq.md | 6 +- src/content/articles/fr/gratuiste.md | 14 +- src/content/articles/fr/sci-hub-blocage.mdx | 56 +- src/content/articles/fr/the-day-I-jamd.mdx | 26 +- src/content/articles/fr/video-compression.md | 8 +- src/content/fragments/en/acme-sh-tls-cert.md | 6 +- src/content/fragments/en/array-vs-array.md | 34 +- src/content/fragments/en/buttons.md | 12 +- src/content/fragments/en/image-full.mdx | 8 +- .../fragments/en/nuxt-graphql-static.md | 16 +- src/content/fragments/en/super-cookies.mdx | 24 +- src/content/fragments/en/toulouse-fun.md | 6 +- src/content/fragments/en/visited-links.md | 6 +- src/content/fragments/fr/acme-sh-tls-cert.md | 6 +- src/content/fragments/fr/array-vs-array.md | 6 +- src/content/fragments/fr/buttons.mdx | 24 +- src/content/fragments/fr/image-full.mdx | 46 +- .../fragments/fr/nuxt-graphql-static.md | 20 +- src/content/fragments/fr/super-cookies.mdx | 24 +- src/content/fragments/fr/toulouse-fun.md | 6 +- src/content/fragments/fr/visited-links.md | 8 +- src/content/references/{fr => }/3w.md | 6 +- src/content/references/en/3w.md | 10 - src/content/references/en/natureo.md | 10 - .../references/en/parole-expression.md | 10 - src/content/references/en/rose-primaire.md | 10 - src/content/references/{fr => }/natureo.md | 6 +- .../references/{fr => }/parole-expression.md | 6 +- .../references/{fr => }/rose-primaire.md | 6 +- .../HP/{fr/01.1-offre.md => 011-offre.md} | 5 +- .../HP/{fr/01.2-offre.md => 012-offre.md} | 1 + .../HP/{fr/01.3-offre.md => 013-offre.md} | 1 + .../HP/{fr/02-methodo.md => 020-methodo.md} | 4 +- src/data/HP/{fr/03-about.md => 030-about.md} | 4 +- src/data/HP/en/01-offre.md | 29 -- src/data/HP/en/02-methodo.md | 29 -- src/data/HP/en/03-about.md | 28 - src/data/veille/{fr => }/2023.md | 4 +- src/data/veille/en/2023.md | 29 -- src/layouts/BaseLayout.astro | 18 +- src/layouts/MarkdownPostLayout.astro | 7 +- src/pages/articles/[id].astro | 28 +- src/pages/fragments/[id].astro | 26 +- src/pages/index.astro | 144 +++--- src/pages/plan-du-site.astro | 65 +-- src/pages/rss.xml.js | 28 +- 84 files changed, 1258 insertions(+), 1354 deletions(-) create mode 100644 .astro/collections/HPsections.schema.json create mode 100644 .astro/collections/articles.schema.json create mode 100644 .astro/collections/fragments.schema.json create mode 100644 .astro/collections/references.schema.json create mode 100644 .astro/collections/veille.schema.json create mode 100644 .astro/content-assets.mjs create mode 100644 .astro/content-modules.mjs create mode 100644 .astro/content.d.ts create mode 100644 .astro/data-store.json create mode 100644 .astro/settings.json delete mode 100755 src/components/LangSwitcher.astro rename src/content/references/{fr => }/3w.md (56%) delete mode 100755 src/content/references/en/3w.md delete mode 100755 src/content/references/en/natureo.md delete mode 100755 src/content/references/en/parole-expression.md delete mode 100755 src/content/references/en/rose-primaire.md rename src/content/references/{fr => }/natureo.md (55%) rename src/content/references/{fr => }/parole-expression.md (59%) rename src/content/references/{fr => }/rose-primaire.md (53%) rename src/data/HP/{fr/01.1-offre.md => 011-offre.md} (96%) rename src/data/HP/{fr/01.2-offre.md => 012-offre.md} (98%) rename src/data/HP/{fr/01.3-offre.md => 013-offre.md} (97%) rename src/data/HP/{fr/02-methodo.md => 020-methodo.md} (97%) rename src/data/HP/{fr/03-about.md => 030-about.md} (97%) delete mode 100755 src/data/HP/en/01-offre.md delete mode 100755 src/data/HP/en/02-methodo.md delete mode 100755 src/data/HP/en/03-about.md rename src/data/veille/{fr => }/2023.md (98%) delete mode 100755 src/data/veille/en/2023.md diff --git a/.astro/collections/HPsections.schema.json b/.astro/collections/HPsections.schema.json new file mode 100644 index 0000000..edfe8a9 --- /dev/null +++ b/.astro/collections/HPsections.schema.json @@ -0,0 +1,48 @@ +{ + "$ref": "#/definitions/HPsections", + "definitions": { + "HPsections": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "lang": { + "type": "string", + "enum": [ + "fr", + "en" + ] + }, + "uid": { + "type": "string" + }, + "image": { + "type": "string" + }, + "order": { + "type": "number" + }, + "quickTitle": { + "type": "string" + }, + "quickImage": { + "type": "string" + }, + "reference": { + "type": "string" + }, + "$schema": { + "type": "string" + } + }, + "required": [ + "type", + "lang", + "order" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/.astro/collections/articles.schema.json b/.astro/collections/articles.schema.json new file mode 100644 index 0000000..209c616 --- /dev/null +++ b/.astro/collections/articles.schema.json @@ -0,0 +1,61 @@ +{ + "$ref": "#/definitions/articles", + "definitions": { + "articles": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "lang": { + "type": "string", + "enum": [ + "fr", + "en" + ] + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "type": { + "type": "string" + }, + "permalink": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "code": { + "type": "boolean" + }, + "draft": { + "type": "boolean" + }, + "$schema": { + "type": "string" + } + }, + "required": [ + "title", + "subtitle", + "lang", + "tags", + "type", + "permalink", + "createdAt" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/.astro/collections/fragments.schema.json b/.astro/collections/fragments.schema.json new file mode 100644 index 0000000..49c36ba --- /dev/null +++ b/.astro/collections/fragments.schema.json @@ -0,0 +1,61 @@ +{ + "$ref": "#/definitions/fragments", + "definitions": { + "fragments": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "lang": { + "type": "string", + "enum": [ + "fr", + "en" + ] + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "type": { + "type": "string" + }, + "permalink": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "code": { + "type": "boolean" + }, + "draft": { + "type": "boolean" + }, + "$schema": { + "type": "string" + } + }, + "required": [ + "title", + "subtitle", + "lang", + "tags", + "type", + "permalink", + "createdAt" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/.astro/collections/references.schema.json b/.astro/collections/references.schema.json new file mode 100644 index 0000000..2d437fe --- /dev/null +++ b/.astro/collections/references.schema.json @@ -0,0 +1,61 @@ +{ + "$ref": "#/definitions/references", + "definitions": { + "references": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "url": { + "type": "string" + }, + "lang": { + "type": "string", + "enum": [ + "fr", + "en" + ] + }, + "permalink": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "code": { + "type": "boolean" + }, + "draft": { + "type": "boolean" + }, + "$schema": { + "type": "string" + } + }, + "required": [ + "title", + "subtitle", + "url", + "lang", + "permalink", + "tags", + "createdAt" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/.astro/collections/veille.schema.json b/.astro/collections/veille.schema.json new file mode 100644 index 0000000..20adb95 --- /dev/null +++ b/.astro/collections/veille.schema.json @@ -0,0 +1,32 @@ +{ + "$ref": "#/definitions/veille", + "definitions": { + "veille": { + "type": "object", + "properties": { + "lang": { + "type": "string", + "enum": [ + "fr", + "en" + ] + }, + "title": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "$schema": { + "type": "string" + } + }, + "required": [ + "lang", + "title" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/.astro/content-assets.mjs b/.astro/content-assets.mjs new file mode 100644 index 0000000..2b8b823 --- /dev/null +++ b/.astro/content-assets.mjs @@ -0,0 +1 @@ +export default new Map(); \ No newline at end of file diff --git a/.astro/content-modules.mjs b/.astro/content-modules.mjs new file mode 100644 index 0000000..c0284e8 --- /dev/null +++ b/.astro/content-modules.mjs @@ -0,0 +1,18 @@ + +export default new Map([ +["src/content/articles/en/after-effects-expressions.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fafter-effects-expressions.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/video-compression.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fvideo-compression.mdx&astroContentModuleFlag=true")], +["src/content/fragments/en/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fimage-full.mdx&astroContentModuleFlag=true")], +["src/content/fragments/en/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], +["src/content/fragments/fr/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fimage-full.mdx&astroContentModuleFlag=true")], +["src/content/fragments/fr/buttons.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fbuttons.mdx&astroContentModuleFlag=true")], +["src/content/articles/fr/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], +["src/content/fragments/fr/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], +["src/content/articles/fr/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/en-after-effects-expressions.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fen-after-effects-expressions.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/en-sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fen-sci-hub-blocage.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/en-the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fen-the-day-I-jamd.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/en-video-compression.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fen-video-compression.mdx&astroContentModuleFlag=true")]]); + \ No newline at end of file diff --git a/.astro/content.d.ts b/.astro/content.d.ts new file mode 100644 index 0000000..6ea9a82 --- /dev/null +++ b/.astro/content.d.ts @@ -0,0 +1,206 @@ +declare module 'astro:content' { + interface Render { + '.mdx': Promise<{ + Content: import('astro').MarkdownInstance<{}>['Content']; + headings: import('astro').MarkdownHeading[]; + remarkPluginFrontmatter: Record; + components: import('astro').MDXInstance<{}>['components']; + }>; + } +} + +declare module 'astro:content' { + export interface RenderResult { + Content: import('astro/runtime/server/index.js').AstroComponentFactory; + headings: import('astro').MarkdownHeading[]; + remarkPluginFrontmatter: Record; + } + interface Render { + '.md': Promise; + } + + export interface RenderedContent { + html: string; + metadata?: { + imagePaths: Array; + [key: string]: unknown; + }; + } +} + +declare module 'astro:content' { + type Flatten = T extends { [K: string]: infer U } ? U : never; + + export type CollectionKey = keyof AnyEntryMap; + export type CollectionEntry = Flatten; + + export type ContentCollectionKey = keyof ContentEntryMap; + export type DataCollectionKey = keyof DataEntryMap; + + type AllValuesOf = T extends any ? T[keyof T] : never; + type ValidContentEntrySlug = AllValuesOf< + ContentEntryMap[C] + >['slug']; + + /** @deprecated Use `getEntry` instead. */ + export function getEntryBySlug< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug | (string & {}), + >( + collection: C, + // Note that this has to accept a regular string too, for SSR + entrySlug: E, + ): E extends ValidContentEntrySlug + ? Promise> + : Promise | undefined>; + + /** @deprecated Use `getEntry` instead. */ + export function getDataEntryById( + collection: C, + entryId: E, + ): Promise>; + + export function getCollection>( + collection: C, + filter?: (entry: CollectionEntry) => entry is E, + ): Promise; + export function getCollection( + collection: C, + filter?: (entry: CollectionEntry) => unknown, + ): Promise[]>; + + export function getEntry< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug | (string & {}), + >(entry: { + collection: C; + slug: E; + }): E extends ValidContentEntrySlug + ? Promise> + : Promise | undefined>; + export function getEntry< + C extends keyof DataEntryMap, + E extends keyof DataEntryMap[C] | (string & {}), + >(entry: { + collection: C; + id: E; + }): E extends keyof DataEntryMap[C] + ? Promise + : Promise | undefined>; + export function getEntry< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug | (string & {}), + >( + collection: C, + slug: E, + ): E extends ValidContentEntrySlug + ? Promise> + : Promise | undefined>; + export function getEntry< + C extends keyof DataEntryMap, + E extends keyof DataEntryMap[C] | (string & {}), + >( + collection: C, + id: E, + ): E extends keyof DataEntryMap[C] + ? string extends keyof DataEntryMap[C] + ? Promise | undefined + : Promise + : Promise | undefined>; + + /** Resolve an array of entry references from the same collection */ + export function getEntries( + entries: { + collection: C; + slug: ValidContentEntrySlug; + }[], + ): Promise[]>; + export function getEntries( + entries: { + collection: C; + id: keyof DataEntryMap[C]; + }[], + ): Promise[]>; + + export function render( + entry: AnyEntryMap[C][string], + ): Promise; + + export function reference( + collection: C, + ): import('astro/zod').ZodEffects< + import('astro/zod').ZodString, + C extends keyof ContentEntryMap + ? { + collection: C; + slug: ValidContentEntrySlug; + } + : { + collection: C; + id: keyof DataEntryMap[C]; + } + >; + // Allow generic `string` to avoid excessive type errors in the config + // if `dev` is not running to update as you edit. + // Invalid collection names will be caught at build time. + export function reference( + collection: C, + ): import('astro/zod').ZodEffects; + + type ReturnTypeOrOriginal = T extends (...args: any[]) => infer R ? R : T; + type InferEntrySchema = import('astro/zod').infer< + ReturnTypeOrOriginal['schema']> + >; + + type ContentEntryMap = { + + }; + + type DataEntryMap = { + "HPsections": Record; + rendered?: RenderedContent; + filePath?: string; +}>; +"articles": Record; + rendered?: RenderedContent; + filePath?: string; +}>; +"fragments": Record; + rendered?: RenderedContent; + filePath?: string; +}>; +"references": Record; + rendered?: RenderedContent; + filePath?: string; +}>; +"veille": Record; + rendered?: RenderedContent; + filePath?: string; +}>; + + }; + + type AnyEntryMap = ContentEntryMap & DataEntryMap; + + export type ContentConfig = typeof import("../src/content.config.js"); +} diff --git a/.astro/data-store.json b/.astro/data-store.json new file mode 100644 index 0000000..98a5c76 --- /dev/null +++ b/.astro/data-store.json @@ -0,0 +1 @@ +[["Map",1,2,9,10,61,62,173,174,189,190,655,656],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.1.1","content-config-digest","8021b3469f132349","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"site\":\"https://www.nardu.in\",\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[\"assets.nardu.in\"],\"remotePatterns\":[{\"protocol\":\"https\"}]},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":\"shiki\",\"shikiConfig\":{\"langs\":[],\"langAlias\":{\"bash\":\"shellscript\",\"sh\":\"shellscript\",\"shell\":\"shellscript\",\"zsh\":\"shellscript\",\"js\":\"javascript\",\"ts\":\"typescript\",\"gql\":\"graphql\"},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"i18n\":{\"defaultLocale\":\"fr\",\"locales\":[\"fr\",\"en\"],\"routing\":{\"prefixDefaultLocale\":false,\"redirectToDefaultLocale\":true,\"fallbackType\":\"redirect\"}},\"security\":{\"checkOrigin\":true},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"responsiveImages\":false},\"legacy\":{\"collections\":false}}","references",["Map",11,12,25,26,39,40,50,51],"3w",{"id":11,"data":13,"filePath":21,"digest":22,"rendered":23},{"title":11,"subtitle":14,"url":15,"lang":16,"slug":11,"tags":17,"createdAt":20},"J'ai fait de la doc!","https://3-w.fr","fr",[18,19],"Front-end","documentation",["Date","2022-10-19T18:02:00.000Z"],"src/content/references/3w.md","0d3d94c8af754e1b",{"html":24},"","natureo",{"id":25,"data":27,"filePath":36,"digest":37,"rendered":38},{"title":28,"subtitle":29,"url":30,"lang":16,"slug":25,"tags":31,"createdAt":35},"Nature en Occitanie","La sobriété au naturel.","https://www.natureo.org/",[18,32,33,34],"accessibilité","éco-conception","CMS",["Date","2023-04-19T18:02:00.000Z"],"src/content/references/natureo.md","6a7169b855b57024",{"html":24},"parole-expression",{"id":39,"data":41,"filePath":47,"digest":48,"rendered":49},{"title":42,"subtitle":43,"url":44,"lang":16,"slug":39,"tags":45,"createdAt":46},"Parole Expression","Un nouveau site pour l'association.","https://www.paroleexpression.fr/",[18,33,34],["Date","2022-04-19T17:11:00.000Z"],"src/content/references/parole-expression.md","ec95a408f8c3e99c",{"html":24},"rose-primaire",{"id":50,"data":52,"filePath":58,"digest":59,"rendered":60},{"title":53,"subtitle":54,"url":55,"lang":16,"slug":50,"tags":56,"createdAt":57},"Rose Primaire","Une agence comme on l'aime.","https://roseprimaire.com/",[18,32,33,34],["Date","2023-04-19T17:11:00.000Z"],"src/content/references/rose-primaire.md","a0133200cf1bee58",{"html":24},"HPsections",["Map",63,64,85,86,102,103,128,129,145,146],"011-offre",{"id":63,"data":65,"body":72,"filePath":73,"digest":74,"rendered":75},{"type":66,"lang":16,"uid":67,"image":68,"order":69,"quickTitle":70,"quickImage":71,"reference":39},"section","offre","/assets/images/home/offre-1.1.svg",1.1,"Mes offres en freelance","/assets/images/home/icon-desktop.svg","## L'offre site web classique\n\nCette offre est destinée à un public souhaitant **se doter d'un site web**, sans forcément intégrer l'accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du [référentiel général d'amélioration de l'accessibilité](https://accessibilite.numerique.gouv.fr/) (\u003Cabbr>RGAA\u003C/abbr>).\n\nL'objectif principal de cette offre étant d'**établir une présence en ligne** pour le client. Que cette dernière ait un but informatif et/ou éditorial.\n\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->","src/data/HP/011-offre.md","290ecd1ed94a1087",{"html":76,"metadata":77},"\u003Ch2 id=\"loffre-site-web-classique\">L’offre site web classique\u003C/h2>\n\u003Cp>Cette offre est destinée à un public souhaitant \u003Cstrong>se doter d’un site web\u003C/strong>, sans forcément intégrer l’accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du \u003Ca href=\"https://accessibilite.numerique.gouv.fr/\">référentiel général d’amélioration de l’accessibilité\u003C/a> (\u003Cabbr>RGAA\u003C/abbr>).\u003C/p>\n\u003Cp>L’objectif principal de cette offre étant d’\u003Cstrong>établir une présence en ligne\u003C/strong> pour le client. Que cette dernière ait un but informatif et/ou éditorial.\u003C/p>\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->",{"headings":78,"imagePaths":83,"frontmatter":84},[79],{"depth":80,"slug":81,"text":82},2,"loffre-site-web-classique","L’offre site web classique",[],{"type":66,"uid":67,"lang":16,"image":68,"order":69,"quickTitle":70,"quickImage":71,"reference":39},"012-offre",{"id":85,"data":87,"body":90,"filePath":91,"digest":92,"rendered":93},{"type":66,"lang":16,"image":88,"order":89,"reference":50},"/assets/images/home/offre-1.2.svg",1.2,"## L'offre accessibilité avancée\n\nCette offre s'adresse plus spécifiquement aux entités pour lesquelles **l'accessibilité du site est un critère majeur.** Qu'il s'agisse d'une création ou d'une mise en conformité après un audit d'accessibilité.\n\nLorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\n\n- [Rose Primaire](https://roseprimaire.com/) pour le conseil et l'accompagnement du projet ;\n- [Sylvain Plantier](https://jedessinebien.com/) et/ou [Benoît Etchevery](http://ben-etche.com/) pour l'illustration et la direction artistique.\n\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->","src/data/HP/012-offre.md","2a3bf3411b3c171b",{"html":94,"metadata":95},"\u003Ch2 id=\"loffre-accessibilité-avancée\">L’offre accessibilité avancée\u003C/h2>\n\u003Cp>Cette offre s’adresse plus spécifiquement aux entités pour lesquelles \u003Cstrong>l’accessibilité du site est un critère majeur.\u003C/strong> Qu’il s’agisse d’une création ou d’une mise en conformité après un audit d’accessibilité.\u003C/p>\n\u003Cp>Lorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://roseprimaire.com/\">Rose Primaire\u003C/a> pour le conseil et l’accompagnement du projet ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://jedessinebien.com/\">Sylvain Plantier\u003C/a> et/ou \u003Ca href=\"http://ben-etche.com/\">Benoît Etchevery\u003C/a> pour l’illustration et la direction artistique.\u003C/li>\n\u003C/ul>\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->",{"headings":96,"imagePaths":100,"frontmatter":101},[97],{"depth":80,"slug":98,"text":99},"loffre-accessibilité-avancée","L’offre accessibilité avancée",[],{"type":66,"lang":16,"order":89,"image":88,"reference":50},"020-methodo",{"id":102,"data":104,"body":109,"filePath":110,"digest":111,"rendered":112},{"type":66,"lang":16,"uid":105,"image":106,"order":80,"quickTitle":107,"quickImage":108},"methodology","/assets/images/home/methodo.svg","Ma méthodologie","/assets/images/home/icon-methodo.svg","## Méthodologie\n\n### Accessibilité par défaut\n\nEngagé pour un web plus accessible, je crée des **sites web** en m'appuyant sur le [référentiel général d'amélioration de l'accessibilité (RGAA)](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) ainsi que sur les bonnes pratiques [Opquast.](https://www.opquast.com/rendre-le-web-meilleur/)\n\n### Sobriété par choix\n\nJe privilégie le développement de **sites statiques** en adoptant une approche [d'éco-conception numérique.](https://eco-conception.designersethiques.org/guide/fr/) \nC'est-à-dire que le site est pensé pour n'embarquer que les fonctionnalités nécessaires à son utilisation.\n\nCette approche présente de **nombreux avantages :**\n\n- chargement rapide des pages ;\n- sécurité renforcée ;\n- coûts serveur réduits ;\n- maintenance facilitée.\n\nLorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l'interface. Cela permet de garantir que **le site reste en ligne** même si le CMS venait à ne plus fonctionner.","src/data/HP/020-methodo.md","75a09b4e0b1e926b",{"html":113,"metadata":114},"\u003Ch2 id=\"méthodologie\">Méthodologie\u003C/h2>\n\u003Ch3 id=\"accessibilité-par-défaut\">Accessibilité par défaut\u003C/h3>\n\u003Cp>Engagé pour un web plus accessible, je crée des \u003Cstrong>sites web\u003C/strong> en m’appuyant sur le \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité (RGAA)\u003C/a> ainsi que sur les bonnes pratiques \u003Ca href=\"https://www.opquast.com/rendre-le-web-meilleur/\">Opquast.\u003C/a>\u003C/p>\n\u003Ch3 id=\"sobriété-par-choix\">Sobriété par choix\u003C/h3>\n\u003Cp>Je privilégie le développement de \u003Cstrong>sites statiques\u003C/strong> en adoptant une approche \u003Ca href=\"https://eco-conception.designersethiques.org/guide/fr/\">d’éco-conception numérique.\u003C/a>\u003Cbr>\nC’est-à-dire que le site est pensé pour n’embarquer que les fonctionnalités nécessaires à son utilisation.\u003C/p>\n\u003Cp>Cette approche présente de \u003Cstrong>nombreux avantages :\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>chargement rapide des pages ;\u003C/li>\n\u003Cli>sécurité renforcée ;\u003C/li>\n\u003Cli>coûts serveur réduits ;\u003C/li>\n\u003Cli>maintenance facilitée.\u003C/li>\n\u003C/ul>\n\u003Cp>Lorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l’interface. Cela permet de garantir que \u003Cstrong>le site reste en ligne\u003C/strong> même si le CMS venait à ne plus fonctionner.\u003C/p>",{"headings":115,"imagePaths":126,"frontmatter":127},[116,119,123],{"depth":80,"slug":117,"text":118},"méthodologie","Méthodologie",{"depth":120,"slug":121,"text":122},3,"accessibilité-par-défaut","Accessibilité par défaut",{"depth":120,"slug":124,"text":125},"sobriété-par-choix","Sobriété par choix",[],{"type":66,"uid":105,"lang":16,"image":106,"order":80,"quickTitle":107,"quickImage":108},"013-offre",{"id":128,"data":130,"body":133,"filePath":134,"digest":135,"rendered":136},{"type":66,"lang":16,"image":131,"order":132},"/assets/images/home/offre-1.3.svg",1.3,"## Et l'éco-conception alors ?\n\nJe ne conçois pas l'éco-conception comme une offre. C'est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l'éco-conception sans accessibilité, j'applique donc ces méthodologies quelque soit le projet !","src/data/HP/013-offre.md","03e37f364ac27cb4",{"html":137,"metadata":138},"\u003Ch2 id=\"et-léco-conception-alors\">Et l’éco-conception alors ?\u003C/h2>\n\u003Cp>Je ne conçois pas l’éco-conception comme une offre. C’est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l’éco-conception sans accessibilité, j’applique donc ces méthodologies quelque soit le projet !\u003C/p>",{"headings":139,"imagePaths":143,"frontmatter":144},[140],{"depth":80,"slug":141,"text":142},"et-léco-conception-alors","Et l’éco-conception alors ?",[],{"type":66,"lang":16,"order":132,"image":131},"030-about",{"id":145,"data":147,"body":152,"filePath":153,"digest":154,"rendered":155},{"type":66,"lang":16,"uid":148,"image":149,"order":120,"quickTitle":150,"quickImage":151},"about","/assets/images/home/about.svg","Moi","/assets/images/home/icon-heart.svg","## À propos\n\n### Formations personnelles\n\nAfin de solidifier mes compétences, j'ai suivi les formations et passé les certifications suivantes :\n\n- [Opquast](https://directory.opquast.com/fr/certificat/CTQSKP/) - Maîtrise de la qualité en projet web ;\n- Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\n\n### Formations des autres\n\nDepuis plusieurs années, j'interviens dans différents campus afin de dispenser des cours de développement web.\n\n### Temps libre\n\nJ’essaie de contribuer à des [projets open source](https://git.nardu.in/explore/repos) qui me tiennent à cœur et je m'engage localement avec le collectif [good-it!](https://www.good-it.org/)\n\nAh et j’écris [des articles](/articles) aussi ! Des articles sur le design, le développement web et l’informatique.","src/data/HP/030-about.md","a7abff6d744406ce",{"html":156,"metadata":157},"\u003Ch2 id=\"à-propos\">À propos\u003C/h2>\n\u003Ch3 id=\"formations-personnelles\">Formations personnelles\u003C/h3>\n\u003Cp>Afin de solidifier mes compétences, j’ai suivi les formations et passé les certifications suivantes :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://directory.opquast.com/fr/certificat/CTQSKP/\">Opquast\u003C/a> - Maîtrise de la qualité en projet web ;\u003C/li>\n\u003Cli>Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"formations-des-autres\">Formations des autres\u003C/h3>\n\u003Cp>Depuis plusieurs années, j’interviens dans différents campus afin de dispenser des cours de développement web.\u003C/p>\n\u003Ch3 id=\"temps-libre\">Temps libre\u003C/h3>\n\u003Cp>J’essaie de contribuer à des \u003Ca href=\"https://git.nardu.in/explore/repos\">projets open source\u003C/a> qui me tiennent à cœur et je m’engage localement avec le collectif \u003Ca href=\"https://www.good-it.org/\">good-it!\u003C/a>\u003C/p>\n\u003Cp>Ah et j’écris \u003Ca href=\"/articles\">des articles\u003C/a> aussi ! Des articles sur le design, le développement web et l’informatique.\u003C/p>",{"headings":158,"imagePaths":171,"frontmatter":172},[159,162,165,168],{"depth":80,"slug":160,"text":161},"à-propos","À propos",{"depth":120,"slug":163,"text":164},"formations-personnelles","Formations personnelles",{"depth":120,"slug":166,"text":167},"formations-des-autres","Formations des autres",{"depth":120,"slug":169,"text":170},"temps-libre","Temps libre",[],{"type":66,"uid":148,"lang":16,"image":149,"order":120,"quickTitle":150,"quickImage":151},"veille",["Map",175,176],"2023",{"id":175,"data":177,"body":179,"filePath":180,"digest":181,"rendered":182},{"lang":16,"title":175,"updatedAt":178},["Date","2023-04-20T17:12:06.000Z"],"- [mmm.page](https://build.mmm.page/) - Éditeur de sites web très simples, en glisser-déposer, pour n'importe quoi.\n- [Color.io](https://www.color.io/) - Éditeur photo en ligne.\n- [Addy's toolkit](https://toolkit.addy.codes/) - Outils et ressources pour les designers et développeurs sites web.\n- [L’accessibilité n’est pas une variable d’ajustement](https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/) — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n > L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\n- [3D en CSS (english)](https://garden.bradwoods.io/notes/css/3d) – Explications et exemples des propriétés 3D en CSS.\n- [Climat : Comment ne pas déprimer ?](https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html) – Podcast.\n- [Fable (english)](https://fable.app) – Application de motion design.\n- [Rive (english)](https://rive.app) – Application de motion design.\n- [Cake Desk](https://cakedesk.app/) – Application de facturation.\n- [Ombre fluide en CSS](https://shadows.brumm.af/) – Générateur.\n- [Smol CSS](https://smolcss.dev/) – Collection de fragments CSS.\n- [Ajustement optique](https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/) (english) – Aligner visuellement plutôt que techniquement.\n- [Datawrapper](https://blog.datawrapper.de/category/datavis-dos-and-donts/) (english) – Conseils pour montrer de la donnée.\n- [Assistivlabs](https://assistivlabs.com/) (english) – Service de test des technologies d'assistance (browserstack mais pour l'accessibilité).\n- [Les caractères fantaisistes et l'accessibilité](https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/) – Explications et exemples de l'enfer que sont les caractères Unicode pour les technologies d'assistance.\n- [Créer un champ `time` sur le web](https://adamsilver.io/blog/designing-a-time-input-backed-by-research/) (english) – Article.\n- [La cascade](https://la-cascade.io) – Collection d'articles sur le CSS.\n- [Tabby](https://tabby.sh) (english) – An alternative terminal app.\n- [Newglyph](https://newglyph.com/) – Fonderie indépendante.\n- [\u003Cspan lang=\"en\">Headless UI\u003C/span>](https://headlessui.com/vue/dialog) (english) – Librairie de composants vue et react.\n- [Vie privée sexy](https://privacy.sexy) (english) – Outils de confidentialité pour windows et macos.\n- [33 concepts JavaScript](https://github.com/leonardomso/33-js-concepts) (english) – Articles.\n- [Formbricks](https://formbricks.com/) (english) – Alternative open source à google form/typeform.\n- [Animations de chargement SVG](https://github.com/n3r4zzurr0/svg-spinners) – Collection.\n- [a11yphant](https://a11yphant.com/) (english) – Challenges de code pour apprendre l'accessibilité.\n- [CSS moderne](https://moderncss.dev/) (english) – Fragments CSS.\n- [Conteneur moderne en CSS](https://twitter.com/KevinJPowell/status/1501555193799925761) (english) – Tweet de Kevin Powell ❤️","src/data/veille/2023.md","1135beec386f207f",{"html":183,"metadata":184},"\u003Cul>\n\u003Cli>\u003Ca href=\"https://build.mmm.page/\">mmm.page\u003C/a> - Éditeur de sites web très simples, en glisser-déposer, pour n’importe quoi.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.color.io/\">Color.io\u003C/a> - Éditeur photo en ligne.\u003C/li>\n\u003Cli>\u003Ca href=\"https://toolkit.addy.codes/\">Addy’s toolkit\u003C/a> - Outils et ressources pour les designers et développeurs sites web.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/\">L’accessibilité n’est pas une variable d’ajustement\u003C/a> — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n\u003Cblockquote>\n\u003Cp>L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\u003C/p>\n\u003C/blockquote>\n\u003C/li>\n\u003Cli>\u003Ca href=\"https://garden.bradwoods.io/notes/css/3d\">3D en CSS (english)\u003C/a> – Explications et exemples des propriétés 3D en CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html\">Climat : Comment ne pas déprimer ?\u003C/a> – Podcast.\u003C/li>\n\u003Cli>\u003Ca href=\"https://fable.app\">Fable (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://rive.app\">Rive (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://cakedesk.app/\">Cake Desk\u003C/a> – Application de facturation.\u003C/li>\n\u003Cli>\u003Ca href=\"https://shadows.brumm.af/\">Ombre fluide en CSS\u003C/a> – Générateur.\u003C/li>\n\u003Cli>\u003Ca href=\"https://smolcss.dev/\">Smol CSS\u003C/a> – Collection de fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/\">Ajustement optique\u003C/a> (english) – Aligner visuellement plutôt que techniquement.\u003C/li>\n\u003Cli>\u003Ca href=\"https://blog.datawrapper.de/category/datavis-dos-and-donts/\">Datawrapper\u003C/a> (english) – Conseils pour montrer de la donnée.\u003C/li>\n\u003Cli>\u003Ca href=\"https://assistivlabs.com/\">Assistivlabs\u003C/a> (english) – Service de test des technologies d’assistance (browserstack mais pour l’accessibilité).\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/\">Les caractères fantaisistes et l’accessibilité\u003C/a> – Explications et exemples de l’enfer que sont les caractères Unicode pour les technologies d’assistance.\u003C/li>\n\u003Cli>\u003Ca href=\"https://adamsilver.io/blog/designing-a-time-input-backed-by-research/\">Créer un champ \u003Ccode>time\u003C/code> sur le web\u003C/a> (english) – Article.\u003C/li>\n\u003Cli>\u003Ca href=\"https://la-cascade.io\">La cascade\u003C/a> – Collection d’articles sur le CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://tabby.sh\">Tabby\u003C/a> (english) – An alternative terminal app.\u003C/li>\n\u003Cli>\u003Ca href=\"https://newglyph.com/\">Newglyph\u003C/a> – Fonderie indépendante.\u003C/li>\n\u003Cli>\u003Ca href=\"https://headlessui.com/vue/dialog\">\u003Cspan lang=\"en\">Headless UI\u003C/span>\u003C/a> (english) – Librairie de composants vue et react.\u003C/li>\n\u003Cli>\u003Ca href=\"https://privacy.sexy\">Vie privée sexy\u003C/a> (english) – Outils de confidentialité pour windows et macos.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/leonardomso/33-js-concepts\">33 concepts JavaScript\u003C/a> (english) – Articles.\u003C/li>\n\u003Cli>\u003Ca href=\"https://formbricks.com/\">Formbricks\u003C/a> (english) – Alternative open source à google form/typeform.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/n3r4zzurr0/svg-spinners\">Animations de chargement SVG\u003C/a> – Collection.\u003C/li>\n\u003Cli>\u003Ca href=\"https://a11yphant.com/\">a11yphant\u003C/a> (english) – Challenges de code pour apprendre l’accessibilité.\u003C/li>\n\u003Cli>\u003Ca href=\"https://moderncss.dev/\">CSS moderne\u003C/a> (english) – Fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/KevinJPowell/status/1501555193799925761\">Conteneur moderne en CSS\u003C/a> (english) – Tweet de Kevin Powell ❤️\u003C/li>\n\u003C/ul>",{"headings":185,"imagePaths":186,"frontmatter":187},[],[],{"lang":16,"title":175,"updatedAt":188},"2023-04-20T17:12:06.000Z","fragments",["Map",191,192,256,257,275,276,286,287,297,298,339,340,350,351,366,367,404,405,467,468,491,492,525,526,536,537,576,577,587,588,640,641],"acme-sh-tls-cert",{"id":191,"data":193,"body":199,"filePath":200,"digest":201,"rendered":202},{"title":194,"subtitle":195,"lang":16,"tags":196,"type":189,"slug":191,"createdAt":198},"Certificates TLS robustes avec acme.sh","384-bit de https",[197],"sécurité",["Date","2022-06-08T14:24:06.000Z"],"## Attention\n\nJe ne suis pas du tout un expert en sécurité. J'aime juste les trucs nouveaux et stylés des internets. \nC'est pourquoi j'ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J'ai maintenant un joli 100/100 sur [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nVous pouvez en apprendre (beaucoup) plus [ici](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) et sur les liens cités (en anglais).\n\n## Prérequis\n\n### Installer acme.sh\n\nPour des raisons de simplicité et d'automatisation, j'utilise [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changer l'authorité par défaut\n\nPar défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let's Encrypt car, d'après acme.sh, ils sont les seuls à proposer des certificats ECC.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Utiliser l'api DNS\n\nSi vous en avez la possibilité, la façon la plus simple de générer un certificat est via l'api de votre fournisseur DNS. acme.sh supporte [énormément](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) de fournisseurs DNS.\n\n### Definir la clé api\n\nSuivez la [documentation](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) pour votre fournisseur DNS, généralement:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Émettre le certificat\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Utiliser le mode standalone\n\nSi vous n'avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s'occupe de toutes les vérifications.\n\nLe port `80` doit être disponible.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Exemples\n\n### Multi domaines standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domaine DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Étapes supplémentaires\n\nLe certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\n\n### Version TLS\n\nLimiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu [la différence de compatibilité de 5%](https://caniuse.com/?search=tls%201.) avec 1.2).\n\n### HSTS\n\nUtiliser le header [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/).\n\n```\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Suite cryptographique\n\nUtiliser une suite cryptographique récente et robuste. C'est ici que mes connaissances deviennent limitées… J'ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\n\nJ'avais basé ma première suite sur [cette liste](https://tls.imirhil.fr/ciphers), en la comparant avec celle de la compatibilité (d'anciens ?) [navigateurs](https://tls.imirhil.fr/suite).\n\nJ'ai ensuite demandé à [Aeris](https://twitter.com/aeris22), le créateur de [tls.imirhil.fr](https://tls.imirhil.fr), ses conseils sur cette suite. Il m'a recommandé d'utiliser :\n\n```\nECDHE+AES:ECDHE+CHACHA20\n```\n\nAfin d'atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\n\n```\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/fr/acme-sh-tls-cert.md","82e6d91747c28ea5",{"html":203,"metadata":204},"\u003Ch2 id=\"attention\">Attention\u003C/h2>\n\u003Cp>Je ne suis pas du tout un expert en sécurité. J’aime juste les trucs nouveaux et stylés des internets.\u003Cbr>\nC’est pourquoi j’ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J’ai maintenant un joli 100/100 sur \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>Vous pouvez en apprendre (beaucoup) plus \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">ici\u003C/a> et sur les liens cités (en anglais).\u003C/p>\n\u003Ch2 id=\"prérequis\">Prérequis\u003C/h2>\n\u003Ch3 id=\"installer-acmesh\">Installer acme.sh\u003C/h3>\n\u003Cp>Pour des raisons de simplicité et d’automatisation, j’utilise \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">curl\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> https://get.acme.sh\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#B392F0\"> sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -s\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> email=mail@domain.tld\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"changer-lauthorité-par-défaut\">Changer l’authorité par défaut\u003C/h3>\n\u003Cp>Par défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let’s Encrypt car, d’après acme.sh, ils sont les seuls à proposer des certificats ECC.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --set-default-ca\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --server\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> letsencrypt\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"utiliser-lapi-dns\">Utiliser l’api DNS\u003C/h2>\n\u003Cp>Si vous en avez la possibilité, la façon la plus simple de générer un certificat est via l’api de votre fournisseur DNS. acme.sh supporte \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">énormément\u003C/a> de fournisseurs DNS.\u003C/p>\n\u003Ch3 id=\"definir-la-clé-api\">Definir la clé api\u003C/h3>\n\u003Cp>Suivez la \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">documentation\u003C/a> pour votre fournisseur DNS, généralement:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">export\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> PROVIDER_Key\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"YOUR_API_KEY\"\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"émettre-le-certificat\">Émettre le certificat\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"utiliser-le-mode-standalone\">Utiliser le mode standalone\u003C/h2>\n\u003Cp>Si vous n’avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s’occupe de toutes les vérifications.\u003C/p>\n\u003Cp>Le port \u003Ccode>80\u003C/code> doit être disponible.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"exemples\">Exemples\u003C/h2>\n\u003Ch3 id=\"multi-domaines-standalone\">Multi domaines standalone\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> www.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> subdomain.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"wildcard-domaine-dns\">Wildcard domaine DNS\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '*.domain.tld'\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"étapes-supplémentaires\">Étapes supplémentaires\u003C/h2>\n\u003Cp>Le certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\u003C/p>\n\u003Ch3 id=\"version-tls\">Version TLS\u003C/h3>\n\u003Cp>Limiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu \u003Ca href=\"https://caniuse.com/?search=tls%201.\">la différence de compatibilité de 5%\u003C/a> avec 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Utiliser le header \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a>.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>Strict-Transport-Security: max-age=31536000; includeSubDomains\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"suite-cryptographique\">Suite cryptographique\u003C/h3>\n\u003Cp>Utiliser une suite cryptographique récente et robuste. C’est ici que mes connaissances deviennent limitées… J’ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\u003C/p>\n\u003Cp>J’avais basé ma première suite sur \u003Ca href=\"https://tls.imirhil.fr/ciphers\">cette liste\u003C/a>, en la comparant avec celle de la compatibilité (d’anciens ?) \u003Ca href=\"https://tls.imirhil.fr/suite\">navigateurs\u003C/a>.\u003C/p>\n\u003Cp>J’ai ensuite demandé à \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, le créateur de \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, ses conseils sur cette suite. Il m’a recommandé d’utiliser :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Afin d’atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES256:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":205,"imagePaths":251,"frontmatter":252},[206,209,212,215,218,221,224,227,230,233,236,239,242,245,248],{"depth":80,"slug":207,"text":208},"attention","Attention",{"depth":80,"slug":210,"text":211},"prérequis","Prérequis",{"depth":120,"slug":213,"text":214},"installer-acmesh","Installer acme.sh",{"depth":120,"slug":216,"text":217},"changer-lauthorité-par-défaut","Changer l’authorité par défaut",{"depth":80,"slug":219,"text":220},"utiliser-lapi-dns","Utiliser l’api DNS",{"depth":120,"slug":222,"text":223},"definir-la-clé-api","Definir la clé api",{"depth":120,"slug":225,"text":226},"émettre-le-certificat","Émettre le certificat",{"depth":80,"slug":228,"text":229},"utiliser-le-mode-standalone","Utiliser le mode standalone",{"depth":80,"slug":231,"text":232},"exemples","Exemples",{"depth":120,"slug":234,"text":235},"multi-domaines-standalone","Multi domaines standalone",{"depth":120,"slug":237,"text":238},"wildcard-domaine-dns","Wildcard domaine DNS",{"depth":80,"slug":240,"text":241},"étapes-supplémentaires","Étapes supplémentaires",{"depth":120,"slug":243,"text":244},"version-tls","Version TLS",{"depth":120,"slug":246,"text":247},"hsts","HSTS",{"depth":120,"slug":249,"text":250},"suite-cryptographique","Suite cryptographique",[],{"title":194,"subtitle":195,"lang":16,"slug":191,"createdAt":253,"excerpt":254,"tags":255,"type":189},"2022-06-08T14:24:06.000Z","La sécurité avec des courbes.",[197],"array-vs-array",{"id":256,"data":258,"body":265,"filePath":266,"digest":267,"rendered":268},{"title":259,"subtitle":260,"lang":16,"tags":261,"type":189,"slug":256,"createdAt":263,"draft":264},"Filtrer un array avec un autre array","En cours de traduction.",[262],"nuxt.js",["Date","2022-06-08T14:24:06.000Z"],true,"[Voir les fragments disponibles](/fragments)","src/content/fragments/fr/array-vs-array.md","7321d444177c3841",{"html":269,"metadata":270},"\u003Cp>\u003Ca href=\"/fragments\">Voir les fragments disponibles\u003C/a>\u003C/p>",{"headings":271,"imagePaths":272,"frontmatter":273},[],[],{"title":259,"subtitle":260,"lang":16,"draft":264,"slug":256,"createdAt":253,"excerpt":260,"tags":274,"type":189},[262],"buttons",{"id":275,"data":277,"body":283,"filePath":284,"digest":285,"deferredRender":264},{"title":278,"subtitle":279,"lang":16,"tags":280,"type":189,"slug":275,"createdAt":282,"code":264,"draft":264},"Effets de survol de boutons","Simples mais efficaces.",[281],"CSS",["Date","2020-10-08T09:00:00.000Z"],"## Styles généraux\n\nTous les boutons présents utilisent ces styles comme base en guise de « reset » :\n\n> N'oubliez pas de préfixer si besoin !\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Ajout d'icône\n\n\u003Cbutton role='none' class='btn btn-icon'>\n\t\u003Cspan>Icône\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('./assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double volet\n\n\u003Cbutton role='none' class='btn btn-rideau'>\n\t\u003Cspan>Volet\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Dégradé animé\n\n\u003Cbutton role='none' class='btn btn-gradient'>\n\t\u003Cspan>Dégradé\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Échelle non desctructrice\n\n\u003Cbutton role='none' class='btn btn-scale'>\n\t\u003Cspan>Échelle\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/fr/buttons.mdx","f5d7b03520f96b04","image-full",{"id":286,"data":288,"body":294,"filePath":295,"digest":296,"deferredRender":264},{"title":289,"subtitle":290,"lang":16,"tags":291,"type":189,"slug":286,"createdAt":292,"updatedAt":293},"Image pleine largeur","Casser le conteneur.",[281],["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Image inline\n\nOn est parfois obligé d'utiliser des images dans des balises `img` plutôt que dans un `background` en css. Comment faire alors pour que l'image sorte de son conteneur pour en faire une bannière ? Exemple pratique à partir de ce même site.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_container_9e3939b3ae.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Contexte\n\nConsidérons le html suivant :\n\n```html\n\u003Csection class=\"container\">\n\t\u003Cdiv class=\"hero\">\n\t\t\u003Cimg class=\"hero__image\" src=\"hero.img\" />\n\t\u003C/div>\n\u003C/section>\n```\n\nEt le style suivant :\n\n```css\n.container {\n\tpadding: 0 14px;\n\tmargin-left: auto;\n\tmargin-right: auto;\n\tmax-width: 1040px;\n}\nimg {\n\tmax-width: 100%;\n\theight: auto;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_original_d49f0d11bf.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Déborder du conteneur\n\nAfin de faire prendre à l'image toute la largeur, on agit sur son conteneur :\n\n```css\n.hero {\n\tmargin-left: calc(50% - 50vw);\n\tposition: relative;\n\twidth: 100vw;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_full_2a902f9539.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Faire une bannière\n\nOn peut alors réduire la hauteur du conteneur pour obtenir une bannière plutôt que l'image entière et faire correspondre la hauteur de l'image à la hauteur du conteneur :\n\n```css\n.hero {\n\theight: 200px;\n}\n.hero__image {\n\theight: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_height_81b4ce969a.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nIl faut ensuite forcer l'image à prendre toute la largeur du conteneur :\n\n```css\n.hero__image {\n\twidth: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_deformed_479046d2cb.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nPas top…\n\n### J'ai cassé l'image…\n\n**ENFIN** le code magique pour redonner son ratio à l'image sans la déformer :\n\n```css\n.hero__image {\n\tobject-fit: cover;\n\tobject-position: center; /* à positionner comme on veut */\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_6c164e82b3.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nCette technique s'apparente à l'utilisation d'une image de background mais en dur 😁\n\n## TL;DR\n\nLe code complet :\n\n```css\n.hero {\n\tmargin-left: calc(50% - 50vw);\n\tposition: relative;\n\twidth: 100vw;\n\theight: 200px;\n}\n.hero__image {\n\twidth: 100%;\n\theight: 100%;\n\t-o-object-fit: cover;\n\tobject-fit: cover;\n\t-o-object-position: center;\n\tobject-position: center;\n}\n```","src/content/fragments/fr/image-full.mdx","91ebd97eef5cb8a4","nuxt-graphql-static",{"id":297,"data":299,"body":305,"filePath":306,"digest":307,"rendered":308},{"title":300,"subtitle":301,"lang":16,"tags":302,"type":189,"slug":297,"createdAt":303,"updatedAt":304},"Site statique et requêtes GraphQL avec Nuxt.js","Le client graphql est roi.",[262],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## Le problème\n\nJe me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (nouvel onglet)').\nAprès quelques recherches, voici [le bug constaté par quelqu'un d'autre](https://github.com/nuxt-community/apollo-module/issues/339 'Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)') sur github.\n\nIl semblerait que le module en l'état ne gère pas correctement la génération statique avec `nuxt generate`.\n\nJe trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les `\u003Cnuxt-link>` ne fonctionnait pas.\n\n## La solution 🙌\n\nHeureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\n\n[Nuxt graphql request à la rescousse !](https://github.com/gomah/nuxt-graphql-request 'Dépôt github du module (nouvel onglet)')\n\n### La conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### La requête\n\nLa meilleure méthode à ce jour est d'utiliser `asyncData` dans les pages et `fetch` dans les composants. Utiliser `fetch` dans les pages ne fonctionne pas bien du tout avec `nuxt generate`.\n\nJ'installe également le paquet `graphql-tag` (uniquement en `devDependencies`) afin de pouvoir importer directement des fichiers `.gql`\n\nExemple de fichier :\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Dans une page\n\n```javascript\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n async asyncData({ $graphql }) {\n const data = await $graphql.default.request(homepageQuery)\n return { data }\n },\n}\n\u003C/script>\n```\n\n#### Dans un composant\n\nIl est plus prudent d'attendre que `fetch` ait reçu une réponse avant d'afficher quoi que ce soit. On peut utiliser `$fetchState` afin d'être tranquille ([documentation](https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation sur la méthode fetch (nouvel onglet)')).\n\n```javascript\n// Header.vue\n\u003Ctemplate>\n \u003Cheader v-if=\"!$fetchState.pending\">\n …\n \u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n data() {\n return {\n data: {},\n }\n },\n async fetch() {\n try {\n const data = await this.$graphql.default.request(headerQuery)\n this.data = data\n } catch (error) {\n console.error(JSON.stringify(error, undefined, 2))\n }\n },\n}\n\u003C/script>\n```\n\n### Les options\n\nPour passer des options à la requête, par exemple pour une version multilingue avec [nuxt/i18n](https://i18n.nuxtjs.org/ 'Documentation de nuxt i18n (nouvel onglet)') et/ou un paramètre d'url dans le cadre d'une page dynamique :\n\n```javascript\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n async asyncData({ $graphql, app, params }) {\n const locale = app.i18n.localeProperties.iso\n const data = await $graphql.default.request(articleQuery, {\n code: locale,\n slug: params.slug,\n })\n return { data }\n },\n}\n\u003C/script>\n```","src/content/fragments/fr/nuxt-graphql-static.md","73b6cc6b4fed04f5",{"html":309,"metadata":310},"\u003Ch2 id=\"le-problème\">Le problème\u003C/h2>\n\u003Cp>Je me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (nouvel onglet)\">nuxt apollo\u003C/a>.\nAprès quelques recherches, voici \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)\">le bug constaté par quelqu’un d’autre\u003C/a> sur github.\u003C/p>\n\u003Cp>Il semblerait que le module en l’état ne gère pas correctement la génération statique avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>Je trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les \u003Ccode><nuxt-link>\u003C/code> ne fonctionnait pas.\u003C/p>\n\u003Ch2 id=\"la-solution\">La solution 🙌\u003C/h2>\n\u003Cp>Heureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\" title=\"Dépôt github du module (nouvel onglet)\">Nuxt graphql request à la rescousse !\u003C/a>\u003C/p>\n\u003Ch3 id=\"la-conf\">La conf\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// nuxt.config.js\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">buildModules\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\"> 'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">graphql\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> clients\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> default\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> endpoint: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> options: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> headers: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> authorization: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">},\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"la-requête\">La requête\u003C/h3>\n\u003Cp>La meilleure méthode à ce jour est d’utiliser \u003Ccode>asyncData\u003C/code> dans les pages et \u003Ccode>fetch\u003C/code> dans les composants. Utiliser \u003Ccode>fetch\u003C/code> dans les pages ne fonctionne pas bien du tout avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>J’installe également le paquet \u003Ccode>graphql-tag\u003C/code> (uniquement en \u003Ccode>devDependencies\u003C/code>) afin de pouvoir importer directement des fichiers \u003Ccode>.gql\u003C/code>\u003C/p>\n\u003Cp>Exemple de fichier :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"graphql\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># homepage.gql\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">query\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\thomepage\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\ttitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\tsubtitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\thero\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\tid\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\talt\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"dans-une-page\">Dans une page\u003C/h4>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import homepageQuery from '~/graphql/queries/singles/homepage'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(homepageQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"dans-un-composant\">Dans un composant\u003C/h4>\n\u003Cp>Il est plus prudent d’attendre que \u003Ccode>fetch\u003C/code> ait reçu une réponse avant d’afficher quoi que ce soit. On peut utiliser \u003Ccode>$fetchState\u003C/code> afin d’être tranquille (\u003Ca href=\"https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation sur la méthode fetch (nouvel onglet)\">documentation\u003C/a>).\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// Header.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> <\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#B392F0\"> v-if\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"!$fetchState.pending\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> …\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> </\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import headerQuery from '~/graphql/queries/singles/header'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">fetch\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> try {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> data\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.$graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(headerQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> data\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> } catch (error) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> console.\u003C/span>\u003Cspan style=\"color:#B392F0\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(JSON.stringify(\u003C/span>\u003Cspan style=\"color:#FFAB70\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">undefined\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, 2))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"les-options\">Les options\u003C/h3>\n\u003Cp>Pour passer des options à la requête, par exemple pour une version multilingue avec \u003Ca href=\"https://i18n.nuxtjs.org/\" title=\"Documentation de nuxt i18n (nouvel onglet)\">nuxt/i18n\u003C/a> et/ou un paramètre d’url dans le cadre d’une page dynamique :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// _slug.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import articleQuery from '~/graphql/queries/articles'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql, app, params }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const locale \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> app.i18n.localeProperties.iso\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(articleQuery, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> code: locale,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> slug: params.slug,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> })\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":311,"imagePaths":334,"frontmatter":335},[312,315,318,321,324,328,331],{"depth":80,"slug":313,"text":314},"le-problème","Le problème",{"depth":80,"slug":316,"text":317},"la-solution","La solution 🙌",{"depth":120,"slug":319,"text":320},"la-conf","La conf",{"depth":120,"slug":322,"text":323},"la-requête","La requête",{"depth":325,"slug":326,"text":327},4,"dans-une-page","Dans une page",{"depth":325,"slug":329,"text":330},"dans-un-composant","Dans un composant",{"depth":120,"slug":332,"text":333},"les-options","Les options",[],{"title":300,"subtitle":301,"lang":16,"slug":297,"createdAt":253,"updatedAt":336,"excerpt":337,"tags":338,"type":189},"2022-09-08T13:43:33.000Z","Quand le module gql le plus utilisé ne fonctionne pas…",[262],"super-cookies",{"id":339,"data":341,"body":347,"filePath":348,"digest":349,"deferredRender":264},{"title":342,"subtitle":343,"lang":16,"tags":344,"type":189,"slug":339,"createdAt":346},"Les meilleurs cookies","Des gâteaux sans consentement.",[345],"cuisine",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Version végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 3/4 de l'aquafaba de 400g de pois chiche (l'eau des pois chiche)\n- 125 grammes d'huile de noix de coco\n- 2 cuillères à café de sirop d'érable\n- 1 plaquette de chocolat (noir) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre si besoin l'huile de noix de coco à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (huile, aquafaba, sirop d'érable)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Version non végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 1 œuf\n- 125 grammes de beurre fondu\n- 2 cuillères à café de miel\n- 1 plaquette de chocolat (noir/blanc/les deux) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre le beurre à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (beurre fondu, œuf, miel)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Notes\n\nLe chocolat peut-être remplacé par n'importe quoi comme des noix, des raisins secs, des légos… (mangez pas des légos soyez sérieux).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Tous les ingrédients mélangés forment une pâte marron.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Les cookies cuits sont bombés et très moelleux.'\n/>","src/content/fragments/fr/super-cookies.mdx","f7a802e0b68cb04a","toulouse-fun",{"id":350,"data":352,"body":265,"filePath":357,"digest":358,"rendered":359},{"title":353,"subtitle":260,"lang":16,"tags":354,"type":189,"slug":350,"createdAt":356,"draft":264},"Toulouse yourself",[355],"lifestyle",["Date","2022-06-22T15:34:45.000Z"],"src/content/fragments/fr/toulouse-fun.md","a0c25b438b34c05e",{"html":269,"metadata":360},{"headings":361,"imagePaths":362,"frontmatter":363},[],[],{"title":353,"subtitle":260,"lang":16,"draft":264,"slug":350,"createdAt":364,"excerpt":260,"tags":365,"type":189},"2022-06-22T15:34:45.000Z",[355],"visited-links",{"id":366,"data":368,"body":375,"filePath":376,"digest":377,"rendered":378},{"title":369,"subtitle":370,"lang":16,"tags":371,"type":372,"slug":366,"createdAt":373,"draft":374},"Liens visités et indication visuelle","Comment différencier les liens déjà cliqués",[18],"snippets",["Date","2023-06-06T18:34:00.000Z"],false,"## La théorie\n\nIl est possible sur le web d'appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu'un lien visité est violet.\n\nGénéralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L'information qu'un lien a déjà été visité ne semble pas indispensable à la navigation. C'est sûrement vrai, mais personnellement, je suis assez content d'avoir un rappel des pages que j'ai déjà consultées lorsque je navigue.\n\nUne information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J'ai alors cherché un moyen d'ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n'est certainement pas idéale, elle se rapproche plus d'une expérience, à priori inoffensive pour l'internaute.\n\n## La spécification\n\nQuand je me suis intéressé à ce qu'il était possible de faire avec les liens déjà visités, j'ai découvert qu'extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu'il était possible de récupérer l'historique de navigation d'un utilisateur grâce aux styles des liens visités. Le sélecteur `:visited` a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. [Plus d'informations dans cet article.](https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector)\n\n## La pratique\n\nQue faire alors, en terme de style, quand on ne peut changer que des couleurs ?\n\nD'après MDN, les propriétés suivantes sont modifiables :\n\n- `color`\n- `background-color`\n- `border-color` (et les propriétés détaillées associées),\n- `column-rule-color`\n- `outline-color`\n- `text-decoration-color`\n- `text-emphasis-color`\n- Les composantes de couleur liées aux attributs SVG `fill` et `stroke`.\n\nChanger la couleur d'un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\n\nEn revanche, il est possible de \" masquer \" un élément en modifiant sa couleur pour qu'elle corresponde à la couleur du fond de la page ou de l'élément parent. On pourrait ainsi imaginer masquer une `border` ou un `outline`.\n\nJ'ai personnellement choisi de faire différemment. J'ai décidé d'utiliser un pseudo-élément `::before` sur l'état non visité du lien puis de le masquer quand celui-ci devient visité.\n\n### Le code\n\n```css\na {\n\tposition: relative;\n\ttext-decoration: none;\n}\na::before {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 0;\n\tinline-size: 2px;\n\tblock-size: 2px;\n\tborder-radius: 4px;\n\ttransform: translate(-6px, 0);\n\tbackground-color: grey;\n}\na:visited::before {\n\tbackground-color: white;\n}\n```\n\nCes règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\n\n### Accessibilité\n\nOn pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété `content` mais les lecteurs d'écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d'écrans annoncent déjà si un lien est visité avant de lire son intitulé.\n\n## Aller plus loin\n\nAfin de pousser l'expérience un peu plus loin, j'ai tenté d'utiliser des éléments plus explicites pour signifier l'état visité du lien. Bien qu'encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\n\nL'idée est d'avoir un `::before` et un `::after`, chacun contenant une icône en base 64 blanche en tant qu'image de fond. Quand le lien est non visité, le `::before` contient un fond coloré qui fait apparaître l'icône. Quand le lien passe en visité, le fond du `::before` devient blanc et celui du `::after` devient coloré, ce qui masque la première icône et affiche la deuxième.\n\nIl est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l'une sur l'autre.\n\n[Voir la démo sur codepen.](https://codepen.io/narduin/pen/VwVwmrO)","src/content/fragments/fr/visited-links.md","52385f4f8bc864b2",{"html":379,"metadata":380},"\u003Ch2 id=\"la-théorie\">La théorie\u003C/h2>\n\u003Cp>Il est possible sur le web d’appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu’un lien visité est violet.\u003C/p>\n\u003Cp>Généralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L’information qu’un lien a déjà été visité ne semble pas indispensable à la navigation. C’est sûrement vrai, mais personnellement, je suis assez content d’avoir un rappel des pages que j’ai déjà consultées lorsque je navigue.\u003C/p>\n\u003Cp>Une information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J’ai alors cherché un moyen d’ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n’est certainement pas idéale, elle se rapproche plus d’une expérience, à priori inoffensive pour l’internaute.\u003C/p>\n\u003Ch2 id=\"la-spécification\">La spécification\u003C/h2>\n\u003Cp>Quand je me suis intéressé à ce qu’il était possible de faire avec les liens déjà visités, j’ai découvert qu’extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu’il était possible de récupérer l’historique de navigation d’un utilisateur grâce aux styles des liens visités. Le sélecteur \u003Ccode>:visited\u003C/code> a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector\">Plus d’informations dans cet article.\u003C/a>\u003C/p>\n\u003Ch2 id=\"la-pratique\">La pratique\u003C/h2>\n\u003Cp>Que faire alors, en terme de style, quand on ne peut changer que des couleurs ?\u003C/p>\n\u003Cp>D’après MDN, les propriétés suivantes sont modifiables :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>background-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>border-color\u003C/code> (et les propriétés détaillées associées),\u003C/li>\n\u003Cli>\u003Ccode>column-rule-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>outline-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-decoration-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-emphasis-color\u003C/code>\u003C/li>\n\u003Cli>Les composantes de couleur liées aux attributs SVG \u003Ccode>fill\u003C/code> et \u003Ccode>stroke\u003C/code>.\u003C/li>\n\u003C/ul>\n\u003Cp>Changer la couleur d’un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\u003C/p>\n\u003Cp>En revanche, il est possible de ” masquer ” un élément en modifiant sa couleur pour qu’elle corresponde à la couleur du fond de la page ou de l’élément parent. On pourrait ainsi imaginer masquer une \u003Ccode>border\u003C/code> ou un \u003Ccode>outline\u003C/code>.\u003C/p>\n\u003Cp>J’ai personnellement choisi de faire différemment. J’ai décidé d’utiliser un pseudo-élément \u003Ccode>::before\u003C/code> sur l’état non visité du lien puis de le masquer quand celui-ci devient visité.\u003C/p>\n\u003Ch3 id=\"le-code\">Le code\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">a\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">relative\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttext-decoration\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">a\u003C/span>\u003Cspan style=\"color:#B392F0\">::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttop\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tleft\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tinline-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tblock-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder-radius\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">4\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translate\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-6\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">grey\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">a\u003C/span>\u003Cspan style=\"color:#B392F0\">:visited::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">white\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Ces règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\u003C/p>\n\u003Ch3 id=\"accessibilité\">Accessibilité\u003C/h3>\n\u003Cp>On pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété \u003Ccode>content\u003C/code> mais les lecteurs d’écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d’écrans annoncent déjà si un lien est visité avant de lire son intitulé.\u003C/p>\n\u003Ch2 id=\"aller-plus-loin\">Aller plus loin\u003C/h2>\n\u003Cp>Afin de pousser l’expérience un peu plus loin, j’ai tenté d’utiliser des éléments plus explicites pour signifier l’état visité du lien. Bien qu’encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\u003C/p>\n\u003Cp>L’idée est d’avoir un \u003Ccode>::before\u003C/code> et un \u003Ccode>::after\u003C/code>, chacun contenant une icône en base 64 blanche en tant qu’image de fond. Quand le lien est non visité, le \u003Ccode>::before\u003C/code> contient un fond coloré qui fait apparaître l’icône. Quand le lien passe en visité, le fond du \u003Ccode>::before\u003C/code> devient blanc et celui du \u003Ccode>::after\u003C/code> devient coloré, ce qui masque la première icône et affiche la deuxième.\u003C/p>\n\u003Cp>Il est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l’une sur l’autre.\u003C/p>\n\u003Cp>\u003Ca href=\"https://codepen.io/narduin/pen/VwVwmrO\">Voir la démo sur codepen.\u003C/a>\u003C/p>",{"headings":381,"imagePaths":399,"frontmatter":400},[382,385,388,391,394,396],{"depth":80,"slug":383,"text":384},"la-théorie","La théorie",{"depth":80,"slug":386,"text":387},"la-spécification","La spécification",{"depth":80,"slug":389,"text":390},"la-pratique","La pratique",{"depth":120,"slug":392,"text":393},"le-code","Le code",{"depth":120,"slug":32,"text":395},"Accessibilité",{"depth":80,"slug":397,"text":398},"aller-plus-loin","Aller plus loin",[],{"title":369,"subtitle":370,"lang":16,"draft":374,"slug":366,"excerpt":401,"tags":402,"type":372,"createdAt":403},"Petit hack CSS",[18],"2023-06-06T18:34:00.000Z","en-acme-sh-tls-cert",{"id":404,"data":406,"body":413,"filePath":414,"digest":415,"rendered":416},{"title":407,"subtitle":408,"lang":409,"tags":410,"type":372,"slug":404,"createdAt":412},"Strong TLS certificates with acme.sh","384-bit of https","en",[411],"security",["Date","2022-06-08T14:24:06.000Z"],"## Disclaimer\n\nI'm, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs. \nThis is why I've switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nYou can learn (far) more by reading [this topic](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) and its linked resources.\n\n## Requirements\n\n### Installing acme.sh\n\nFor automation and ease of use purposes, I'm using [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# for using standalone mode, you might have to install as sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changing default authority\n\nBy default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let's Encrypt because according to acme.sh, they're the only ones offering ECC capabilities.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Using your DNS api\n\nIf available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports [a lot](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) of DNS providers.\n\n### Define an api key\n\nFollow the [docs](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) for your DNS provider, usually:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Issue the cert\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Using standalone mode\n\nIf you don't have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\n\nPort `80` must be free.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Examples\n\n### Multi domains standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domain DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Next steps\n\nThe ECC certificate alone will not grant you a high/perfect score.\n\n### TLS version\n\nLimit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a [5% compatibility gap](https://caniuse.com/?search=tls%201.) with 1.2).\n\n### HSTS\n\nUse the [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/) header.\n\n```\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Cipher suite\n\nUse recent and strong ciphers. This is where my knowledge hits its limit… I'm having a really hard time understanding what to use and why.\n\nI've based my initial choices of ciphers on [this list](https://tls.imirhil.fr/ciphers), cross referencing it with (older?) [browser compatibility](https://tls.imirhil.fr/suite).\n\nI then asked [Aeris](https://twitter.com/aeris22), the creator of [tls.imirhil.fr](https://tls.imirhil.fr), about it and he advised me to use the following:\n\n```\nECDHE+AES:ECDHE+CHACHA20\n```\n\nIn order to achieve a perfect score, we can be a little more restrictive with:\n\n```\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/en/acme-sh-tls-cert.md","41577e8aee884f85",{"html":417,"metadata":418},"\u003Ch2 id=\"disclaimer\">Disclaimer\u003C/h2>\n\u003Cp>I’m, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs.\u003Cbr>\nThis is why I’ve switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>You can learn (far) more by reading \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">this topic\u003C/a> and its linked resources.\u003C/p>\n\u003Ch2 id=\"requirements\">Requirements\u003C/h2>\n\u003Ch3 id=\"installing-acmesh\">Installing acme.sh\u003C/h3>\n\u003Cp>For automation and ease of use purposes, I’m using \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># for using standalone mode, you might have to install as sudo\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">curl\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> https://get.acme.sh\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#B392F0\"> sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -s\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> email=mail@domain.tld\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"changing-default-authority\">Changing default authority\u003C/h3>\n\u003Cp>By default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let’s Encrypt because according to acme.sh, they’re the only ones offering ECC capabilities.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --set-default-ca\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --server\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> letsencrypt\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"using-your-dns-api\">Using your DNS api\u003C/h2>\n\u003Cp>If available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">a lot\u003C/a> of DNS providers.\u003C/p>\n\u003Ch3 id=\"define-an-api-key\">Define an api key\u003C/h3>\n\u003Cp>Follow the \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">docs\u003C/a> for your DNS provider, usually:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">export\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> PROVIDER_Key\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"YOUR_API_KEY\"\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"issue-the-cert\">Issue the cert\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"using-standalone-mode\">Using standalone mode\u003C/h2>\n\u003Cp>If you don’t have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\u003C/p>\n\u003Cp>Port \u003Ccode>80\u003C/code> must be free.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"examples\">Examples\u003C/h2>\n\u003Ch3 id=\"multi-domains-standalone\">Multi domains standalone\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> www.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> subdomain.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"wildcard-domain-dns\">Wildcard domain DNS\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '*.domain.tld'\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"next-steps\">Next steps\u003C/h2>\n\u003Cp>The ECC certificate alone will not grant you a high/perfect score.\u003C/p>\n\u003Ch3 id=\"tls-version\">TLS version\u003C/h3>\n\u003Cp>Limit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a \u003Ca href=\"https://caniuse.com/?search=tls%201.\">5% compatibility gap\u003C/a> with 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Use the \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a> header.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>Strict-Transport-Security: max-age=31536000; includeSubDomains\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"cipher-suite\">Cipher suite\u003C/h3>\n\u003Cp>Use recent and strong ciphers. This is where my knowledge hits its limit… I’m having a really hard time understanding what to use and why.\u003C/p>\n\u003Cp>I’ve based my initial choices of ciphers on \u003Ca href=\"https://tls.imirhil.fr/ciphers\">this list\u003C/a>, cross referencing it with (older?) \u003Ca href=\"https://tls.imirhil.fr/suite\">browser compatibility\u003C/a>.\u003C/p>\n\u003Cp>I then asked \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, the creator of \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, about it and he advised me to use the following:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>In order to achieve a perfect score, we can be a little more restrictive with:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES256:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":419,"imagePaths":463,"frontmatter":464},[420,423,426,429,432,435,438,441,444,447,450,453,456,459,460],{"depth":80,"slug":421,"text":422},"disclaimer","Disclaimer",{"depth":80,"slug":424,"text":425},"requirements","Requirements",{"depth":120,"slug":427,"text":428},"installing-acmesh","Installing acme.sh",{"depth":120,"slug":430,"text":431},"changing-default-authority","Changing default authority",{"depth":80,"slug":433,"text":434},"using-your-dns-api","Using your DNS api",{"depth":120,"slug":436,"text":437},"define-an-api-key","Define an api key",{"depth":120,"slug":439,"text":440},"issue-the-cert","Issue the cert",{"depth":80,"slug":442,"text":443},"using-standalone-mode","Using standalone mode",{"depth":80,"slug":445,"text":446},"examples","Examples",{"depth":120,"slug":448,"text":449},"multi-domains-standalone","Multi domains standalone",{"depth":120,"slug":451,"text":452},"wildcard-domain-dns","Wildcard domain DNS",{"depth":80,"slug":454,"text":455},"next-steps","Next steps",{"depth":120,"slug":457,"text":458},"tls-version","TLS version",{"depth":120,"slug":246,"text":247},{"depth":120,"slug":461,"text":462},"cipher-suite","Cipher suite",[],{"title":407,"subtitle":408,"lang":409,"slug":404,"createdAt":253,"excerpt":465,"tags":466,"type":372},"Real cert have curves.",[411],"en-array-vs-array",{"id":467,"data":469,"body":474,"filePath":475,"digest":476,"rendered":477},{"title":470,"subtitle":471,"lang":409,"tags":472,"type":372,"slug":467,"createdAt":473},"Filter an array against another array","Array vs Array.",[262],["Date","2022-06-08T14:24:06.000Z"],"## Context\n\nFor a project, I had to come up with a way to filter an array of objects based on another array of strings.\n\nIn other words, I needed to include every object which `user` property was found in the second array.\n\nHere is an example:\n\n```javascript\nconst skills = [\n\t{\n\t\tname: 'Be awesome',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Great jokes',\n\t\tuser: 'Jacques'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Beatriz'\n\t}\n]\n\nconst selectedUsers = ['Jean', 'Beatriz']\n```\n\nI thought it would be pretty easy but I guess I'm not familiar enough with javascript 😬\n\n## My solution\n\nAfter a bit of thinking, I came up with the following statement:\n\n> I need to filter the skills based on which users are selected. So I need to loop over the `selectedUsers` array and filter the skills according to their `user` value.\n\nAfter a bit more trials and errors, this is the code I ended up using in a `computed property`:\n\n```javascript\n// index.vue\nconst filteredSkills = selectedUsers.map((user) => {\n\treturn skills.filter((skill) => {\n\t\treturn skill.user === user\n\t})\n})\n```\n\nI used `map()` in order to loop on the second array and used its string value to only include the corresponding skills with `filter()`.\n\nI'm pretty sure there is a better way to do it though…","src/content/fragments/en/array-vs-array.md","c63ba57b1049cf4c",{"html":478,"metadata":479},"\u003Ch2 id=\"context\">Context\u003C/h2>\n\u003Cp>For a project, I had to come up with a way to filter an array of objects based on another array of strings.\u003C/p>\n\u003Cp>In other words, I needed to include every object which \u003Ccode>user\u003C/code> property was found in the second array.\u003C/p>\n\u003Cp>Here is an example:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> skills\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Be awesome'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jean'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Great jokes'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jacques'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jean'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Beatriz'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> selectedUsers\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jean'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Beatriz'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>I thought it would be pretty easy but I guess I’m not familiar enough with javascript 😬\u003C/p>\n\u003Ch2 id=\"my-solution\">My solution\u003C/h2>\n\u003Cp>After a bit of thinking, I came up with the following statement:\u003C/p>\n\u003Cblockquote>\n\u003Cp>I need to filter the skills based on which users are selected. So I need to loop over the \u003Ccode>selectedUsers\u003C/code> array and filter the skills according to their \u003Ccode>user\u003C/code> value.\u003C/p>\n\u003C/blockquote>\n\u003Cp>After a bit more trials and errors, this is the code I ended up using in a \u003Ccode>computed property\u003C/code>:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> filteredSkills\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> selectedUsers.\u003C/span>\u003Cspan style=\"color:#B392F0\">map\u003C/span>\u003Cspan style=\"color:#E1E4E8\">((\u003C/span>\u003Cspan style=\"color:#FFAB70\">user\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">=>\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">\treturn\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> skills.\u003C/span>\u003Cspan style=\"color:#B392F0\">filter\u003C/span>\u003Cspan style=\"color:#E1E4E8\">((\u003C/span>\u003Cspan style=\"color:#FFAB70\">skill\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">=>\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">\t\treturn\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> skill.user \u003C/span>\u003Cspan style=\"color:#F97583\">===\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> user\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t})\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">})\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>I used \u003Ccode>map()\u003C/code> in order to loop on the second array and used its string value to only include the corresponding skills with \u003Ccode>filter()\u003C/code>.\u003C/p>\n\u003Cp>I’m pretty sure there is a better way to do it though…\u003C/p>",{"headings":480,"imagePaths":487,"frontmatter":488},[481,484],{"depth":80,"slug":482,"text":483},"context","Context",{"depth":80,"slug":485,"text":486},"my-solution","My solution",[],{"title":470,"subtitle":471,"lang":409,"slug":467,"createdAt":253,"excerpt":489,"tags":490,"type":372},"My peak javascript",[262],"en-buttons",{"id":491,"data":493,"body":498,"filePath":499,"digest":500,"rendered":501},{"title":494,"subtitle":495,"lang":409,"tags":496,"type":372,"slug":491,"createdAt":497,"code":264,"draft":264},"Buttons hover","Simple, but nice.",[281],["Date","2020-10-08T09:00:00.000Z"],"## General rules\n\nAll the buttons use these styles as a “reset”:\n\n> Don't forget to prefix if necessary!\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Add an icon\n\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('~assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double shutter down\n\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Animated gradient\n\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Non destructive scale\n\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/en/buttons.md","ea9a5513a5a4cef4",{"html":502,"metadata":503},"\u003Ch2 id=\"general-rules\">General rules\u003C/h2>\n\u003Cp>All the buttons use these styles as a “reset”:\u003C/p>\n\u003Cblockquote>\n\u003Cp>Don’t forget to prefix if necessary!\u003C/p>\n\u003C/blockquote>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tmargin\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">20\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tpadding\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">12\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 26\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">relative\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tdisplay\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">inline-block\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\toverflow\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hidden\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tfont-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">20\u003C/span>\u003Cspan style=\"color:#F97583\">rem\u003C/span>\u003Cspan style=\"color:#E1E4E8\">; \u003C/span>\u003Cspan style=\"color:#6A737D\">/* 20px */\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tline-height\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">1.6\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttext-align\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">center\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttext-decoration\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tfont-weight\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">bold\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcursor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">pointer\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder-radius\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t-moz-appearance\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t-webkit-appearance\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">white\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hotpink\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: background-color \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"add-an-icon\">Add an icon\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hotpink\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">url\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'~assets/svg/arrow-right-white.svg'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">20\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttop\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tright\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translate\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">40\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">-50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">ease\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:hover\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:focus\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">darkorchid\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:hover::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:focus::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translate\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-10\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">-50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon\u003C/span>\u003Cspan style=\"color:#F97583\"> >\u003C/span>\u003Cspan style=\"color:#85E89D\"> span\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tdisplay\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">inline-block\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\theight\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:hover\u003C/span>\u003Cspan style=\"color:#F97583\"> >\u003C/span>\u003Cspan style=\"color:#85E89D\"> span\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:focus\u003C/span>\u003Cspan style=\"color:#F97583\"> >\u003C/span>\u003Cspan style=\"color:#85E89D\"> span\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translateX\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-10\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"double-shutter-down\">Double shutter down\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> solid\u003C/span>\u003Cspan style=\"color:#79B8FF\"> #10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">#10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">transparent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">color\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">white\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hotpink\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">darkorchid\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\theight\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbottom\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tleft\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tz-index\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">-1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition-timing-function\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition-timing-function\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">cubic-bezier\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">0.75\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.125\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:focus::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:focus::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translateY\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:focus::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition-delay\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.175\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"animated-gradient\">Animated gradient\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-gradient\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">linear-gradient\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-45\u003C/span>\u003Cspan style=\"color:#F97583\">deg\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#ee7752\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#e73c7e\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#23a6d5\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#23d5ab\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">400\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 400\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tanimation\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: GradientReverse \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.5\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:#79B8FF\"> normal\u003C/span>\u003Cspan style=\"color:#79B8FF\"> forwards\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-gradient:hover\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-gradient:focus\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tanimation\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: Gradient \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.5\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:#79B8FF\"> normal\u003C/span>\u003Cspan style=\"color:#79B8FF\"> forwards\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">@keyframes\u003C/span>\u003Cspan style=\"color:#FFAB70\"> Gradient\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t0%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t100%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">@keyframes\u003C/span>\u003Cspan style=\"color:#FFAB70\"> GradientReverse\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t0%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t100%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"non-destructive-scale\">Non destructive scale\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\toverflow\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">visible\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">#10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">transparent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttop\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tleft\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbottom\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> solid\u003C/span>\u003Cspan style=\"color:#79B8FF\"> #10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder-radius\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale:hover::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale:focus::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">scale\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">1.1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":504,"imagePaths":520,"frontmatter":521},[505,508,511,514,517],{"depth":80,"slug":506,"text":507},"general-rules","General rules",{"depth":80,"slug":509,"text":510},"add-an-icon","Add an icon",{"depth":80,"slug":512,"text":513},"double-shutter-down","Double shutter down",{"depth":80,"slug":515,"text":516},"animated-gradient","Animated gradient",{"depth":80,"slug":518,"text":519},"non-destructive-scale","Non destructive scale",[],{"title":494,"subtitle":495,"lang":409,"slug":491,"draft":264,"excerpt":522,"tags":523,"code":264,"type":372,"createdAt":524},"Easy to grab and use hover effects.",[281],"2020-10-08T09:00:00.000Z","en-image-full",{"id":525,"data":527,"body":533,"filePath":534,"digest":535,"deferredRender":264},{"title":528,"subtitle":529,"lang":409,"tags":530,"type":372,"slug":525,"createdAt":531,"updatedAt":532,"draft":264},"Full width image","Translation in progress, stay tuned ;)",[281],["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"[Go back to available snippets](/en/snippets)","src/content/fragments/en/image-full.mdx","2e3dddf593f6d72f","en-nuxt-graphql-static",{"id":536,"data":538,"body":544,"filePath":545,"digest":546,"rendered":547},{"title":539,"subtitle":540,"lang":409,"tags":541,"type":372,"slug":536,"createdAt":542,"updatedAt":543},"Static website and GraphQL queries with Nuxt.js","Graphql client is king.",[262],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## The problem\n\nI encountered a nasty bug while using static generation with Nuxt and [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (new tab)') client.\nI found [the issue](https://github.com/nuxt-community/apollo-module/issues/339 'Github issue on nuxt/apollo repository (new tab)') already reported on github.\n\nIt seems the module doesn't handle static generation correctly with `nuxt generate`.\n\nI could find request to my local API url after the static generation. Moreover, it also seemed like `\u003Cnuxt-link>` navigation was broken.\n\n## The solution 🙌\n\nFortunately, there is another Nuxt module that handles GraphQL requests!\n\n[Nuxt graphql request to the rescue!](https://github.com/gomah/nuxt-graphql-request)\n\n### The conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### The request\n\nThe best approach so far is to use `asyncData` in pages and `fetch` in components. Using `fetch` in pages does not work well at all with `nuxt generate`.\n\nI also install the `graphql-tag` package (only in `devDependencies`) to be able to import directly `.gql` files.\n\nQuery example:\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Inside a page\n\n```javascript\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n async asyncData({ $graphql }) {\n const data = await $graphql.default.request(homepageQuery)\n return { data }\n },\n}\n\u003C/script>\n```\n\n#### Inside a component\n\nIt is safer to wait until `fetch` has received a response before displaying anything. You can use `$fetchState` to be sure ([documentation](https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation on the fetch hook (new tab)')).\n\n```javascript\n// Header.vue\n\u003Ctemplate>\n \u003Cheader v-if=\"!$fetchState.pending\">\n …\n \u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n data() {\n return {\n data: {},\n }\n },\n async fetch() {\n try {\n const data = await this.$graphql.default.request(headerQuery)\n this.data = data\n } catch (error) {\n console.error(JSON.stringify(error, undefined, 2))\n }\n },\n}\n\u003C/script>\n```\n\n### Options\n\nTo pass options to the request, for example for a multilingual version with [nuxt/i18n](https://i18n.nuxtjs.org/) and/or a url parameter in a dynamic page:\n\n```javascript\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n async asyncData({ $graphql, app, params }) {\n const locale = app.i18n.localeProperties.iso\n const data = await $graphql.default.request(articleQuery, {\n code: locale,\n slug: params.slug,\n })\n return { data }\n },\n}\n\u003C/script>\n```","src/content/fragments/en/nuxt-graphql-static.md","181e8091294eb858",{"html":548,"metadata":549},"\u003Ch2 id=\"the-problem\">The problem\u003C/h2>\n\u003Cp>I encountered a nasty bug while using static generation with Nuxt and \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (new tab)\">nuxt apollo\u003C/a> client.\nI found \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Github issue on nuxt/apollo repository (new tab)\">the issue\u003C/a> already reported on github.\u003C/p>\n\u003Cp>It seems the module doesn’t handle static generation correctly with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I could find request to my local API url after the static generation. Moreover, it also seemed like \u003Ccode><nuxt-link>\u003C/code> navigation was broken.\u003C/p>\n\u003Ch2 id=\"the-solution\">The solution 🙌\u003C/h2>\n\u003Cp>Fortunately, there is another Nuxt module that handles GraphQL requests!\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\">Nuxt graphql request to the rescue!\u003C/a>\u003C/p>\n\u003Ch3 id=\"the-conf\">The conf\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// nuxt.config.js\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">buildModules\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\"> 'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">graphql\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> clients\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> default\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> endpoint: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> options: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> headers: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> authorization: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">},\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"the-request\">The request\u003C/h3>\n\u003Cp>The best approach so far is to use \u003Ccode>asyncData\u003C/code> in pages and \u003Ccode>fetch\u003C/code> in components. Using \u003Ccode>fetch\u003C/code> in pages does not work well at all with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I also install the \u003Ccode>graphql-tag\u003C/code> package (only in \u003Ccode>devDependencies\u003C/code>) to be able to import directly \u003Ccode>.gql\u003C/code> files.\u003C/p>\n\u003Cp>Query example:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"graphql\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># homepage.gql\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">query\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\thomepage\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\ttitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\tsubtitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\thero\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\tid\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\talt\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"inside-a-page\">Inside a page\u003C/h4>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import homepageQuery from '~/graphql/queries/singles/homepage'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(homepageQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"inside-a-component\">Inside a component\u003C/h4>\n\u003Cp>It is safer to wait until \u003Ccode>fetch\u003C/code> has received a response before displaying anything. You can use \u003Ccode>$fetchState\u003C/code> to be sure (\u003Ca href=\"https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation on the fetch hook (new tab)\">documentation\u003C/a>).\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// Header.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> <\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#B392F0\"> v-if\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"!$fetchState.pending\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> …\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> </\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import headerQuery from '~/graphql/queries/singles/header'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">fetch\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> try {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> data\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.$graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(headerQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> data\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> } catch (error) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> console.\u003C/span>\u003Cspan style=\"color:#B392F0\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(JSON.stringify(\u003C/span>\u003Cspan style=\"color:#FFAB70\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">undefined\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, 2))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"options\">Options\u003C/h3>\n\u003Cp>To pass options to the request, for example for a multilingual version with \u003Ca href=\"https://i18n.nuxtjs.org/\">nuxt/i18n\u003C/a> and/or a url parameter in a dynamic page:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// _slug.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import articleQuery from '~/graphql/queries/articles'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql, app, params }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const locale \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> app.i18n.localeProperties.iso\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(articleQuery, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> code: locale,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> slug: params.slug,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> })\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":550,"imagePaths":572,"frontmatter":573},[551,554,557,560,563,566,569],{"depth":80,"slug":552,"text":553},"the-problem","The problem",{"depth":80,"slug":555,"text":556},"the-solution","The solution 🙌",{"depth":120,"slug":558,"text":559},"the-conf","The conf",{"depth":120,"slug":561,"text":562},"the-request","The request",{"depth":325,"slug":564,"text":565},"inside-a-page","Inside a page",{"depth":325,"slug":567,"text":568},"inside-a-component","Inside a component",{"depth":120,"slug":570,"text":571},"options","Options",[],{"title":539,"subtitle":540,"lang":409,"slug":536,"createdAt":253,"updatedAt":336,"excerpt":574,"tags":575,"type":372},"When the most used gql module doesn't work…",[262],"en-super-cookies",{"id":576,"data":578,"body":584,"filePath":585,"digest":586,"deferredRender":264},{"title":579,"subtitle":580,"lang":409,"tags":581,"type":372,"slug":576,"createdAt":583},"The best cookies","Consentless biscuits.",[582],"food",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 tablespoon of baking powder\n- 3/4 of aquafaba from 400g of chickpea (chickpea water)\n- 125 grams of coconut oil\n- 2 teaspoons of maple syrup\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- if necessary, melt the coconut oil over low heat\n- meanwhile, mix all the dry ingredients\n- add all liquid ingredients (oil, aquafaba, maple syrup)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Non vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 table spoon of baking powder\n- 1 egg\n- 125 grams of melted butter\n- 2 teaspoons of honey\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- melt butter over low heat\n- meanwhile, mix all dry ingredients\n- add all liquid ingredients (melted butter, egg, honey)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Notes\n\nChocolate can be replaced by anything like nuts, raisins, legos... (don't eat legos be reasonable).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='All ingredients mixed together to form a brown paste.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='The cookies are round and soft after baking.'\n/>","src/content/fragments/en/super-cookies.mdx","b0c67adad40c177c","en-toulouse-fun",{"id":587,"data":589,"body":593,"filePath":594,"digest":595,"rendered":596},{"title":353,"subtitle":590,"lang":409,"tags":591,"type":372,"slug":587,"createdAt":592},"Only the bestest",[355],["Date","2022-06-22T15:34:45.000Z"],"Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite. \n**It's always a good idea to make a reservation!**\n\n## Restaurants\n\n### French cuisine\n\n- [Solides](https://www.solides.fr/) — semi-gastronomic\n- [Les impulsifs](https://les-impulsifs-toulouse.eatbu.com/?lang=en) — semi-gastronomic\n- [Sixta](https://sixta-toulouse.fr/) — vege/vegan/gluten friendly\n- [Attila](https://attila.site-solocal.com/) — great **fish restaurant,** just above the Victor Hugo market\n- [Chez Emile](https://www.restaurant-emile.com/) - best [cassoulet](https://en.wikipedia.org/wiki/Cassoulet) in town (or so I'm told)\n\n### Korean\n\n- [Le ptit Louis](https://leptitlouis.fr/) — best of its kind, **only for lunch**\n- [Kongbap](https://kong-bap.com/) — street-food like\n\n### Japanese\n\n- [Iori](https://www.iori.fr/) — best ramen\n- [Japoyaki](https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402) — best sushi/sashimis\n\n## Drinks and snacks\n\n### Bars\n\n- [Le Bièrographe](https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327) — all time favourite, **check out the typical toulouse basement**\n- [A Taula](https://www.facebook.com/ataulatolosa/) — all time favourite in summer, **amazing terrace,** also: great tapas\n- [The Hopscotch Pub](https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385) — good beers, good whiskies, good cocktials, good food\n\n### Cafés & tea rooms\n\n- [Bapz](https://www.bapz.fr/contact) — Excellent pastries / hot beverages\n- [Ô thé divin](https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/) — nice lunch options\n- [Les Rêveries d’Hercule](https://www.lesreveriesdhercule.com/) — Pottery Café, relaxing activity (ceramics need to be baked, there'll be a delay to get them back)\n- Bonus: the best bakeries in [Carmes](https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872) and [Saint-Aubin](https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694) — croissants, baguettes **traditions**, chocolatines and more\n\n### Wine shops\n\n- [l'envie du sud](https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930) — amazing selection of wines and other spirits, excellent advice from the staff\n- [enoteca](https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952) — smaller selection but more beers and great advice from the staff as well\n\n## Other delights\n\n### Ice creams\n\n- [Forno gusto](https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450) — only in the summer\n- [Moustache](https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540) — lots of flavours\n\n### Cheese shop\n\n- [Xavier](https://xavier.fr/) — one of the **best of the country**, two shops in Toulouse, including one at Victor Hugo market\n- [Massembea](https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490) — a serious contender in Toulouse (weird hours)\n\n### Delicatessen\n\n- [Café Bacquié](http://cafe-bacquie.com/) — stock up on fine foods, coffees, teas and other great quality products","src/content/fragments/en/toulouse-fun.md","370491cc68079e8c",{"html":597,"metadata":598},"\u003Cp>Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite.\u003Cbr>\n\u003Cstrong>It’s always a good idea to make a reservation!\u003C/strong>\u003C/p>\n\u003Ch2 id=\"restaurants\">Restaurants\u003C/h2>\n\u003Ch3 id=\"french-cuisine\">French cuisine\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.solides.fr/\">Solides\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://les-impulsifs-toulouse.eatbu.com/?lang=en\">Les impulsifs\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://sixta-toulouse.fr/\">Sixta\u003C/a> — vege/vegan/gluten friendly\u003C/li>\n\u003Cli>\u003Ca href=\"https://attila.site-solocal.com/\">Attila\u003C/a> — great \u003Cstrong>fish restaurant,\u003C/strong> just above the Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.restaurant-emile.com/\">Chez Emile\u003C/a> - best \u003Ca href=\"https://en.wikipedia.org/wiki/Cassoulet\">cassoulet\u003C/a> in town (or so I’m told)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"korean\">Korean\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://leptitlouis.fr/\">Le ptit Louis\u003C/a> — best of its kind, \u003Cstrong>only for lunch\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://kong-bap.com/\">Kongbap\u003C/a> — street-food like\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"japanese\">Japanese\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.iori.fr/\">Iori\u003C/a> — best ramen\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402\">Japoyaki\u003C/a> — best sushi/sashimis\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"drinks-and-snacks\">Drinks and snacks\u003C/h2>\n\u003Ch3 id=\"bars\">Bars\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327\">Le Bièrographe\u003C/a> — all time favourite, \u003Cstrong>check out the typical toulouse basement\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.facebook.com/ataulatolosa/\">A Taula\u003C/a> — all time favourite in summer, \u003Cstrong>amazing terrace,\u003C/strong> also: great tapas\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385\">The Hopscotch Pub\u003C/a> — good beers, good whiskies, good cocktials, good food\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cafés--tea-rooms\">Cafés & tea rooms\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.bapz.fr/contact\">Bapz\u003C/a> — Excellent pastries / hot beverages\u003C/li>\n\u003Cli>\u003Ca href=\"https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/\">Ô thé divin\u003C/a> — nice lunch options\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lesreveriesdhercule.com/\">Les Rêveries d’Hercule\u003C/a> — Pottery Café, relaxing activity (ceramics need to be baked, there’ll be a delay to get them back)\u003C/li>\n\u003Cli>Bonus: the best bakeries in \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872\">Carmes\u003C/a> and \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694\">Saint-Aubin\u003C/a> — croissants, baguettes \u003Cstrong>traditions\u003C/strong>, chocolatines and more\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"wine-shops\">Wine shops\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930\">l’envie du sud\u003C/a> — amazing selection of wines and other spirits, excellent advice from the staff\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952\">enoteca\u003C/a> — smaller selection but more beers and great advice from the staff as well\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"other-delights\">Other delights\u003C/h2>\n\u003Ch3 id=\"ice-creams\">Ice creams\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450\">Forno gusto\u003C/a> — only in the summer\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540\">Moustache\u003C/a> — lots of flavours\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cheese-shop\">Cheese shop\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://xavier.fr/\">Xavier\u003C/a> — one of the \u003Cstrong>best of the country\u003C/strong>, two shops in Toulouse, including one at Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490\">Massembea\u003C/a> — a serious contender in Toulouse (weird hours)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"delicatessen\">Delicatessen\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"http://cafe-bacquie.com/\">Café Bacquié\u003C/a> — stock up on fine foods, coffees, teas and other great quality products\u003C/li>\n\u003C/ul>",{"headings":599,"imagePaths":636,"frontmatter":637},[600,603,606,609,612,615,618,621,624,627,630,633],{"depth":80,"slug":601,"text":602},"restaurants","Restaurants",{"depth":120,"slug":604,"text":605},"french-cuisine","French cuisine",{"depth":120,"slug":607,"text":608},"korean","Korean",{"depth":120,"slug":610,"text":611},"japanese","Japanese",{"depth":80,"slug":613,"text":614},"drinks-and-snacks","Drinks and snacks",{"depth":120,"slug":616,"text":617},"bars","Bars",{"depth":120,"slug":619,"text":620},"cafés--tea-rooms","Cafés & tea rooms",{"depth":120,"slug":622,"text":623},"wine-shops","Wine shops",{"depth":80,"slug":625,"text":626},"other-delights","Other delights",{"depth":120,"slug":628,"text":629},"ice-creams","Ice creams",{"depth":120,"slug":631,"text":632},"cheese-shop","Cheese shop",{"depth":120,"slug":634,"text":635},"delicatessen","Delicatessen",[],{"title":353,"subtitle":590,"lang":409,"slug":587,"excerpt":638,"tags":639,"type":372,"createdAt":364},"Gonna have to trust me on this ¯\\_(ツ)_/¯",[355],"en-visited-links",{"id":640,"data":642,"body":533,"filePath":646,"digest":647,"rendered":648},{"title":643,"subtitle":529,"lang":409,"tags":644,"type":372,"slug":640,"createdAt":645,"draft":264},"Visited links and visuel aid",[18],["Date","2023-06-06T18:34:00.000Z"],"src/content/fragments/en/visited-links.md","cb7c11c12c25067e",{"html":649,"metadata":650},"\u003Cp>\u003Ca href=\"/en/snippets\">Go back to available snippets\u003C/a>\u003C/p>",{"headings":651,"imagePaths":652,"frontmatter":653},[],[],{"title":643,"subtitle":529,"lang":409,"draft":264,"slug":640,"excerpt":401,"tags":654,"type":372,"createdAt":403},[18],"articles",["Map",657,658,670,671,704,705,738,739,749,750,766,767,781,782,792,793,805,806],"sci-hub-blocage",{"id":657,"data":659,"body":667,"filePath":668,"digest":669,"deferredRender":264},{"title":660,"subtitle":661,"lang":16,"tags":662,"type":655,"slug":657,"createdAt":665,"updatedAt":666},"Sci-hub bloqué, comment contourner","La science du partage.",[663,664],"Internet","Science",["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nL'adresse actuelle de sci-hub est : [sci-hub.se](https://sci-hub.se)\n\n## Résumé de la situation\n\nN’étant pas moi-même directement chercheur, je vous laisse regarder [cette vidéo](https://youtu.be/rcgxY__YXEc) explicative extrêmement bien faite sur le sujet de la publication scientifique.\n\n> “ Mais c’est scandaleux ! ”​\n\nJ’ai constaté que le blocage était actif chez SFR. Je n’ai pas encore pu vérifier pour les autres fournisseurs mais j’imagine qu’ils se sont tous conformés à la décision de justice.\nLe blocage mis en place est assez basique. Il s’agit d’un blocage “ DNS ”.\n\nUn DNS est un serveur qui sert à faire le lien entre un nom de domaine : **sci-hub.tw** et une adresse IP : **186.2.163.90**.\n\nC’est en quelque sorte l’annuaire d’internet. Sans l’adresse, impossible de contacter le domaine. Ce que les FAI ont certainement fait : bloquer les requêtes au nom de domaine [sci-hub.se.](http://sci-hub.se/) Ainsi, aucune adresse IP n’est renvoyée et le site n’est pas accessible.\n\n## Comment contourner ce blocage ?\n\n- Soit en utilisant un VPN\n- Soit en modifiant les serveurs DNS de vos ordinateurs/box internet\n\nJe recommande la deuxième solution car elle permet de se prémunir contre de futurs blocages/filtrages/censures de la part de votre FAI et ne nécessite pas de contrepartie financière.\nJe vais me focaliser sur le changement depuis un ordinateur car il sera effectif où que vous soyez.\n\n### Sur MacOs\n\nOuvrez :\n\n1. Préférences système\n1. Réseau\n1. Ethernet et/ou Wi-fi\n1. Avancé\n1. DNS\n1. Serveurs DNS\n\nDe là, vous pouvez ajouter des serveurs DNS en cliquant sur l'icône +. Cliquez sur ok et appliquez les nouveaux paramètres. Vous devrez peut-être redémarrer votre ordinateur pour que les changements fonctionnent.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS réglages réseau et DNS'\n/>\n\n### Sur Windows (ici 10)\n\nOuvrez :\n\n1. Réglages\n1. Réseau et internet\n1. Modifier les options de l'adaptateur\n1. Clic droit sur les propriétés de votre interface réseau\n1. Selectionnez « protocole Internet version 4 » (et/ou 6)\n1. Propriétés\n1. Utiliser l’adresse de serveur DNS suivante\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Réglages windows'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows réglages réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows régalges connections réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows options adaptateur réseau'\n/>\n\n## Quels serveurs DNS utiliser ?\n\nIl y a de nombreux serveurs DNS accessibles. Les plus connus étant ceux de Google, Cloudflare et OpenDNS. Si vous tenez vraiment à utiliser ceux de Google, je vous laisse chercher leur adresse. Voici mes recommandations par ordre de préférence.\n\nPlusieurs fournisseurs :\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMes favoris puisqu’il s’agit d’une [association française.](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net/fr)\n\nQuand9 est une fondation à but non lucratif proposant des serveurs DNS publics et gratuits. Leurs serveur classiques offrent un filtrage de domaines malveillants identifiés. Ils ne collectent pas de données et sont conforment au \u003Cabbr title=\"Règlement général sur la protection des données\">RGPD\u003C/abbr>.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## C'est tout.\n\nEn modifiant ces réglages, vous vous affranchissez de vos fournisseurs d’accès et de leurs règles de filtrage du contenu.\n\nPour l’instant, ces blocages sont presque symboliques car si Sci-hub venait à changer d’url, le blocage ne fonctionnerait plus. Mais la victoire des éditeurs au tribunal montre qu’ils n’ont pas dit leur dernier mot. Nous ne sommes donc pas à l’abri d’un futur blocage plus large et plus dur à contrer.\n\nSi vous voulez en apprendre plus sur le combat de ces gens qui se battent pour que la recherche ne soit pas une marchandise, je vous conseille [ce documentaire](https://youtu.be/y_CQATGOX2w) sur Aaron Shwartz. Ou plus simplement [cet article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) sur la fondatrice de Sci-hub.\n\nEn attendant, bonnes lectures à tou·te·s. On est avec vous !","src/content/articles/fr/sci-hub-blocage.mdx","6438fdc02b91ec59","en-2022",{"id":670,"data":672,"body":678,"filePath":679,"digest":680,"rendered":681},{"title":673,"subtitle":674,"lang":409,"tags":675,"type":655,"slug":670,"createdAt":677},"Nico v2.0","2022 update of many things.",[676],"Freelance",["Date","2022-06-08T14:24:06.000Z"],"After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\n\n## Services\n\n### No more print\n\nEven though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for \"classic\" graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\n\n### Internet all the way\n\nOn the other hand, I spend my time **doing web stuff.** A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer **more specific web offerings,** in which I have specialised.\n\nThus, **accessibility** and **eco-design** become integrated expertises in my practice. They are no longer options on a quote but **my core business.**\n\n## The website\n\nI have reworked my website, especially the homepage and its content, to better reflect these decisions.\n\nI have also made several behavioural changes:\n\n- external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven't found a good reason to continue using this behaviour;\n- I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu);\n- \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\n- I only trigger animations if the user has not asked the system to reduce the amount motion [(reference)](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).\n\nI am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello [astro](https://astro.build/) 👀).\n\n## Le Nico\n\nOn a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\n\nI have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.","src/content/articles/en/2022.md","7b98592763cb0929",{"html":682,"metadata":683},"\u003Cp>After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\u003C/p>\n\u003Ch2 id=\"services\">Services\u003C/h2>\n\u003Ch3 id=\"no-more-print\">No more print\u003C/h3>\n\u003Cp>Even though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for “classic” graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\u003C/p>\n\u003Ch3 id=\"internet-all-the-way\">Internet all the way\u003C/h3>\n\u003Cp>On the other hand, I spend my time \u003Cstrong>doing web stuff.\u003C/strong> A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer \u003Cstrong>more specific web offerings,\u003C/strong> in which I have specialised.\u003C/p>\n\u003Cp>Thus, \u003Cstrong>accessibility\u003C/strong> and \u003Cstrong>eco-design\u003C/strong> become integrated expertises in my practice. They are no longer options on a quote but \u003Cstrong>my core business.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Cp>I have reworked my website, especially the homepage and its content, to better reflect these decisions.\u003C/p>\n\u003Cp>I have also made several behavioural changes:\u003C/p>\n\u003Cul>\n\u003Cli>external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven’t found a good reason to continue using this behaviour;\u003C/li>\n\u003Cli>I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a>;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\u003C/li>\n\u003Cli>I only trigger animations if the user has not asked the system to reduce the amount motion \u003Ca href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion\">(reference)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>I am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello \u003Ca href=\"https://astro.build/\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>On a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\u003C/p>\n\u003Cp>I have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.\u003C/p>",{"headings":684,"imagePaths":700,"frontmatter":701},[685,688,691,694,697],{"depth":80,"slug":686,"text":687},"services","Services",{"depth":120,"slug":689,"text":690},"no-more-print","No more print",{"depth":120,"slug":692,"text":693},"internet-all-the-way","Internet all the way",{"depth":80,"slug":695,"text":696},"the-website","The website",{"depth":80,"slug":698,"text":699},"le-nico","Le Nico",[],{"title":673,"subtitle":674,"lang":409,"slug":670,"excerpt":702,"tags":703,"type":655,"createdAt":253},"Changes in my services, the website and myself.",[676],"en-2023",{"id":704,"data":706,"body":712,"filePath":713,"digest":714,"rendered":715},{"title":707,"subtitle":708,"lang":409,"tags":709,"type":655,"slug":704,"createdAt":710,"updatedAt":711},"Nico v2.5","Update 2023.",[676],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"This article will be updated when I have something new to share during the year 2023.\n\n## The website\n\n### Technologies\n\nOops... I (re)did it again.\n\nI have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself [in 2022 !](/en/articles/2022/#the-website)\n\nI will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\n\nMy \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I'm back to a solid **95/100** without any particular optimization. With some small efforts, I've reached the good old 100/100.\n\nI then did a work of modernization of the codebase. Hello CSS variables and goodbye `media queries`. In no particular order, here are some of the improvements I made:\n\n- `flexbox` and `grid` to adapt the layout to different screen sizes;\n- CSS variables for colors, font sizes and margins;\n- some `container queries`, just to try;\n- logical CSS properties (`inline` and `block` instead of `width` and `height` for example).\n\nI took this opportunity to publish [the source code](https://git.nardu.in/nardu.in/website-astro) on my git repository.\n\n**Update #1:** I've added [an RSS feed](/en/rss.xml) as I find myself using it more and more on other websites.\n\n### Analytics\n\nI removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\n\nIt's nice to see that your site is consulted, but if there is no other purpose behind it, it's an extra resource loaded for nothing by visitors. Maybe I'll reactivate the tracking when I have a use for it (other than flattering my ego).\n\nPrevious visit reports can be found at [this link.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Content\n\n- I've added a [work](/en/work/) page to list some of my projects.\n- I've also added [a page](/en/veille/) where I list some interesting things from around the web.\n\n## Additional projects\n\nI'm still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at [3-w.fr](https://3-w.fr/) (an address I am very proud of).\n\nI have to update it more regularly but I hope that the platform will help students progress!\n\n**More to come soon!**","src/content/articles/en/2023.md","489c650e66cced63",{"html":716,"metadata":717},"\u003Cp>This article will be updated when I have something new to share during the year 2023.\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oops… I (re)did it again.\u003C/p>\n\u003Cp>I have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself \u003Ca href=\"/en/articles/2022/#the-website\">in 2022 !\u003C/a>\u003C/p>\n\u003Cp>I will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\u003C/p>\n\u003Cp>My \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I’m back to a solid \u003Cstrong>95/100\u003C/strong> without any particular optimization. With some small efforts, I’ve reached the good old 100/100.\u003C/p>\n\u003Cp>I then did a work of modernization of the codebase. Hello CSS variables and goodbye \u003Ccode>media queries\u003C/code>. In no particular order, here are some of the improvements I made:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> and \u003Ccode>grid\u003C/code> to adapt the layout to different screen sizes;\u003C/li>\n\u003Cli>CSS variables for colors, font sizes and margins;\u003C/li>\n\u003Cli>some \u003Ccode>container queries\u003C/code>, just to try;\u003C/li>\n\u003Cli>logical CSS properties (\u003Ccode>inline\u003C/code> and \u003Ccode>block\u003C/code> instead of \u003Ccode>width\u003C/code> and \u003Ccode>height\u003C/code> for example).\u003C/li>\n\u003C/ul>\n\u003Cp>I took this opportunity to publish \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">the source code\u003C/a> on my git repository.\u003C/p>\n\u003Cp>\u003Cstrong>Update #1:\u003C/strong> I’ve added \u003Ca href=\"/en/rss.xml\">an RSS feed\u003C/a> as I find myself using it more and more on other websites.\u003C/p>\n\u003Ch3 id=\"analytics\">Analytics\u003C/h3>\n\u003Cp>I removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\u003C/p>\n\u003Cp>It’s nice to see that your site is consulted, but if there is no other purpose behind it, it’s an extra resource loaded for nothing by visitors. Maybe I’ll reactivate the tracking when I have a use for it (other than flattering my ego).\u003C/p>\n\u003Cp>Previous visit reports can be found at \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">this link.\u003C/a>\u003C/p>\n\u003Ch3 id=\"content\">Content\u003C/h3>\n\u003Cul>\n\u003Cli>I’ve added a \u003Ca href=\"/en/work/\">work\u003C/a> page to list some of my projects.\u003C/li>\n\u003Cli>I’ve also added \u003Ca href=\"/en/veille/\">a page\u003C/a> where I list some interesting things from around the web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"additional-projects\">Additional projects\u003C/h2>\n\u003Cp>I’m still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (an address I am very proud of).\u003C/p>\n\u003Cp>I have to update it more regularly but I hope that the platform will help students progress!\u003C/p>\n\u003Cp>\u003Cstrong>More to come soon!\u003C/strong>\u003C/p>",{"headings":718,"imagePaths":732,"frontmatter":733},[719,720,723,726,729],{"depth":80,"slug":695,"text":696},{"depth":120,"slug":721,"text":722},"technologies","Technologies",{"depth":120,"slug":724,"text":725},"analytics","Analytics",{"depth":120,"slug":727,"text":728},"content","Content",{"depth":80,"slug":730,"text":731},"additional-projects","Additional projects",[],{"title":707,"subtitle":708,"lang":409,"slug":704,"excerpt":734,"tags":735,"type":655,"createdAt":736,"updatedAt":737},"New changes.",[676],"2023-02-03T17:41:00.000Z","2023-05-17T17:41:00.000Z","en-after-effects-expressions",{"id":738,"data":740,"body":746,"filePath":747,"digest":748,"deferredRender":264},{"title":741,"subtitle":742,"lang":409,"tags":743,"type":655,"slug":738,"createdAt":745,"code":264},"After Effects Expressions","Animation on steroïds.",[744],"Design",["Date","2019-04-24T09:00:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## An ever lasting battle\n\nThere is very little documentation and the existing one is hard to find or very old. Very often I just don't have the time to dive into expression learning while animating even though it could help the entire project on the long term.\nSo the last time I had to do a complex animation, **I took the damn time!**\n\n## The begining of the end (of keyframes).\n\nEveryone uses expressions whether they know it or not. Most of the time it's a rather transparent process for the animator. For example: when parenting a property to another one, After Effects creates an expression for us.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/basic_expression_d81b12f1ac.jpeg'\n\twidth='728'\n\theight='80'\n\talt='Parenting the position of the form to a null creates an expression.'\n/>\n\nOver the last updates, Adobe has made an effort to make expressions more accessible to everyone. For example, the expression box is now resembling a code editor thanks to code-coloring and auto-completion features. After Effects expression feel like JavaScript with custom functions.\n\nThose custom functions can be called through a menu once you enabled the expressions on a property. It offers organized shortcut and proper syntax to all of AE native functions and a bunch of JavaScript standard ones.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/shortcut_39cc19d383.jpeg'\n\twidth='728'\n\theight='322'\n\talt='Alt + Click the stopwatch to access the shortcuts.'\n/>\n\n## So I need to learn javascript to do motion design now?\n\n### Why bother?\n\nI know that most animators don't have any kind of development background. However, if Adobe thought it best to let us use expressions, I think we ought to, at least, try.\n\n> A lot of incredible professionals like [Mt Mograph](https://www.mtmograph.com/) and [Video Copilot](https://videocopilot.net/) use expressions.\n\nLike every optimization process, building an expressions knowledge takes time. However, like all optimization process, you will benefit from it afterwards.\n\n### Where to learn\n\nI've gathered a list of my favourite learning grounds. Plenty more exist, **go get'em!**\n\n- [Adobe official expression starter guide (FR)](https://helpx.adobe.com/fr/after-effects/using/expression-language-reference.html)\n- [Adobe official expression basic (EN)](https://helpx.adobe.com/after-effects/using/expression-basics.html)\n- [Adobe forums for expressions](https://community.adobe.com/t5/after-effects/bd-p/after-effects?page=1&sort=latest_replies&filter=all&topics=label-expressions)\n- [Creative Cow expressions forums](https://creativecow.net/forums/forum/adobe-after-effects-expressions/)\n- [Youtube channel about expressions](https://www.youtube.com/playlist?list=PLvr5U5ZSt6IzHyvSL9fo0M9NRPsTvra31)\n- [All expressions explained](http://aescript.jecool.net/reference/)\n- [All expressions explained again](http://expressions.aenhancers.com/index.html)\n- [Nice examples of basic expressions](https://www.schoolofmotion.com/tutorials/amazing-expressions-in-after-effects)\n\n## Real world example\n\n### Number counter\n\nLet's say you need to animate a rather simple counter from 0% to 100%.\n\n- Start by creating a text layer. Define your typographic choices, colours, etc.\n- On the effect menu add expression options > slider control\n- Alt + Click the Source text property\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/alt-counter.mp4' type='video/mp4' />\n\u003C/video>\n\n- Parent the source text to the slider control through the pickwhip.\n\n\u003Cvideo width='462' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/pickwhip.mp4' type='video/mp4' />\n\u003C/video>\n\nYou should get something like this in the expressions panel:\n\n```javascript\neffect(\"Slider Control\")(\"Slider\")​\n```\n\n- Set two keyframes on the slider from 0 to 100. The text should update accordingly.\n- By default, After Effects does not round numbers. In the expression panel, wrap your expression with the `Math.round()` function.\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/round.mp4' type='video/mp4' />\n\u003C/video>\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\"))​\n```\n\nGreat! We have a working counter. But we wanted a percentage counter. We could add a % glyph in another text layer but let's not.\n\nStill in the expression panel, we're going to add a string containing the % glyph, using basic JavaScript concatenation: `+ '%'`\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\")) + '%'​\n```\n\n\u003Cvideo width='538' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/percent.mp4' type='video/mp4' />\n\u003C/video>\n\n**And there we go!** A fully functioning and customizable counter using a slider controller and expressions.","src/content/articles/en/after-effects-expressions.mdx","3b6f88fbf35af1a4","en-faq",{"id":749,"data":751,"body":755,"filePath":756,"digest":757,"rendered":758},{"title":752,"subtitle":529,"lang":409,"tags":753,"type":655,"slug":749,"createdAt":754,"draft":264},"Accessibility and sobriety",[676],["Date","2022-06-22T15:34:45.000Z"],"[Go back to available articles](/en/articles)","src/content/articles/en/faq.md","82d516449896f6ca",{"html":759,"metadata":760},"\u003Cp>\u003Ca href=\"/en/articles\">Go back to available articles\u003C/a>\u003C/p>",{"headings":761,"imagePaths":762,"frontmatter":763},[],[],{"title":752,"subtitle":529,"lang":409,"slug":749,"draft":264,"excerpt":764,"tags":765,"type":655,"createdAt":364},"Why, how et and especially what.",[676],"en-gratuiste",{"id":766,"data":768,"body":755,"filePath":772,"digest":773,"rendered":774},{"title":769,"subtitle":529,"lang":409,"tags":770,"type":655,"slug":766,"createdAt":771,"draft":264},"Gratuiste",[744,676],["Date","2017-05-27T07:47:36.000Z"],"src/content/articles/en/gratuiste.md","ebec75d19f0ff741",{"html":759,"metadata":775},{"headings":776,"imagePaths":777,"frontmatter":778},[],[],{"title":769,"subtitle":529,"lang":409,"slug":766,"draft":264,"excerpt":529,"tags":779,"type":655,"createdAt":780},[744,676],"2017-05-27T07:47:36.000Z","en-sci-hub-unblock",{"id":781,"data":783,"body":789,"filePath":790,"digest":791,"deferredRender":264},{"title":784,"subtitle":785,"lang":409,"tags":786,"type":655,"slug":781,"createdAt":787,"updatedAt":788},"Access blocked Sci-hub","The science of sharing.",[663,664],["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nThe current sci-hub address is: \u003Ca href=\"https://sci-hub.se\" rel=\"noreferer noopener\">sci-hub.se\u003C/a>\n\n## What is this about?\n\nNot being a researcher myself, here’s an [extremely well done explanatory video](https://youtu.be/rcgxY__YXEc) on the subject of scientific publication (french audio with auto subtitle).\n\n> “This is outrageous!”​\n\nI noticed that my ISP was indeed blocking access. I have not yet been able to check for the other suppliers, but I imagine that they have all complied with the court decision.\nThe restriction in place is quite basic. This is a “DNS” block. A DNS is a server that is used to link a domain name: **www.sci-hub.tw** to an IP address: **186.2.163.90**\nIt is, in a way, the Internet phone book. Without the address, it is impossible to contact the domain. What ISPs have certainly done: block requests to the [sci-hub.se.](http://sci-hub.se/) domain name. As a result, no IP address is returned and the site is not accessible.\n\n## How to bypass this?\n\n- Either by using a VPN\n- Either by modifying the DNS servers of your computers/Internet box\n\nI would recommend the second solution because it allows you to protect yourself against future blockages/filtering/censorship from your ISP and does not require any financial compensation.\nI will focus on change from a computer because it will be effective wherever you are and not only from your home.\n\n### MacOs\n\nGo to:\n\n1. System Preferences\n1. Network\n1. (wi-fi and/or ethernet)\n1. Advanced\n1. DNS\n\nFrom there, you can add DNS servers by clicking the + icon. Click ok and apply the new settings. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS network and DNS settings'\n/>\n\n### Windows (10)\n\nGo to:\n\n1. System Settings\n1. Network & Internet\n1. Change adapter options\n1. Right click your adapter then “properties”\n1. Select “internet protocol version 4” (and/or 6)\n1. Properties\n1. Use the following DNS server addresses\n\nFrom there, you can add DNS servers. Click save. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Windows system settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows network settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows network connections settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows network adapter settings'\n/>\n\n## Which DNS?\n\nThere are many DNS servers available. The best known are Google, Cloudflare and OpenDNS. If you really want to use Google’s, I’ll let you look up their address. Here are my recommendations in order of preference.\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMy favorite since it is a [french association](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net)\n\nQuand9 is a non-profit foundation offering free public DNS servers. Their classic servers offer filtering of identified malicious domains. They do not collect data and are \u003Cabbr title=\"General Data Protection Regulation\">GDPR\u003C/abbr>-compliant.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## That's it.\n\nBy changing these settings, you are free from your ISPs and their content filtering rules.\n\nFor the moment, these restrictions are almost symbolic because if Sci-hub were to change its url, the block would no longer work. But the publishers’ victory in court shows that they have not had their last word. We are therefore not immune to a wider and stronger block in the future.\n\nIf you want to learn more about the struggle of the people who fight to ensure that research is not a paid commodity, I recommend [this documentary](https://youtu.be/y_CQATGOX2w) on Aaron Shwartz. Or [this article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) about the founder of Sci-hub.\n\nIn the meantime, good readings to all of you. We stand with you!","src/content/articles/en/sci-hub-blocage.mdx","8959506d941cdcc5","en-the-day-I-jamd",{"id":792,"data":794,"body":802,"filePath":803,"digest":804,"deferredRender":264},{"title":795,"subtitle":796,"lang":409,"tags":797,"type":655,"slug":792,"createdAt":800,"updatedAt":801},"The day I Jam’d","A story of unusual tools and fun gambles.",[798,799],"Dev","Jamstack",["Date","2020-10-08T09:00:00.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## The not so easy choice\n\nWhen I was still using Wordpress for my personal website, I thought it would be nice to try [OpenLiteSpeed](https://openlitespeed.org) webserver. Being a designer, I always like to have a graphical interface and I heard OLS had very nice caching and overall performances.\n\n## FIGHT!\n\nA few years later, I learned about Jamstack and its incredible potential. Not being impulsive at all, I chose to entirely remake my website with tools like [11ty](https://www.11ty.dev/) and [Strapi](https://strapi.io/).\n\nI remember Strapi still being in alpha/beta and colleagues telling me it was a risky gamble, especially since I was pretty new to the node.js world.\n\n> Open source and french? Sign me up!\n\nSo I started recreating my website identically with 11ty and Strapi. Same hosting on a Digital Ocean droplet, same webserver, same content. I had done a fair amout of performance optimizations on my wordpress install so I was eager to compare the results with the new static version.\n\nBoy did they exceed my expectations! With almost no optimization on the static side, I got the following results.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 53/100 on Wordpress.'\n/>\n\nDespite a lot of efforts I could not do better. I’m no expert in caching, do not use CDN and relied on plugins to achieve a lot of stuff (php not being my strongest skill 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 97/100 on jamstack.'\n/>\n\nAlmost **zero** special configuration (I was too anxious to test) and I reached an awesome score. I know lighthouse scores are not everything but hey, **53 vs 97**… I’ll take it!\n\n## Now kiss 🥰\n\nBoth of these approaches have their benefits and drawbacks. As a freelance, my clients often prefer or ask for Wordpress because of its reputation. I always present a Jamstack alternative when possible but it’s still scary to most compared to Wordpress. I feel however that it’s going to be easier to use Jamstack with time.\n\n## I did it again…\n\nHere we are now, a quarantine and a few months later and this website is running with… [Nuxt.js](https://nuxtjs.org/). I know, I’m sorry, I couldn’t resist the latest [nuxt content](https://content.nuxtjs.org/) functionnality.\n\nSo I re-did everything again… and let me just say: **wow**, what an experience!\nI **love** developing with Nuxt. Using nuxt content allowed me to focus on design and, well, content.\nNo more Apollo client and graphQL query, only markdown and a few promises.\n\nDon’t get me wrong, I really like working with Strapi and its graphQL capabilities but for the purpose of this website, nuxt content does it (extremely well).\n\nI’m still using Strapi as a way to upload, store and manage images, videos, gifs, etc. It might be too much for this use case but I like to know that I can still go back to it if I want to! Also, I spent quite a bit of time setting it up with OpenLiteSpeed and I’m still too attached to this accomplishment to let it go.\n\n## In the end\n\nWordpress, Jamstack, vanilla everything… Does it really matter? For me, the dev experience was far more enjoyable working with 11ty, nuxt.js and strapi than with Wordpress.\n\nOn the performance and accessibility side, it also seems to be the better/smarter choice. It might not be everytime! ¯\\\\\\_(ツ)\\_/¯\n\nCan’t wait to learn [astro](https://astro.build/) and start from scratch again!","src/content/articles/en/the-day-I-jamd.mdx","60b77e216e02f618","en-video-compression",{"id":805,"data":807,"body":813,"filePath":814,"digest":815,"deferredRender":264},{"title":808,"subtitle":809,"lang":409,"tags":810,"type":655,"slug":805,"createdAt":811,"updatedAt":812},"Video compression","Encode like you mean it.",[744],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Let's play.\n\nVideos are everywhere. **EVERYWHERE!** But videos can and will be huge when 4k becomes an internet standard. Currently, 1920x1080 is king and we usually have no problem hosting or playing this resolution.\n\n## Because we can doesn't mean we should.\n\nRight now, the (good) trend of web performance is on the rise. Everyone wants a blazing fast loading website, which might not be possible if we send requests to 100mb (or even more) videos.\n\nWith a good connection, users will not see the difference. But if we go down that path, nor will they with a 300mb one. So the goal is to make every asset as small as possible. It's already the case with images. But it's simpler and faster than video encoding.\n\n## Small size, best quality.\n\nLet's say we exported​ a 1920x1080 video from Premiere Pro with these basic settings:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-premiere-1.jpeg'\n\twidth='673'\n\theight='800'\n/>\n\nIt's gorgeous, it's Full HD, it's 1:30 minute of excellent editing but it's 50mb… What a shame.\n\n> We can already bring down the size from Premiere or Media Encoder by selecting CBR instead of VBR and using a low bitrate (like 2 or 3).\n\nLet's now use [Handbrake!](https://handbrake.fr/) It's free, open source and multi platform. You can also read this great article from [Ueno](https://loremipsum.ueno.co/dear-ueno-how-do-you-compress-videos-6657ebd9dd28?gi=930afecec398) on video encoding.\n\n**Please please PLEASE. Never export videos from within After Effects.**\n\n## Handbrake\n\n### Summary screen\n\nWhile it's not as nice as Premiere Pro, it has way more exporting capabilities. Follow these steps to use good standard settings:\n\n1. Open your source video\n1. Select a preset corresponding to your future usage like Fast 1080p30\n1. Check Web Optimized\n1. Keep MPEG-4 as the format\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-1.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Video screen\n\n1. Keep H.264 (x264) or use H.264 nvidia nvenc if you can (crazy fast encoding by nvidia)\n1. Choose Constant Quality and try a value between 20 and 30​ (higher = smaller size but lower quality)\n1. Choose Peak Framerate. If you don't know the framerate, keep the default setting\n1. Choose the type of video you are encoding (film, animation…)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-2.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Audio screen\n\nIf you don't have audio, be sure to set the audio channel to none.\nIf you have an audio channel, these settings are great and will not influence the size much​:\n\n1. Codec AAC\n1. Samplerate 44.1\n1. Bitrate 192 to 256 (your choice)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-3.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Export!\n\nI used a RF of 25 for this example and no audio.\n\n1. My Premiere Pro video was 50,6mb\n1. My Handbrake video is 5,5mb​\n\n> What a save!\n\n​I ended up dividing the original size by 10. Which is cool.\nI tried with a RF of 30. The video was still pretty good and only 3,3mb.\n\n## Exporting for the web\n\nNow that we know how to properly compress videos, let's go further. Say we have a website with a lot of videos on the same page. We still want to load the content as fast as possible. So our videos need to be as small as possible. We won't do better than previously seen using mp4/H.264. However, we can use **webm/VP9.**\nWebm is an html video format and VP9 is its latest codec.\n\nUsing Handbrake and webm/VP9, we can achieve really great compression without losing too much quality (or none at all depending on the settings). I was able to divide by 4 the size of a video using these presets:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-4.jpg'\n\twidth='728'\n\theight='313'\n\talt=''\n/>\n\nThe only down side is that it takes some time to encode. It will depend on the video length and your computing power.\n\nI tried various settings but I read [here](https://trac.ffmpeg.org/wiki/Encode/VP9) that VP9 is supposed to be used with two-pass encoding. You then have to find the right bitrate (here 1000) for your situation.","src/content/articles/en/video-compression.mdx","5bb9f69df6c651d1"] \ No newline at end of file diff --git a/.astro/settings.json b/.astro/settings.json new file mode 100644 index 0000000..5b5bd70 --- /dev/null +++ b/.astro/settings.json @@ -0,0 +1,5 @@ +{ + "_variables": { + "lastUpdateCheck": 1735403503212 + } +} \ No newline at end of file diff --git a/.astro/types.d.ts b/.astro/types.d.ts index 40a8751..03d7cc4 100755 --- a/.astro/types.d.ts +++ b/.astro/types.d.ts @@ -1,483 +1,2 @@ -declare module 'astro:content' { - interface Render { - '.mdx': Promise<{ - Content: import('astro').MarkdownInstance<{}>['Content']; - headings: import('astro').MarkdownHeading[]; - remarkPluginFrontmatter: Record; - }>; - } -} - -declare module 'astro:content' { - interface Render { - '.md': Promise<{ - Content: import('astro').MarkdownInstance<{}>['Content']; - headings: import('astro').MarkdownHeading[]; - remarkPluginFrontmatter: Record; - }>; - } -} - -declare module 'astro:content' { - export { z } from 'astro/zod'; - - type Flatten = T extends { [K: string]: infer U } ? U : never; - - export type CollectionKey = keyof AnyEntryMap; - export type CollectionEntry = Flatten; - - export type ContentCollectionKey = keyof ContentEntryMap; - export type DataCollectionKey = keyof DataEntryMap; - - // This needs to be in sync with ImageMetadata - export type ImageFunction = () => import('astro/zod').ZodObject<{ - src: import('astro/zod').ZodString; - width: import('astro/zod').ZodNumber; - height: import('astro/zod').ZodNumber; - format: import('astro/zod').ZodUnion< - [ - import('astro/zod').ZodLiteral<'png'>, - import('astro/zod').ZodLiteral<'jpg'>, - import('astro/zod').ZodLiteral<'jpeg'>, - import('astro/zod').ZodLiteral<'tiff'>, - import('astro/zod').ZodLiteral<'webp'>, - import('astro/zod').ZodLiteral<'gif'>, - import('astro/zod').ZodLiteral<'svg'>, - import('astro/zod').ZodLiteral<'avif'>, - ] - >; - }>; - - type BaseSchemaWithoutEffects = - | import('astro/zod').AnyZodObject - | import('astro/zod').ZodUnion<[BaseSchemaWithoutEffects, ...BaseSchemaWithoutEffects[]]> - | import('astro/zod').ZodDiscriminatedUnion - | import('astro/zod').ZodIntersection; - - type BaseSchema = - | BaseSchemaWithoutEffects - | import('astro/zod').ZodEffects; - - export type SchemaContext = { image: ImageFunction }; - - type DataCollectionConfig = { - type: 'data'; - schema?: S | ((context: SchemaContext) => S); - }; - - type ContentCollectionConfig = { - type?: 'content'; - schema?: S | ((context: SchemaContext) => S); - }; - - type CollectionConfig = ContentCollectionConfig | DataCollectionConfig; - - export function defineCollection( - input: CollectionConfig - ): CollectionConfig; - - type AllValuesOf = T extends any ? T[keyof T] : never; - type ValidContentEntrySlug = AllValuesOf< - ContentEntryMap[C] - >['slug']; - - export function getEntryBySlug< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >( - collection: C, - // Note that this has to accept a regular string too, for SSR - entrySlug: E - ): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - - export function getDataEntryById( - collection: C, - entryId: E - ): Promise>; - - export function getCollection>( - collection: C, - filter?: (entry: CollectionEntry) => entry is E - ): Promise; - export function getCollection( - collection: C, - filter?: (entry: CollectionEntry) => unknown - ): Promise[]>; - - export function getEntry< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >(entry: { - collection: C; - slug: E; - }): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - export function getEntry< - C extends keyof DataEntryMap, - E extends keyof DataEntryMap[C] | (string & {}), - >(entry: { - collection: C; - id: E; - }): E extends keyof DataEntryMap[C] - ? Promise - : Promise | undefined>; - export function getEntry< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >( - collection: C, - slug: E - ): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - export function getEntry< - C extends keyof DataEntryMap, - E extends keyof DataEntryMap[C] | (string & {}), - >( - collection: C, - id: E - ): E extends keyof DataEntryMap[C] - ? Promise - : Promise | undefined>; - - /** Resolve an array of entry references from the same collection */ - export function getEntries( - entries: { - collection: C; - slug: ValidContentEntrySlug; - }[] - ): Promise[]>; - export function getEntries( - entries: { - collection: C; - id: keyof DataEntryMap[C]; - }[] - ): Promise[]>; - - export function reference( - collection: C - ): import('astro/zod').ZodEffects< - import('astro/zod').ZodString, - C extends keyof ContentEntryMap - ? { - collection: C; - slug: ValidContentEntrySlug; - } - : { - collection: C; - id: keyof DataEntryMap[C]; - } - >; - // Allow generic `string` to avoid excessive type errors in the config - // if `dev` is not running to update as you edit. - // Invalid collection names will be caught at build time. - export function reference( - collection: C - ): import('astro/zod').ZodEffects; - - type ReturnTypeOrOriginal = T extends (...args: any[]) => infer R ? R : T; - type InferEntrySchema = import('astro/zod').infer< - ReturnTypeOrOriginal['schema']> - >; - - type ContentEntryMap = { - "articles": { -"en/2022.md": { - id: "en/2022.md"; - slug: "en/2022"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".md"] }; -"en/2023.md": { - id: "en/2023.md"; - slug: "en/2023"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".md"] }; -"en/after-effects-expressions.mdx": { - id: "en/after-effects-expressions.mdx"; - slug: "en/after-effects-expressions"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".mdx"] }; -"en/faq.md": { - id: "en/faq.md"; - slug: "en/faq"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".md"] }; -"en/gratuiste.md": { - id: "en/gratuiste.md"; - slug: "en/gratuiste"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".md"] }; -"en/sci-hub-blocage.mdx": { - id: "en/sci-hub-blocage.mdx"; - slug: "en/sci-hub-blocage"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".mdx"] }; -"en/the-day-I-jamd.mdx": { - id: "en/the-day-I-jamd.mdx"; - slug: "en/the-day-i-jamd"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".mdx"] }; -"en/video-compression.mdx": { - id: "en/video-compression.mdx"; - slug: "en/video-compression"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".mdx"] }; -"fr/2022.md": { - id: "fr/2022.md"; - slug: "fr/2022"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".md"] }; -"fr/2023.md": { - id: "fr/2023.md"; - slug: "fr/2023"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".md"] }; -"fr/after-effects-expressions.md": { - id: "fr/after-effects-expressions.md"; - slug: "fr/after-effects-expressions"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".md"] }; -"fr/faq.md": { - id: "fr/faq.md"; - slug: "fr/faq"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".md"] }; -"fr/gratuiste.md": { - id: "fr/gratuiste.md"; - slug: "fr/gratuiste"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".md"] }; -"fr/sci-hub-blocage.mdx": { - id: "fr/sci-hub-blocage.mdx"; - slug: "fr/sci-hub-blocage"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".mdx"] }; -"fr/the-day-I-jamd.mdx": { - id: "fr/the-day-I-jamd.mdx"; - slug: "fr/the-day-i-jamd"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".mdx"] }; -"fr/video-compression.md": { - id: "fr/video-compression.md"; - slug: "fr/video-compression"; - body: string; - collection: "articles"; - data: InferEntrySchema<"articles"> -} & { render(): Render[".md"] }; -}; -"fragments": { -"en/acme-sh-tls-cert.md": { - id: "en/acme-sh-tls-cert.md"; - slug: "en/acme-sh-tls-cert"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".md"] }; -"en/array-vs-array.md": { - id: "en/array-vs-array.md"; - slug: "en/array-vs-array"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".md"] }; -"en/buttons.md": { - id: "en/buttons.md"; - slug: "en/buttons"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".md"] }; -"en/image-full.mdx": { - id: "en/image-full.mdx"; - slug: "en/image-full"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".mdx"] }; -"en/nuxt-graphql-static.md": { - id: "en/nuxt-graphql-static.md"; - slug: "en/nuxt-graphql-static"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".md"] }; -"en/super-cookies.mdx": { - id: "en/super-cookies.mdx"; - slug: "en/super-cookies"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".mdx"] }; -"en/toulouse-fun.md": { - id: "en/toulouse-fun.md"; - slug: "en/toulouse-fun"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".md"] }; -"en/visited-links.md": { - id: "en/visited-links.md"; - slug: "en/visited-links"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".md"] }; -"fr/acme-sh-tls-cert.md": { - id: "fr/acme-sh-tls-cert.md"; - slug: "fr/acme-sh-tls-cert"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".md"] }; -"fr/array-vs-array.md": { - id: "fr/array-vs-array.md"; - slug: "fr/array-vs-array"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".md"] }; -"fr/buttons.mdx": { - id: "fr/buttons.mdx"; - slug: "fr/buttons"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".mdx"] }; -"fr/image-full.mdx": { - id: "fr/image-full.mdx"; - slug: "fr/image-full"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".mdx"] }; -"fr/nuxt-graphql-static.md": { - id: "fr/nuxt-graphql-static.md"; - slug: "fr/nuxt-graphql-static"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".md"] }; -"fr/super-cookies.mdx": { - id: "fr/super-cookies.mdx"; - slug: "fr/super-cookies"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".mdx"] }; -"fr/toulouse-fun.md": { - id: "fr/toulouse-fun.md"; - slug: "fr/toulouse-fun"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".md"] }; -"fr/visited-links.md": { - id: "fr/visited-links.md"; - slug: "fr/visited-links"; - body: string; - collection: "fragments"; - data: InferEntrySchema<"fragments"> -} & { render(): Render[".md"] }; -}; -"references": { -"en/3w.md": { - id: "en/3w.md"; - slug: "en/3w"; - body: string; - collection: "references"; - data: InferEntrySchema<"references"> -} & { render(): Render[".md"] }; -"en/natureo.md": { - id: "en/natureo.md"; - slug: "en/natureo"; - body: string; - collection: "references"; - data: InferEntrySchema<"references"> -} & { render(): Render[".md"] }; -"en/parole-expression.md": { - id: "en/parole-expression.md"; - slug: "en/parole-expression"; - body: string; - collection: "references"; - data: InferEntrySchema<"references"> -} & { render(): Render[".md"] }; -"en/rose-primaire.md": { - id: "en/rose-primaire.md"; - slug: "en/rose-primaire"; - body: string; - collection: "references"; - data: InferEntrySchema<"references"> -} & { render(): Render[".md"] }; -"fr/3w.md": { - id: "fr/3w.md"; - slug: "fr/3w"; - body: string; - collection: "references"; - data: InferEntrySchema<"references"> -} & { render(): Render[".md"] }; -"fr/natureo.md": { - id: "fr/natureo.md"; - slug: "fr/natureo"; - body: string; - collection: "references"; - data: InferEntrySchema<"references"> -} & { render(): Render[".md"] }; -"fr/parole-expression.md": { - id: "fr/parole-expression.md"; - slug: "fr/parole-expression"; - body: string; - collection: "references"; - data: InferEntrySchema<"references"> -} & { render(): Render[".md"] }; -"fr/rose-primaire.md": { - id: "fr/rose-primaire.md"; - slug: "fr/rose-primaire"; - body: string; - collection: "references"; - data: InferEntrySchema<"references"> -} & { render(): Render[".md"] }; -}; - - }; - - type DataEntryMap = { - - }; - - type AnyEntryMap = ContentEntryMap & DataEntryMap; - - type ContentConfig = typeof import("../src/content/config"); -} +/// +/// \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 28ac688..5eb9746 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,8 @@ { - "editor.formatOnSave": true, - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.insertSpaces": false, - "editor.detectIndentation": false, - "editor.tabSize": 2 + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.insertSpaces": false, + "editor.detectIndentation": false, + "editor.tabSize": 2, + "astro.content-intellisense": true } diff --git a/package.json b/package.json index 01a8606..0157e68 100755 --- a/package.json +++ b/package.json @@ -1,30 +1,27 @@ { - "name": "@example/minimal", - "type": "module", - "version": "0.0.1", - "private": true, - "scripts": { - "dev": "astro-i18n sync && astro dev", - "start": "astro dev", - "build": "astro build", - "preview": "astro preview", - "astro": "astro", - "i18n:install": "astro-i18n install", - "i18n:sync": "astro-i18n sync" - }, - "dependencies": { - "@astrojs/mdx": "4.0.3", - "@astrojs/rss": "4.0.10", - "@astrojs/sitemap": "3.2.1", - "@astrojs/ts-plugin": "^1.10.4", - "astro": "5.1.1", - "sharp": "^0.33.5" - }, - "devDependencies": { - "autoprefixer": "^10.4.20", - "postcss": "^8.4.49", - "prettier": "^3.4.2", - "prettier-plugin-astro": "^0.14.1", - "prettier-plugin-organize-imports": "^4.1.0" - } + "name": "nardude", + "type": "module", + "version": "3.0.0", + "private": true, + "scripts": { + "dev": "astro dev", + "build": "astro build", + "preview": "astro preview", + "astro": "astro" + }, + "dependencies": { + "@astrojs/mdx": "4.0.3", + "@astrojs/rss": "4.0.10", + "@astrojs/sitemap": "3.2.1", + "@astrojs/ts-plugin": "^1.10.4", + "astro": "5.1.1", + "sharp": "^0.33.5" + }, + "devDependencies": { + "autoprefixer": "^10.4.20", + "postcss": "^8.4.49", + "prettier": "^3.4.2", + "prettier-plugin-astro": "^0.14.1", + "prettier-plugin-organize-imports": "^4.1.0" + } } diff --git a/src/components/AstroImage.astro b/src/components/AstroImage.astro index 4d6fbe0..64fdc49 100755 --- a/src/components/AstroImage.astro +++ b/src/components/AstroImage.astro @@ -1,45 +1,45 @@ --- -import { Image, getImage } from "astro:assets"; +import { Image, getImage } from 'astro:assets' -const { src, alt, width, height, ...attrs } = Astro.props; +const { src, alt, width, height, ...attrs } = Astro.props // if h/w attributes are declared, use them. If not, use from the source file -const imgHeight = height ? height : src.height; -const imgWidth = width ? width : src.width; +const imgHeight = height ? height : src.height +const imgWidth = width ? width : src.width // compute avif and webp format in order to use inside a element const imgAvif = await getImage({ src: src, - format: "avif", + format: 'avif', width: Number(imgWidth), - height: Number(imgHeight), -}); + height: Number(imgHeight) +}) const imgWebp = await getImage({ src: src, - format: "webp", + format: 'webp', // need Number() because sharp wants an integer and not a string for w/h width: Number(imgWidth), - height: Number(imgHeight), -}); + height: Number(imgHeight) +}) --- {alt diff --git a/src/components/CardEditorial.astro b/src/components/CardEditorial.astro index dcdfe3d..bd0da71 100755 --- a/src/components/CardEditorial.astro +++ b/src/components/CardEditorial.astro @@ -1,20 +1,19 @@ --- -import ListTags from "./ListTags.astro"; -import { l, t } from "astro-i18n"; +import ListTags from './ListTags.astro' -const { item, routeName } = Astro.props; +const { item, routeName } = Astro.props // no link on references cards -const isReference = routeName === t("references.slug"); +const isReference = routeName === 'references' --- -
      +

      { !isReference ? ( {item.data.title} @@ -27,15 +26,15 @@ const isReference = routeName === t("references.slug"); { isReference && ( - - {t("references.cta")} - {item.data.title} + + Consulter le site + {item.data.title} ) }

      - diff --git a/src/pages/rss.xml.js b/src/pages/rss.xml.js index 3d32fa2..f91a0b2 100755 --- a/src/pages/rss.xml.js +++ b/src/pages/rss.xml.js @@ -1,19 +1,19 @@ -import rss from "@astrojs/rss"; -import { getCollection } from "astro:content"; +import rss from '@astrojs/rss' +import { getCollection } from 'astro:content' export async function get(context) { - const articles = await getCollection("articles", ({ data }) => { - return data.lang === "fr" && !data.draft; - }); - const fragments = await getCollection("fragments", ({ data }) => { - return data.lang === "fr" && !data.draft; - }); - const posts = articles.concat(fragments); + const articles = await getCollection('articles', ({ data }) => { + return data.lang === 'fr' && !data.draft + }) + const fragments = await getCollection('fragments', ({ data }) => { + return data.lang === 'fr' && !data.draft + }) + const posts = articles.concat(fragments) return rss({ // `` field in output xml - title: "Nicolas Arduin", + title: 'Nicolas Arduin', // `<description>` field in output xml - description: "Articles publiés sur nardu.in", + description: 'Articles publiés sur nardu.in', // Pull in your project "site" from the endpoint context // https://docs.astro.build/en/reference/api-reference/#contextsite site: context.site, @@ -26,9 +26,9 @@ export async function get(context) { lang: post.data.lang, // Compute RSS link from post `slug` // This example assumes all posts are rendered as `/blog/[slug]` routes - link: `/${post.data.type}/${post.data.permalink}/`, + link: `/${post.data.type}/${post.data.slug}/` })), // (optional) inject custom xml - customData: `<language>fr-fr</language>`, - }); + customData: `<language>fr-fr</language>` + }) } -- 2.45.2 From 65c60033137513d153e01cacd8baa2a92f8bb1bd Mon Sep 17 00:00:00 2001 From: nico <contact@nardu.in> Date: Sun, 29 Dec 2024 14:49:35 +0100 Subject: [PATCH 04/16] better sitemap organization --- .astro/collections/articles.schema.json | 4 +- .astro/collections/fragments.schema.json | 4 +- .astro/collections/references.schema.json | 4 +- .astro/content-modules.mjs | 10 ++-- .astro/data-store.json | 2 +- .gitignore | 3 +- src/pages/plan-du-site.astro | 57 ++++++++++++++++++----- 7 files changed, 57 insertions(+), 27 deletions(-) diff --git a/.astro/collections/articles.schema.json b/.astro/collections/articles.schema.json index 209c616..622042f 100644 --- a/.astro/collections/articles.schema.json +++ b/.astro/collections/articles.schema.json @@ -26,7 +26,7 @@ "type": { "type": "string" }, - "permalink": { + "slug": { "type": "string" }, "createdAt": { @@ -51,7 +51,7 @@ "lang", "tags", "type", - "permalink", + "slug", "createdAt" ], "additionalProperties": false diff --git a/.astro/collections/fragments.schema.json b/.astro/collections/fragments.schema.json index 49c36ba..31e03c0 100644 --- a/.astro/collections/fragments.schema.json +++ b/.astro/collections/fragments.schema.json @@ -26,7 +26,7 @@ "type": { "type": "string" }, - "permalink": { + "slug": { "type": "string" }, "createdAt": { @@ -51,7 +51,7 @@ "lang", "tags", "type", - "permalink", + "slug", "createdAt" ], "additionalProperties": false diff --git a/.astro/collections/references.schema.json b/.astro/collections/references.schema.json index 2d437fe..c2f0c06 100644 --- a/.astro/collections/references.schema.json +++ b/.astro/collections/references.schema.json @@ -20,7 +20,7 @@ "en" ] }, - "permalink": { + "slug": { "type": "string" }, "tags": { @@ -50,7 +50,7 @@ "subtitle", "url", "lang", - "permalink", + "slug", "tags", "createdAt" ], diff --git a/.astro/content-modules.mjs b/.astro/content-modules.mjs index c0284e8..c4a699e 100644 --- a/.astro/content-modules.mjs +++ b/.astro/content-modules.mjs @@ -6,13 +6,9 @@ export default new Map([ ["src/content/articles/en/video-compression.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fvideo-compression.mdx&astroContentModuleFlag=true")], ["src/content/fragments/en/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fimage-full.mdx&astroContentModuleFlag=true")], ["src/content/fragments/en/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], -["src/content/fragments/fr/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fimage-full.mdx&astroContentModuleFlag=true")], -["src/content/fragments/fr/buttons.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fbuttons.mdx&astroContentModuleFlag=true")], ["src/content/articles/fr/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], -["src/content/fragments/fr/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], +["src/content/fragments/fr/buttons.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fbuttons.mdx&astroContentModuleFlag=true")], +["src/content/fragments/fr/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fimage-full.mdx&astroContentModuleFlag=true")], ["src/content/articles/fr/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], -["src/content/articles/en/en-after-effects-expressions.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fen-after-effects-expressions.mdx&astroContentModuleFlag=true")], -["src/content/articles/en/en-sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fen-sci-hub-blocage.mdx&astroContentModuleFlag=true")], -["src/content/articles/en/en-the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fen-the-day-I-jamd.mdx&astroContentModuleFlag=true")], -["src/content/articles/en/en-video-compression.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fen-video-compression.mdx&astroContentModuleFlag=true")]]); +["src/content/fragments/fr/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fsuper-cookies.mdx&astroContentModuleFlag=true")]]); \ No newline at end of file diff --git a/.astro/data-store.json b/.astro/data-store.json index 98a5c76..e65e8a3 100644 --- a/.astro/data-store.json +++ b/.astro/data-store.json @@ -1 +1 @@ -[["Map",1,2,9,10,61,62,173,174,189,190,655,656],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.1.1","content-config-digest","8021b3469f132349","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"site\":\"https://www.nardu.in\",\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[\"assets.nardu.in\"],\"remotePatterns\":[{\"protocol\":\"https\"}]},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":\"shiki\",\"shikiConfig\":{\"langs\":[],\"langAlias\":{\"bash\":\"shellscript\",\"sh\":\"shellscript\",\"shell\":\"shellscript\",\"zsh\":\"shellscript\",\"js\":\"javascript\",\"ts\":\"typescript\",\"gql\":\"graphql\"},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"i18n\":{\"defaultLocale\":\"fr\",\"locales\":[\"fr\",\"en\"],\"routing\":{\"prefixDefaultLocale\":false,\"redirectToDefaultLocale\":true,\"fallbackType\":\"redirect\"}},\"security\":{\"checkOrigin\":true},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"responsiveImages\":false},\"legacy\":{\"collections\":false}}","references",["Map",11,12,25,26,39,40,50,51],"3w",{"id":11,"data":13,"filePath":21,"digest":22,"rendered":23},{"title":11,"subtitle":14,"url":15,"lang":16,"slug":11,"tags":17,"createdAt":20},"J'ai fait de la doc!","https://3-w.fr","fr",[18,19],"Front-end","documentation",["Date","2022-10-19T18:02:00.000Z"],"src/content/references/3w.md","0d3d94c8af754e1b",{"html":24},"","natureo",{"id":25,"data":27,"filePath":36,"digest":37,"rendered":38},{"title":28,"subtitle":29,"url":30,"lang":16,"slug":25,"tags":31,"createdAt":35},"Nature en Occitanie","La sobriété au naturel.","https://www.natureo.org/",[18,32,33,34],"accessibilité","éco-conception","CMS",["Date","2023-04-19T18:02:00.000Z"],"src/content/references/natureo.md","6a7169b855b57024",{"html":24},"parole-expression",{"id":39,"data":41,"filePath":47,"digest":48,"rendered":49},{"title":42,"subtitle":43,"url":44,"lang":16,"slug":39,"tags":45,"createdAt":46},"Parole Expression","Un nouveau site pour l'association.","https://www.paroleexpression.fr/",[18,33,34],["Date","2022-04-19T17:11:00.000Z"],"src/content/references/parole-expression.md","ec95a408f8c3e99c",{"html":24},"rose-primaire",{"id":50,"data":52,"filePath":58,"digest":59,"rendered":60},{"title":53,"subtitle":54,"url":55,"lang":16,"slug":50,"tags":56,"createdAt":57},"Rose Primaire","Une agence comme on l'aime.","https://roseprimaire.com/",[18,32,33,34],["Date","2023-04-19T17:11:00.000Z"],"src/content/references/rose-primaire.md","a0133200cf1bee58",{"html":24},"HPsections",["Map",63,64,85,86,102,103,128,129,145,146],"011-offre",{"id":63,"data":65,"body":72,"filePath":73,"digest":74,"rendered":75},{"type":66,"lang":16,"uid":67,"image":68,"order":69,"quickTitle":70,"quickImage":71,"reference":39},"section","offre","/assets/images/home/offre-1.1.svg",1.1,"Mes offres en freelance","/assets/images/home/icon-desktop.svg","## L'offre site web classique\n\nCette offre est destinée à un public souhaitant **se doter d'un site web**, sans forcément intégrer l'accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du [référentiel général d'amélioration de l'accessibilité](https://accessibilite.numerique.gouv.fr/) (\u003Cabbr>RGAA\u003C/abbr>).\n\nL'objectif principal de cette offre étant d'**établir une présence en ligne** pour le client. Que cette dernière ait un but informatif et/ou éditorial.\n\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->","src/data/HP/011-offre.md","290ecd1ed94a1087",{"html":76,"metadata":77},"\u003Ch2 id=\"loffre-site-web-classique\">L’offre site web classique\u003C/h2>\n\u003Cp>Cette offre est destinée à un public souhaitant \u003Cstrong>se doter d’un site web\u003C/strong>, sans forcément intégrer l’accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du \u003Ca href=\"https://accessibilite.numerique.gouv.fr/\">référentiel général d’amélioration de l’accessibilité\u003C/a> (\u003Cabbr>RGAA\u003C/abbr>).\u003C/p>\n\u003Cp>L’objectif principal de cette offre étant d’\u003Cstrong>établir une présence en ligne\u003C/strong> pour le client. Que cette dernière ait un but informatif et/ou éditorial.\u003C/p>\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->",{"headings":78,"imagePaths":83,"frontmatter":84},[79],{"depth":80,"slug":81,"text":82},2,"loffre-site-web-classique","L’offre site web classique",[],{"type":66,"uid":67,"lang":16,"image":68,"order":69,"quickTitle":70,"quickImage":71,"reference":39},"012-offre",{"id":85,"data":87,"body":90,"filePath":91,"digest":92,"rendered":93},{"type":66,"lang":16,"image":88,"order":89,"reference":50},"/assets/images/home/offre-1.2.svg",1.2,"## L'offre accessibilité avancée\n\nCette offre s'adresse plus spécifiquement aux entités pour lesquelles **l'accessibilité du site est un critère majeur.** Qu'il s'agisse d'une création ou d'une mise en conformité après un audit d'accessibilité.\n\nLorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\n\n- [Rose Primaire](https://roseprimaire.com/) pour le conseil et l'accompagnement du projet ;\n- [Sylvain Plantier](https://jedessinebien.com/) et/ou [Benoît Etchevery](http://ben-etche.com/) pour l'illustration et la direction artistique.\n\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->","src/data/HP/012-offre.md","2a3bf3411b3c171b",{"html":94,"metadata":95},"\u003Ch2 id=\"loffre-accessibilité-avancée\">L’offre accessibilité avancée\u003C/h2>\n\u003Cp>Cette offre s’adresse plus spécifiquement aux entités pour lesquelles \u003Cstrong>l’accessibilité du site est un critère majeur.\u003C/strong> Qu’il s’agisse d’une création ou d’une mise en conformité après un audit d’accessibilité.\u003C/p>\n\u003Cp>Lorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://roseprimaire.com/\">Rose Primaire\u003C/a> pour le conseil et l’accompagnement du projet ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://jedessinebien.com/\">Sylvain Plantier\u003C/a> et/ou \u003Ca href=\"http://ben-etche.com/\">Benoît Etchevery\u003C/a> pour l’illustration et la direction artistique.\u003C/li>\n\u003C/ul>\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->",{"headings":96,"imagePaths":100,"frontmatter":101},[97],{"depth":80,"slug":98,"text":99},"loffre-accessibilité-avancée","L’offre accessibilité avancée",[],{"type":66,"lang":16,"order":89,"image":88,"reference":50},"020-methodo",{"id":102,"data":104,"body":109,"filePath":110,"digest":111,"rendered":112},{"type":66,"lang":16,"uid":105,"image":106,"order":80,"quickTitle":107,"quickImage":108},"methodology","/assets/images/home/methodo.svg","Ma méthodologie","/assets/images/home/icon-methodo.svg","## Méthodologie\n\n### Accessibilité par défaut\n\nEngagé pour un web plus accessible, je crée des **sites web** en m'appuyant sur le [référentiel général d'amélioration de l'accessibilité (RGAA)](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) ainsi que sur les bonnes pratiques [Opquast.](https://www.opquast.com/rendre-le-web-meilleur/)\n\n### Sobriété par choix\n\nJe privilégie le développement de **sites statiques** en adoptant une approche [d'éco-conception numérique.](https://eco-conception.designersethiques.org/guide/fr/) \nC'est-à-dire que le site est pensé pour n'embarquer que les fonctionnalités nécessaires à son utilisation.\n\nCette approche présente de **nombreux avantages :**\n\n- chargement rapide des pages ;\n- sécurité renforcée ;\n- coûts serveur réduits ;\n- maintenance facilitée.\n\nLorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l'interface. Cela permet de garantir que **le site reste en ligne** même si le CMS venait à ne plus fonctionner.","src/data/HP/020-methodo.md","75a09b4e0b1e926b",{"html":113,"metadata":114},"\u003Ch2 id=\"méthodologie\">Méthodologie\u003C/h2>\n\u003Ch3 id=\"accessibilité-par-défaut\">Accessibilité par défaut\u003C/h3>\n\u003Cp>Engagé pour un web plus accessible, je crée des \u003Cstrong>sites web\u003C/strong> en m’appuyant sur le \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité (RGAA)\u003C/a> ainsi que sur les bonnes pratiques \u003Ca href=\"https://www.opquast.com/rendre-le-web-meilleur/\">Opquast.\u003C/a>\u003C/p>\n\u003Ch3 id=\"sobriété-par-choix\">Sobriété par choix\u003C/h3>\n\u003Cp>Je privilégie le développement de \u003Cstrong>sites statiques\u003C/strong> en adoptant une approche \u003Ca href=\"https://eco-conception.designersethiques.org/guide/fr/\">d’éco-conception numérique.\u003C/a>\u003Cbr>\nC’est-à-dire que le site est pensé pour n’embarquer que les fonctionnalités nécessaires à son utilisation.\u003C/p>\n\u003Cp>Cette approche présente de \u003Cstrong>nombreux avantages :\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>chargement rapide des pages ;\u003C/li>\n\u003Cli>sécurité renforcée ;\u003C/li>\n\u003Cli>coûts serveur réduits ;\u003C/li>\n\u003Cli>maintenance facilitée.\u003C/li>\n\u003C/ul>\n\u003Cp>Lorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l’interface. Cela permet de garantir que \u003Cstrong>le site reste en ligne\u003C/strong> même si le CMS venait à ne plus fonctionner.\u003C/p>",{"headings":115,"imagePaths":126,"frontmatter":127},[116,119,123],{"depth":80,"slug":117,"text":118},"méthodologie","Méthodologie",{"depth":120,"slug":121,"text":122},3,"accessibilité-par-défaut","Accessibilité par défaut",{"depth":120,"slug":124,"text":125},"sobriété-par-choix","Sobriété par choix",[],{"type":66,"uid":105,"lang":16,"image":106,"order":80,"quickTitle":107,"quickImage":108},"013-offre",{"id":128,"data":130,"body":133,"filePath":134,"digest":135,"rendered":136},{"type":66,"lang":16,"image":131,"order":132},"/assets/images/home/offre-1.3.svg",1.3,"## Et l'éco-conception alors ?\n\nJe ne conçois pas l'éco-conception comme une offre. C'est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l'éco-conception sans accessibilité, j'applique donc ces méthodologies quelque soit le projet !","src/data/HP/013-offre.md","03e37f364ac27cb4",{"html":137,"metadata":138},"\u003Ch2 id=\"et-léco-conception-alors\">Et l’éco-conception alors ?\u003C/h2>\n\u003Cp>Je ne conçois pas l’éco-conception comme une offre. C’est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l’éco-conception sans accessibilité, j’applique donc ces méthodologies quelque soit le projet !\u003C/p>",{"headings":139,"imagePaths":143,"frontmatter":144},[140],{"depth":80,"slug":141,"text":142},"et-léco-conception-alors","Et l’éco-conception alors ?",[],{"type":66,"lang":16,"order":132,"image":131},"030-about",{"id":145,"data":147,"body":152,"filePath":153,"digest":154,"rendered":155},{"type":66,"lang":16,"uid":148,"image":149,"order":120,"quickTitle":150,"quickImage":151},"about","/assets/images/home/about.svg","Moi","/assets/images/home/icon-heart.svg","## À propos\n\n### Formations personnelles\n\nAfin de solidifier mes compétences, j'ai suivi les formations et passé les certifications suivantes :\n\n- [Opquast](https://directory.opquast.com/fr/certificat/CTQSKP/) - Maîtrise de la qualité en projet web ;\n- Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\n\n### Formations des autres\n\nDepuis plusieurs années, j'interviens dans différents campus afin de dispenser des cours de développement web.\n\n### Temps libre\n\nJ’essaie de contribuer à des [projets open source](https://git.nardu.in/explore/repos) qui me tiennent à cœur et je m'engage localement avec le collectif [good-it!](https://www.good-it.org/)\n\nAh et j’écris [des articles](/articles) aussi ! Des articles sur le design, le développement web et l’informatique.","src/data/HP/030-about.md","a7abff6d744406ce",{"html":156,"metadata":157},"\u003Ch2 id=\"à-propos\">À propos\u003C/h2>\n\u003Ch3 id=\"formations-personnelles\">Formations personnelles\u003C/h3>\n\u003Cp>Afin de solidifier mes compétences, j’ai suivi les formations et passé les certifications suivantes :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://directory.opquast.com/fr/certificat/CTQSKP/\">Opquast\u003C/a> - Maîtrise de la qualité en projet web ;\u003C/li>\n\u003Cli>Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"formations-des-autres\">Formations des autres\u003C/h3>\n\u003Cp>Depuis plusieurs années, j’interviens dans différents campus afin de dispenser des cours de développement web.\u003C/p>\n\u003Ch3 id=\"temps-libre\">Temps libre\u003C/h3>\n\u003Cp>J’essaie de contribuer à des \u003Ca href=\"https://git.nardu.in/explore/repos\">projets open source\u003C/a> qui me tiennent à cœur et je m’engage localement avec le collectif \u003Ca href=\"https://www.good-it.org/\">good-it!\u003C/a>\u003C/p>\n\u003Cp>Ah et j’écris \u003Ca href=\"/articles\">des articles\u003C/a> aussi ! Des articles sur le design, le développement web et l’informatique.\u003C/p>",{"headings":158,"imagePaths":171,"frontmatter":172},[159,162,165,168],{"depth":80,"slug":160,"text":161},"à-propos","À propos",{"depth":120,"slug":163,"text":164},"formations-personnelles","Formations personnelles",{"depth":120,"slug":166,"text":167},"formations-des-autres","Formations des autres",{"depth":120,"slug":169,"text":170},"temps-libre","Temps libre",[],{"type":66,"uid":148,"lang":16,"image":149,"order":120,"quickTitle":150,"quickImage":151},"veille",["Map",175,176],"2023",{"id":175,"data":177,"body":179,"filePath":180,"digest":181,"rendered":182},{"lang":16,"title":175,"updatedAt":178},["Date","2023-04-20T17:12:06.000Z"],"- [mmm.page](https://build.mmm.page/) - Éditeur de sites web très simples, en glisser-déposer, pour n'importe quoi.\n- [Color.io](https://www.color.io/) - Éditeur photo en ligne.\n- [Addy's toolkit](https://toolkit.addy.codes/) - Outils et ressources pour les designers et développeurs sites web.\n- [L’accessibilité n’est pas une variable d’ajustement](https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/) — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n > L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\n- [3D en CSS (english)](https://garden.bradwoods.io/notes/css/3d) – Explications et exemples des propriétés 3D en CSS.\n- [Climat : Comment ne pas déprimer ?](https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html) – Podcast.\n- [Fable (english)](https://fable.app) – Application de motion design.\n- [Rive (english)](https://rive.app) – Application de motion design.\n- [Cake Desk](https://cakedesk.app/) – Application de facturation.\n- [Ombre fluide en CSS](https://shadows.brumm.af/) – Générateur.\n- [Smol CSS](https://smolcss.dev/) – Collection de fragments CSS.\n- [Ajustement optique](https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/) (english) – Aligner visuellement plutôt que techniquement.\n- [Datawrapper](https://blog.datawrapper.de/category/datavis-dos-and-donts/) (english) – Conseils pour montrer de la donnée.\n- [Assistivlabs](https://assistivlabs.com/) (english) – Service de test des technologies d'assistance (browserstack mais pour l'accessibilité).\n- [Les caractères fantaisistes et l'accessibilité](https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/) – Explications et exemples de l'enfer que sont les caractères Unicode pour les technologies d'assistance.\n- [Créer un champ `time` sur le web](https://adamsilver.io/blog/designing-a-time-input-backed-by-research/) (english) – Article.\n- [La cascade](https://la-cascade.io) – Collection d'articles sur le CSS.\n- [Tabby](https://tabby.sh) (english) – An alternative terminal app.\n- [Newglyph](https://newglyph.com/) – Fonderie indépendante.\n- [\u003Cspan lang=\"en\">Headless UI\u003C/span>](https://headlessui.com/vue/dialog) (english) – Librairie de composants vue et react.\n- [Vie privée sexy](https://privacy.sexy) (english) – Outils de confidentialité pour windows et macos.\n- [33 concepts JavaScript](https://github.com/leonardomso/33-js-concepts) (english) – Articles.\n- [Formbricks](https://formbricks.com/) (english) – Alternative open source à google form/typeform.\n- [Animations de chargement SVG](https://github.com/n3r4zzurr0/svg-spinners) – Collection.\n- [a11yphant](https://a11yphant.com/) (english) – Challenges de code pour apprendre l'accessibilité.\n- [CSS moderne](https://moderncss.dev/) (english) – Fragments CSS.\n- [Conteneur moderne en CSS](https://twitter.com/KevinJPowell/status/1501555193799925761) (english) – Tweet de Kevin Powell ❤️","src/data/veille/2023.md","1135beec386f207f",{"html":183,"metadata":184},"\u003Cul>\n\u003Cli>\u003Ca href=\"https://build.mmm.page/\">mmm.page\u003C/a> - Éditeur de sites web très simples, en glisser-déposer, pour n’importe quoi.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.color.io/\">Color.io\u003C/a> - Éditeur photo en ligne.\u003C/li>\n\u003Cli>\u003Ca href=\"https://toolkit.addy.codes/\">Addy’s toolkit\u003C/a> - Outils et ressources pour les designers et développeurs sites web.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/\">L’accessibilité n’est pas une variable d’ajustement\u003C/a> — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n\u003Cblockquote>\n\u003Cp>L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\u003C/p>\n\u003C/blockquote>\n\u003C/li>\n\u003Cli>\u003Ca href=\"https://garden.bradwoods.io/notes/css/3d\">3D en CSS (english)\u003C/a> – Explications et exemples des propriétés 3D en CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html\">Climat : Comment ne pas déprimer ?\u003C/a> – Podcast.\u003C/li>\n\u003Cli>\u003Ca href=\"https://fable.app\">Fable (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://rive.app\">Rive (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://cakedesk.app/\">Cake Desk\u003C/a> – Application de facturation.\u003C/li>\n\u003Cli>\u003Ca href=\"https://shadows.brumm.af/\">Ombre fluide en CSS\u003C/a> – Générateur.\u003C/li>\n\u003Cli>\u003Ca href=\"https://smolcss.dev/\">Smol CSS\u003C/a> – Collection de fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/\">Ajustement optique\u003C/a> (english) – Aligner visuellement plutôt que techniquement.\u003C/li>\n\u003Cli>\u003Ca href=\"https://blog.datawrapper.de/category/datavis-dos-and-donts/\">Datawrapper\u003C/a> (english) – Conseils pour montrer de la donnée.\u003C/li>\n\u003Cli>\u003Ca href=\"https://assistivlabs.com/\">Assistivlabs\u003C/a> (english) – Service de test des technologies d’assistance (browserstack mais pour l’accessibilité).\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/\">Les caractères fantaisistes et l’accessibilité\u003C/a> – Explications et exemples de l’enfer que sont les caractères Unicode pour les technologies d’assistance.\u003C/li>\n\u003Cli>\u003Ca href=\"https://adamsilver.io/blog/designing-a-time-input-backed-by-research/\">Créer un champ \u003Ccode>time\u003C/code> sur le web\u003C/a> (english) – Article.\u003C/li>\n\u003Cli>\u003Ca href=\"https://la-cascade.io\">La cascade\u003C/a> – Collection d’articles sur le CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://tabby.sh\">Tabby\u003C/a> (english) – An alternative terminal app.\u003C/li>\n\u003Cli>\u003Ca href=\"https://newglyph.com/\">Newglyph\u003C/a> – Fonderie indépendante.\u003C/li>\n\u003Cli>\u003Ca href=\"https://headlessui.com/vue/dialog\">\u003Cspan lang=\"en\">Headless UI\u003C/span>\u003C/a> (english) – Librairie de composants vue et react.\u003C/li>\n\u003Cli>\u003Ca href=\"https://privacy.sexy\">Vie privée sexy\u003C/a> (english) – Outils de confidentialité pour windows et macos.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/leonardomso/33-js-concepts\">33 concepts JavaScript\u003C/a> (english) – Articles.\u003C/li>\n\u003Cli>\u003Ca href=\"https://formbricks.com/\">Formbricks\u003C/a> (english) – Alternative open source à google form/typeform.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/n3r4zzurr0/svg-spinners\">Animations de chargement SVG\u003C/a> – Collection.\u003C/li>\n\u003Cli>\u003Ca href=\"https://a11yphant.com/\">a11yphant\u003C/a> (english) – Challenges de code pour apprendre l’accessibilité.\u003C/li>\n\u003Cli>\u003Ca href=\"https://moderncss.dev/\">CSS moderne\u003C/a> (english) – Fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/KevinJPowell/status/1501555193799925761\">Conteneur moderne en CSS\u003C/a> (english) – Tweet de Kevin Powell ❤️\u003C/li>\n\u003C/ul>",{"headings":185,"imagePaths":186,"frontmatter":187},[],[],{"lang":16,"title":175,"updatedAt":188},"2023-04-20T17:12:06.000Z","fragments",["Map",191,192,256,257,275,276,286,287,297,298,339,340,350,351,366,367,404,405,467,468,491,492,525,526,536,537,576,577,587,588,640,641],"acme-sh-tls-cert",{"id":191,"data":193,"body":199,"filePath":200,"digest":201,"rendered":202},{"title":194,"subtitle":195,"lang":16,"tags":196,"type":189,"slug":191,"createdAt":198},"Certificates TLS robustes avec acme.sh","384-bit de https",[197],"sécurité",["Date","2022-06-08T14:24:06.000Z"],"## Attention\n\nJe ne suis pas du tout un expert en sécurité. J'aime juste les trucs nouveaux et stylés des internets. \nC'est pourquoi j'ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J'ai maintenant un joli 100/100 sur [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nVous pouvez en apprendre (beaucoup) plus [ici](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) et sur les liens cités (en anglais).\n\n## Prérequis\n\n### Installer acme.sh\n\nPour des raisons de simplicité et d'automatisation, j'utilise [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changer l'authorité par défaut\n\nPar défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let's Encrypt car, d'après acme.sh, ils sont les seuls à proposer des certificats ECC.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Utiliser l'api DNS\n\nSi vous en avez la possibilité, la façon la plus simple de générer un certificat est via l'api de votre fournisseur DNS. acme.sh supporte [énormément](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) de fournisseurs DNS.\n\n### Definir la clé api\n\nSuivez la [documentation](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) pour votre fournisseur DNS, généralement:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Émettre le certificat\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Utiliser le mode standalone\n\nSi vous n'avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s'occupe de toutes les vérifications.\n\nLe port `80` doit être disponible.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Exemples\n\n### Multi domaines standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domaine DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Étapes supplémentaires\n\nLe certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\n\n### Version TLS\n\nLimiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu [la différence de compatibilité de 5%](https://caniuse.com/?search=tls%201.) avec 1.2).\n\n### HSTS\n\nUtiliser le header [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/).\n\n```\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Suite cryptographique\n\nUtiliser une suite cryptographique récente et robuste. C'est ici que mes connaissances deviennent limitées… J'ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\n\nJ'avais basé ma première suite sur [cette liste](https://tls.imirhil.fr/ciphers), en la comparant avec celle de la compatibilité (d'anciens ?) [navigateurs](https://tls.imirhil.fr/suite).\n\nJ'ai ensuite demandé à [Aeris](https://twitter.com/aeris22), le créateur de [tls.imirhil.fr](https://tls.imirhil.fr), ses conseils sur cette suite. Il m'a recommandé d'utiliser :\n\n```\nECDHE+AES:ECDHE+CHACHA20\n```\n\nAfin d'atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\n\n```\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/fr/acme-sh-tls-cert.md","82e6d91747c28ea5",{"html":203,"metadata":204},"\u003Ch2 id=\"attention\">Attention\u003C/h2>\n\u003Cp>Je ne suis pas du tout un expert en sécurité. J’aime juste les trucs nouveaux et stylés des internets.\u003Cbr>\nC’est pourquoi j’ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J’ai maintenant un joli 100/100 sur \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>Vous pouvez en apprendre (beaucoup) plus \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">ici\u003C/a> et sur les liens cités (en anglais).\u003C/p>\n\u003Ch2 id=\"prérequis\">Prérequis\u003C/h2>\n\u003Ch3 id=\"installer-acmesh\">Installer acme.sh\u003C/h3>\n\u003Cp>Pour des raisons de simplicité et d’automatisation, j’utilise \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">curl\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> https://get.acme.sh\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#B392F0\"> sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -s\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> email=mail@domain.tld\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"changer-lauthorité-par-défaut\">Changer l’authorité par défaut\u003C/h3>\n\u003Cp>Par défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let’s Encrypt car, d’après acme.sh, ils sont les seuls à proposer des certificats ECC.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --set-default-ca\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --server\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> letsencrypt\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"utiliser-lapi-dns\">Utiliser l’api DNS\u003C/h2>\n\u003Cp>Si vous en avez la possibilité, la façon la plus simple de générer un certificat est via l’api de votre fournisseur DNS. acme.sh supporte \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">énormément\u003C/a> de fournisseurs DNS.\u003C/p>\n\u003Ch3 id=\"definir-la-clé-api\">Definir la clé api\u003C/h3>\n\u003Cp>Suivez la \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">documentation\u003C/a> pour votre fournisseur DNS, généralement:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">export\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> PROVIDER_Key\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"YOUR_API_KEY\"\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"émettre-le-certificat\">Émettre le certificat\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"utiliser-le-mode-standalone\">Utiliser le mode standalone\u003C/h2>\n\u003Cp>Si vous n’avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s’occupe de toutes les vérifications.\u003C/p>\n\u003Cp>Le port \u003Ccode>80\u003C/code> doit être disponible.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"exemples\">Exemples\u003C/h2>\n\u003Ch3 id=\"multi-domaines-standalone\">Multi domaines standalone\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> www.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> subdomain.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"wildcard-domaine-dns\">Wildcard domaine DNS\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '*.domain.tld'\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"étapes-supplémentaires\">Étapes supplémentaires\u003C/h2>\n\u003Cp>Le certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\u003C/p>\n\u003Ch3 id=\"version-tls\">Version TLS\u003C/h3>\n\u003Cp>Limiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu \u003Ca href=\"https://caniuse.com/?search=tls%201.\">la différence de compatibilité de 5%\u003C/a> avec 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Utiliser le header \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a>.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>Strict-Transport-Security: max-age=31536000; includeSubDomains\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"suite-cryptographique\">Suite cryptographique\u003C/h3>\n\u003Cp>Utiliser une suite cryptographique récente et robuste. C’est ici que mes connaissances deviennent limitées… J’ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\u003C/p>\n\u003Cp>J’avais basé ma première suite sur \u003Ca href=\"https://tls.imirhil.fr/ciphers\">cette liste\u003C/a>, en la comparant avec celle de la compatibilité (d’anciens ?) \u003Ca href=\"https://tls.imirhil.fr/suite\">navigateurs\u003C/a>.\u003C/p>\n\u003Cp>J’ai ensuite demandé à \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, le créateur de \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, ses conseils sur cette suite. Il m’a recommandé d’utiliser :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Afin d’atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES256:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":205,"imagePaths":251,"frontmatter":252},[206,209,212,215,218,221,224,227,230,233,236,239,242,245,248],{"depth":80,"slug":207,"text":208},"attention","Attention",{"depth":80,"slug":210,"text":211},"prérequis","Prérequis",{"depth":120,"slug":213,"text":214},"installer-acmesh","Installer acme.sh",{"depth":120,"slug":216,"text":217},"changer-lauthorité-par-défaut","Changer l’authorité par défaut",{"depth":80,"slug":219,"text":220},"utiliser-lapi-dns","Utiliser l’api DNS",{"depth":120,"slug":222,"text":223},"definir-la-clé-api","Definir la clé api",{"depth":120,"slug":225,"text":226},"émettre-le-certificat","Émettre le certificat",{"depth":80,"slug":228,"text":229},"utiliser-le-mode-standalone","Utiliser le mode standalone",{"depth":80,"slug":231,"text":232},"exemples","Exemples",{"depth":120,"slug":234,"text":235},"multi-domaines-standalone","Multi domaines standalone",{"depth":120,"slug":237,"text":238},"wildcard-domaine-dns","Wildcard domaine DNS",{"depth":80,"slug":240,"text":241},"étapes-supplémentaires","Étapes supplémentaires",{"depth":120,"slug":243,"text":244},"version-tls","Version TLS",{"depth":120,"slug":246,"text":247},"hsts","HSTS",{"depth":120,"slug":249,"text":250},"suite-cryptographique","Suite cryptographique",[],{"title":194,"subtitle":195,"lang":16,"slug":191,"createdAt":253,"excerpt":254,"tags":255,"type":189},"2022-06-08T14:24:06.000Z","La sécurité avec des courbes.",[197],"array-vs-array",{"id":256,"data":258,"body":265,"filePath":266,"digest":267,"rendered":268},{"title":259,"subtitle":260,"lang":16,"tags":261,"type":189,"slug":256,"createdAt":263,"draft":264},"Filtrer un array avec un autre array","En cours de traduction.",[262],"nuxt.js",["Date","2022-06-08T14:24:06.000Z"],true,"[Voir les fragments disponibles](/fragments)","src/content/fragments/fr/array-vs-array.md","7321d444177c3841",{"html":269,"metadata":270},"\u003Cp>\u003Ca href=\"/fragments\">Voir les fragments disponibles\u003C/a>\u003C/p>",{"headings":271,"imagePaths":272,"frontmatter":273},[],[],{"title":259,"subtitle":260,"lang":16,"draft":264,"slug":256,"createdAt":253,"excerpt":260,"tags":274,"type":189},[262],"buttons",{"id":275,"data":277,"body":283,"filePath":284,"digest":285,"deferredRender":264},{"title":278,"subtitle":279,"lang":16,"tags":280,"type":189,"slug":275,"createdAt":282,"code":264,"draft":264},"Effets de survol de boutons","Simples mais efficaces.",[281],"CSS",["Date","2020-10-08T09:00:00.000Z"],"## Styles généraux\n\nTous les boutons présents utilisent ces styles comme base en guise de « reset » :\n\n> N'oubliez pas de préfixer si besoin !\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Ajout d'icône\n\n\u003Cbutton role='none' class='btn btn-icon'>\n\t\u003Cspan>Icône\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('./assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double volet\n\n\u003Cbutton role='none' class='btn btn-rideau'>\n\t\u003Cspan>Volet\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Dégradé animé\n\n\u003Cbutton role='none' class='btn btn-gradient'>\n\t\u003Cspan>Dégradé\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Échelle non desctructrice\n\n\u003Cbutton role='none' class='btn btn-scale'>\n\t\u003Cspan>Échelle\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/fr/buttons.mdx","f5d7b03520f96b04","image-full",{"id":286,"data":288,"body":294,"filePath":295,"digest":296,"deferredRender":264},{"title":289,"subtitle":290,"lang":16,"tags":291,"type":189,"slug":286,"createdAt":292,"updatedAt":293},"Image pleine largeur","Casser le conteneur.",[281],["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Image inline\n\nOn est parfois obligé d'utiliser des images dans des balises `img` plutôt que dans un `background` en css. Comment faire alors pour que l'image sorte de son conteneur pour en faire une bannière ? Exemple pratique à partir de ce même site.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_container_9e3939b3ae.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Contexte\n\nConsidérons le html suivant :\n\n```html\n\u003Csection class=\"container\">\n\t\u003Cdiv class=\"hero\">\n\t\t\u003Cimg class=\"hero__image\" src=\"hero.img\" />\n\t\u003C/div>\n\u003C/section>\n```\n\nEt le style suivant :\n\n```css\n.container {\n\tpadding: 0 14px;\n\tmargin-left: auto;\n\tmargin-right: auto;\n\tmax-width: 1040px;\n}\nimg {\n\tmax-width: 100%;\n\theight: auto;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_original_d49f0d11bf.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Déborder du conteneur\n\nAfin de faire prendre à l'image toute la largeur, on agit sur son conteneur :\n\n```css\n.hero {\n\tmargin-left: calc(50% - 50vw);\n\tposition: relative;\n\twidth: 100vw;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_full_2a902f9539.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Faire une bannière\n\nOn peut alors réduire la hauteur du conteneur pour obtenir une bannière plutôt que l'image entière et faire correspondre la hauteur de l'image à la hauteur du conteneur :\n\n```css\n.hero {\n\theight: 200px;\n}\n.hero__image {\n\theight: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_height_81b4ce969a.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nIl faut ensuite forcer l'image à prendre toute la largeur du conteneur :\n\n```css\n.hero__image {\n\twidth: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_deformed_479046d2cb.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nPas top…\n\n### J'ai cassé l'image…\n\n**ENFIN** le code magique pour redonner son ratio à l'image sans la déformer :\n\n```css\n.hero__image {\n\tobject-fit: cover;\n\tobject-position: center; /* à positionner comme on veut */\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_6c164e82b3.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nCette technique s'apparente à l'utilisation d'une image de background mais en dur 😁\n\n## TL;DR\n\nLe code complet :\n\n```css\n.hero {\n\tmargin-left: calc(50% - 50vw);\n\tposition: relative;\n\twidth: 100vw;\n\theight: 200px;\n}\n.hero__image {\n\twidth: 100%;\n\theight: 100%;\n\t-o-object-fit: cover;\n\tobject-fit: cover;\n\t-o-object-position: center;\n\tobject-position: center;\n}\n```","src/content/fragments/fr/image-full.mdx","91ebd97eef5cb8a4","nuxt-graphql-static",{"id":297,"data":299,"body":305,"filePath":306,"digest":307,"rendered":308},{"title":300,"subtitle":301,"lang":16,"tags":302,"type":189,"slug":297,"createdAt":303,"updatedAt":304},"Site statique et requêtes GraphQL avec Nuxt.js","Le client graphql est roi.",[262],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## Le problème\n\nJe me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (nouvel onglet)').\nAprès quelques recherches, voici [le bug constaté par quelqu'un d'autre](https://github.com/nuxt-community/apollo-module/issues/339 'Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)') sur github.\n\nIl semblerait que le module en l'état ne gère pas correctement la génération statique avec `nuxt generate`.\n\nJe trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les `\u003Cnuxt-link>` ne fonctionnait pas.\n\n## La solution 🙌\n\nHeureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\n\n[Nuxt graphql request à la rescousse !](https://github.com/gomah/nuxt-graphql-request 'Dépôt github du module (nouvel onglet)')\n\n### La conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### La requête\n\nLa meilleure méthode à ce jour est d'utiliser `asyncData` dans les pages et `fetch` dans les composants. Utiliser `fetch` dans les pages ne fonctionne pas bien du tout avec `nuxt generate`.\n\nJ'installe également le paquet `graphql-tag` (uniquement en `devDependencies`) afin de pouvoir importer directement des fichiers `.gql`\n\nExemple de fichier :\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Dans une page\n\n```javascript\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n async asyncData({ $graphql }) {\n const data = await $graphql.default.request(homepageQuery)\n return { data }\n },\n}\n\u003C/script>\n```\n\n#### Dans un composant\n\nIl est plus prudent d'attendre que `fetch` ait reçu une réponse avant d'afficher quoi que ce soit. On peut utiliser `$fetchState` afin d'être tranquille ([documentation](https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation sur la méthode fetch (nouvel onglet)')).\n\n```javascript\n// Header.vue\n\u003Ctemplate>\n \u003Cheader v-if=\"!$fetchState.pending\">\n …\n \u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n data() {\n return {\n data: {},\n }\n },\n async fetch() {\n try {\n const data = await this.$graphql.default.request(headerQuery)\n this.data = data\n } catch (error) {\n console.error(JSON.stringify(error, undefined, 2))\n }\n },\n}\n\u003C/script>\n```\n\n### Les options\n\nPour passer des options à la requête, par exemple pour une version multilingue avec [nuxt/i18n](https://i18n.nuxtjs.org/ 'Documentation de nuxt i18n (nouvel onglet)') et/ou un paramètre d'url dans le cadre d'une page dynamique :\n\n```javascript\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n async asyncData({ $graphql, app, params }) {\n const locale = app.i18n.localeProperties.iso\n const data = await $graphql.default.request(articleQuery, {\n code: locale,\n slug: params.slug,\n })\n return { data }\n },\n}\n\u003C/script>\n```","src/content/fragments/fr/nuxt-graphql-static.md","73b6cc6b4fed04f5",{"html":309,"metadata":310},"\u003Ch2 id=\"le-problème\">Le problème\u003C/h2>\n\u003Cp>Je me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (nouvel onglet)\">nuxt apollo\u003C/a>.\nAprès quelques recherches, voici \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)\">le bug constaté par quelqu’un d’autre\u003C/a> sur github.\u003C/p>\n\u003Cp>Il semblerait que le module en l’état ne gère pas correctement la génération statique avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>Je trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les \u003Ccode><nuxt-link>\u003C/code> ne fonctionnait pas.\u003C/p>\n\u003Ch2 id=\"la-solution\">La solution 🙌\u003C/h2>\n\u003Cp>Heureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\" title=\"Dépôt github du module (nouvel onglet)\">Nuxt graphql request à la rescousse !\u003C/a>\u003C/p>\n\u003Ch3 id=\"la-conf\">La conf\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// nuxt.config.js\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">buildModules\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\"> 'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">graphql\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> clients\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> default\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> endpoint: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> options: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> headers: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> authorization: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">},\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"la-requête\">La requête\u003C/h3>\n\u003Cp>La meilleure méthode à ce jour est d’utiliser \u003Ccode>asyncData\u003C/code> dans les pages et \u003Ccode>fetch\u003C/code> dans les composants. Utiliser \u003Ccode>fetch\u003C/code> dans les pages ne fonctionne pas bien du tout avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>J’installe également le paquet \u003Ccode>graphql-tag\u003C/code> (uniquement en \u003Ccode>devDependencies\u003C/code>) afin de pouvoir importer directement des fichiers \u003Ccode>.gql\u003C/code>\u003C/p>\n\u003Cp>Exemple de fichier :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"graphql\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># homepage.gql\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">query\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\thomepage\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\ttitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\tsubtitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\thero\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\tid\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\talt\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"dans-une-page\">Dans une page\u003C/h4>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import homepageQuery from '~/graphql/queries/singles/homepage'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(homepageQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"dans-un-composant\">Dans un composant\u003C/h4>\n\u003Cp>Il est plus prudent d’attendre que \u003Ccode>fetch\u003C/code> ait reçu une réponse avant d’afficher quoi que ce soit. On peut utiliser \u003Ccode>$fetchState\u003C/code> afin d’être tranquille (\u003Ca href=\"https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation sur la méthode fetch (nouvel onglet)\">documentation\u003C/a>).\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// Header.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> <\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#B392F0\"> v-if\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"!$fetchState.pending\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> …\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> </\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import headerQuery from '~/graphql/queries/singles/header'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">fetch\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> try {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> data\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.$graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(headerQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> data\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> } catch (error) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> console.\u003C/span>\u003Cspan style=\"color:#B392F0\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(JSON.stringify(\u003C/span>\u003Cspan style=\"color:#FFAB70\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">undefined\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, 2))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"les-options\">Les options\u003C/h3>\n\u003Cp>Pour passer des options à la requête, par exemple pour une version multilingue avec \u003Ca href=\"https://i18n.nuxtjs.org/\" title=\"Documentation de nuxt i18n (nouvel onglet)\">nuxt/i18n\u003C/a> et/ou un paramètre d’url dans le cadre d’une page dynamique :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// _slug.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import articleQuery from '~/graphql/queries/articles'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql, app, params }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const locale \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> app.i18n.localeProperties.iso\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(articleQuery, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> code: locale,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> slug: params.slug,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> })\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":311,"imagePaths":334,"frontmatter":335},[312,315,318,321,324,328,331],{"depth":80,"slug":313,"text":314},"le-problème","Le problème",{"depth":80,"slug":316,"text":317},"la-solution","La solution 🙌",{"depth":120,"slug":319,"text":320},"la-conf","La conf",{"depth":120,"slug":322,"text":323},"la-requête","La requête",{"depth":325,"slug":326,"text":327},4,"dans-une-page","Dans une page",{"depth":325,"slug":329,"text":330},"dans-un-composant","Dans un composant",{"depth":120,"slug":332,"text":333},"les-options","Les options",[],{"title":300,"subtitle":301,"lang":16,"slug":297,"createdAt":253,"updatedAt":336,"excerpt":337,"tags":338,"type":189},"2022-09-08T13:43:33.000Z","Quand le module gql le plus utilisé ne fonctionne pas…",[262],"super-cookies",{"id":339,"data":341,"body":347,"filePath":348,"digest":349,"deferredRender":264},{"title":342,"subtitle":343,"lang":16,"tags":344,"type":189,"slug":339,"createdAt":346},"Les meilleurs cookies","Des gâteaux sans consentement.",[345],"cuisine",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Version végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 3/4 de l'aquafaba de 400g de pois chiche (l'eau des pois chiche)\n- 125 grammes d'huile de noix de coco\n- 2 cuillères à café de sirop d'érable\n- 1 plaquette de chocolat (noir) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre si besoin l'huile de noix de coco à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (huile, aquafaba, sirop d'érable)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Version non végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 1 œuf\n- 125 grammes de beurre fondu\n- 2 cuillères à café de miel\n- 1 plaquette de chocolat (noir/blanc/les deux) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre le beurre à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (beurre fondu, œuf, miel)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Notes\n\nLe chocolat peut-être remplacé par n'importe quoi comme des noix, des raisins secs, des légos… (mangez pas des légos soyez sérieux).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Tous les ingrédients mélangés forment une pâte marron.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Les cookies cuits sont bombés et très moelleux.'\n/>","src/content/fragments/fr/super-cookies.mdx","f7a802e0b68cb04a","toulouse-fun",{"id":350,"data":352,"body":265,"filePath":357,"digest":358,"rendered":359},{"title":353,"subtitle":260,"lang":16,"tags":354,"type":189,"slug":350,"createdAt":356,"draft":264},"Toulouse yourself",[355],"lifestyle",["Date","2022-06-22T15:34:45.000Z"],"src/content/fragments/fr/toulouse-fun.md","a0c25b438b34c05e",{"html":269,"metadata":360},{"headings":361,"imagePaths":362,"frontmatter":363},[],[],{"title":353,"subtitle":260,"lang":16,"draft":264,"slug":350,"createdAt":364,"excerpt":260,"tags":365,"type":189},"2022-06-22T15:34:45.000Z",[355],"visited-links",{"id":366,"data":368,"body":375,"filePath":376,"digest":377,"rendered":378},{"title":369,"subtitle":370,"lang":16,"tags":371,"type":372,"slug":366,"createdAt":373,"draft":374},"Liens visités et indication visuelle","Comment différencier les liens déjà cliqués",[18],"snippets",["Date","2023-06-06T18:34:00.000Z"],false,"## La théorie\n\nIl est possible sur le web d'appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu'un lien visité est violet.\n\nGénéralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L'information qu'un lien a déjà été visité ne semble pas indispensable à la navigation. C'est sûrement vrai, mais personnellement, je suis assez content d'avoir un rappel des pages que j'ai déjà consultées lorsque je navigue.\n\nUne information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J'ai alors cherché un moyen d'ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n'est certainement pas idéale, elle se rapproche plus d'une expérience, à priori inoffensive pour l'internaute.\n\n## La spécification\n\nQuand je me suis intéressé à ce qu'il était possible de faire avec les liens déjà visités, j'ai découvert qu'extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu'il était possible de récupérer l'historique de navigation d'un utilisateur grâce aux styles des liens visités. Le sélecteur `:visited` a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. [Plus d'informations dans cet article.](https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector)\n\n## La pratique\n\nQue faire alors, en terme de style, quand on ne peut changer que des couleurs ?\n\nD'après MDN, les propriétés suivantes sont modifiables :\n\n- `color`\n- `background-color`\n- `border-color` (et les propriétés détaillées associées),\n- `column-rule-color`\n- `outline-color`\n- `text-decoration-color`\n- `text-emphasis-color`\n- Les composantes de couleur liées aux attributs SVG `fill` et `stroke`.\n\nChanger la couleur d'un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\n\nEn revanche, il est possible de \" masquer \" un élément en modifiant sa couleur pour qu'elle corresponde à la couleur du fond de la page ou de l'élément parent. On pourrait ainsi imaginer masquer une `border` ou un `outline`.\n\nJ'ai personnellement choisi de faire différemment. J'ai décidé d'utiliser un pseudo-élément `::before` sur l'état non visité du lien puis de le masquer quand celui-ci devient visité.\n\n### Le code\n\n```css\na {\n\tposition: relative;\n\ttext-decoration: none;\n}\na::before {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 0;\n\tinline-size: 2px;\n\tblock-size: 2px;\n\tborder-radius: 4px;\n\ttransform: translate(-6px, 0);\n\tbackground-color: grey;\n}\na:visited::before {\n\tbackground-color: white;\n}\n```\n\nCes règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\n\n### Accessibilité\n\nOn pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété `content` mais les lecteurs d'écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d'écrans annoncent déjà si un lien est visité avant de lire son intitulé.\n\n## Aller plus loin\n\nAfin de pousser l'expérience un peu plus loin, j'ai tenté d'utiliser des éléments plus explicites pour signifier l'état visité du lien. Bien qu'encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\n\nL'idée est d'avoir un `::before` et un `::after`, chacun contenant une icône en base 64 blanche en tant qu'image de fond. Quand le lien est non visité, le `::before` contient un fond coloré qui fait apparaître l'icône. Quand le lien passe en visité, le fond du `::before` devient blanc et celui du `::after` devient coloré, ce qui masque la première icône et affiche la deuxième.\n\nIl est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l'une sur l'autre.\n\n[Voir la démo sur codepen.](https://codepen.io/narduin/pen/VwVwmrO)","src/content/fragments/fr/visited-links.md","52385f4f8bc864b2",{"html":379,"metadata":380},"\u003Ch2 id=\"la-théorie\">La théorie\u003C/h2>\n\u003Cp>Il est possible sur le web d’appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu’un lien visité est violet.\u003C/p>\n\u003Cp>Généralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L’information qu’un lien a déjà été visité ne semble pas indispensable à la navigation. C’est sûrement vrai, mais personnellement, je suis assez content d’avoir un rappel des pages que j’ai déjà consultées lorsque je navigue.\u003C/p>\n\u003Cp>Une information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J’ai alors cherché un moyen d’ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n’est certainement pas idéale, elle se rapproche plus d’une expérience, à priori inoffensive pour l’internaute.\u003C/p>\n\u003Ch2 id=\"la-spécification\">La spécification\u003C/h2>\n\u003Cp>Quand je me suis intéressé à ce qu’il était possible de faire avec les liens déjà visités, j’ai découvert qu’extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu’il était possible de récupérer l’historique de navigation d’un utilisateur grâce aux styles des liens visités. Le sélecteur \u003Ccode>:visited\u003C/code> a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector\">Plus d’informations dans cet article.\u003C/a>\u003C/p>\n\u003Ch2 id=\"la-pratique\">La pratique\u003C/h2>\n\u003Cp>Que faire alors, en terme de style, quand on ne peut changer que des couleurs ?\u003C/p>\n\u003Cp>D’après MDN, les propriétés suivantes sont modifiables :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>background-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>border-color\u003C/code> (et les propriétés détaillées associées),\u003C/li>\n\u003Cli>\u003Ccode>column-rule-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>outline-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-decoration-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-emphasis-color\u003C/code>\u003C/li>\n\u003Cli>Les composantes de couleur liées aux attributs SVG \u003Ccode>fill\u003C/code> et \u003Ccode>stroke\u003C/code>.\u003C/li>\n\u003C/ul>\n\u003Cp>Changer la couleur d’un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\u003C/p>\n\u003Cp>En revanche, il est possible de ” masquer ” un élément en modifiant sa couleur pour qu’elle corresponde à la couleur du fond de la page ou de l’élément parent. On pourrait ainsi imaginer masquer une \u003Ccode>border\u003C/code> ou un \u003Ccode>outline\u003C/code>.\u003C/p>\n\u003Cp>J’ai personnellement choisi de faire différemment. J’ai décidé d’utiliser un pseudo-élément \u003Ccode>::before\u003C/code> sur l’état non visité du lien puis de le masquer quand celui-ci devient visité.\u003C/p>\n\u003Ch3 id=\"le-code\">Le code\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">a\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">relative\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttext-decoration\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">a\u003C/span>\u003Cspan style=\"color:#B392F0\">::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttop\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tleft\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tinline-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tblock-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder-radius\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">4\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translate\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-6\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">grey\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">a\u003C/span>\u003Cspan style=\"color:#B392F0\">:visited::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">white\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Ces règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\u003C/p>\n\u003Ch3 id=\"accessibilité\">Accessibilité\u003C/h3>\n\u003Cp>On pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété \u003Ccode>content\u003C/code> mais les lecteurs d’écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d’écrans annoncent déjà si un lien est visité avant de lire son intitulé.\u003C/p>\n\u003Ch2 id=\"aller-plus-loin\">Aller plus loin\u003C/h2>\n\u003Cp>Afin de pousser l’expérience un peu plus loin, j’ai tenté d’utiliser des éléments plus explicites pour signifier l’état visité du lien. Bien qu’encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\u003C/p>\n\u003Cp>L’idée est d’avoir un \u003Ccode>::before\u003C/code> et un \u003Ccode>::after\u003C/code>, chacun contenant une icône en base 64 blanche en tant qu’image de fond. Quand le lien est non visité, le \u003Ccode>::before\u003C/code> contient un fond coloré qui fait apparaître l’icône. Quand le lien passe en visité, le fond du \u003Ccode>::before\u003C/code> devient blanc et celui du \u003Ccode>::after\u003C/code> devient coloré, ce qui masque la première icône et affiche la deuxième.\u003C/p>\n\u003Cp>Il est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l’une sur l’autre.\u003C/p>\n\u003Cp>\u003Ca href=\"https://codepen.io/narduin/pen/VwVwmrO\">Voir la démo sur codepen.\u003C/a>\u003C/p>",{"headings":381,"imagePaths":399,"frontmatter":400},[382,385,388,391,394,396],{"depth":80,"slug":383,"text":384},"la-théorie","La théorie",{"depth":80,"slug":386,"text":387},"la-spécification","La spécification",{"depth":80,"slug":389,"text":390},"la-pratique","La pratique",{"depth":120,"slug":392,"text":393},"le-code","Le code",{"depth":120,"slug":32,"text":395},"Accessibilité",{"depth":80,"slug":397,"text":398},"aller-plus-loin","Aller plus loin",[],{"title":369,"subtitle":370,"lang":16,"draft":374,"slug":366,"excerpt":401,"tags":402,"type":372,"createdAt":403},"Petit hack CSS",[18],"2023-06-06T18:34:00.000Z","en-acme-sh-tls-cert",{"id":404,"data":406,"body":413,"filePath":414,"digest":415,"rendered":416},{"title":407,"subtitle":408,"lang":409,"tags":410,"type":372,"slug":404,"createdAt":412},"Strong TLS certificates with acme.sh","384-bit of https","en",[411],"security",["Date","2022-06-08T14:24:06.000Z"],"## Disclaimer\n\nI'm, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs. \nThis is why I've switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nYou can learn (far) more by reading [this topic](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) and its linked resources.\n\n## Requirements\n\n### Installing acme.sh\n\nFor automation and ease of use purposes, I'm using [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# for using standalone mode, you might have to install as sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changing default authority\n\nBy default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let's Encrypt because according to acme.sh, they're the only ones offering ECC capabilities.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Using your DNS api\n\nIf available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports [a lot](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) of DNS providers.\n\n### Define an api key\n\nFollow the [docs](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) for your DNS provider, usually:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Issue the cert\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Using standalone mode\n\nIf you don't have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\n\nPort `80` must be free.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Examples\n\n### Multi domains standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domain DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Next steps\n\nThe ECC certificate alone will not grant you a high/perfect score.\n\n### TLS version\n\nLimit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a [5% compatibility gap](https://caniuse.com/?search=tls%201.) with 1.2).\n\n### HSTS\n\nUse the [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/) header.\n\n```\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Cipher suite\n\nUse recent and strong ciphers. This is where my knowledge hits its limit… I'm having a really hard time understanding what to use and why.\n\nI've based my initial choices of ciphers on [this list](https://tls.imirhil.fr/ciphers), cross referencing it with (older?) [browser compatibility](https://tls.imirhil.fr/suite).\n\nI then asked [Aeris](https://twitter.com/aeris22), the creator of [tls.imirhil.fr](https://tls.imirhil.fr), about it and he advised me to use the following:\n\n```\nECDHE+AES:ECDHE+CHACHA20\n```\n\nIn order to achieve a perfect score, we can be a little more restrictive with:\n\n```\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/en/acme-sh-tls-cert.md","41577e8aee884f85",{"html":417,"metadata":418},"\u003Ch2 id=\"disclaimer\">Disclaimer\u003C/h2>\n\u003Cp>I’m, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs.\u003Cbr>\nThis is why I’ve switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>You can learn (far) more by reading \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">this topic\u003C/a> and its linked resources.\u003C/p>\n\u003Ch2 id=\"requirements\">Requirements\u003C/h2>\n\u003Ch3 id=\"installing-acmesh\">Installing acme.sh\u003C/h3>\n\u003Cp>For automation and ease of use purposes, I’m using \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># for using standalone mode, you might have to install as sudo\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">curl\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> https://get.acme.sh\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#B392F0\"> sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -s\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> email=mail@domain.tld\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"changing-default-authority\">Changing default authority\u003C/h3>\n\u003Cp>By default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let’s Encrypt because according to acme.sh, they’re the only ones offering ECC capabilities.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --set-default-ca\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --server\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> letsencrypt\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"using-your-dns-api\">Using your DNS api\u003C/h2>\n\u003Cp>If available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">a lot\u003C/a> of DNS providers.\u003C/p>\n\u003Ch3 id=\"define-an-api-key\">Define an api key\u003C/h3>\n\u003Cp>Follow the \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">docs\u003C/a> for your DNS provider, usually:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">export\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> PROVIDER_Key\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"YOUR_API_KEY\"\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"issue-the-cert\">Issue the cert\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"using-standalone-mode\">Using standalone mode\u003C/h2>\n\u003Cp>If you don’t have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\u003C/p>\n\u003Cp>Port \u003Ccode>80\u003C/code> must be free.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"examples\">Examples\u003C/h2>\n\u003Ch3 id=\"multi-domains-standalone\">Multi domains standalone\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> www.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> subdomain.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"wildcard-domain-dns\">Wildcard domain DNS\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '*.domain.tld'\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"next-steps\">Next steps\u003C/h2>\n\u003Cp>The ECC certificate alone will not grant you a high/perfect score.\u003C/p>\n\u003Ch3 id=\"tls-version\">TLS version\u003C/h3>\n\u003Cp>Limit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a \u003Ca href=\"https://caniuse.com/?search=tls%201.\">5% compatibility gap\u003C/a> with 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Use the \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a> header.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>Strict-Transport-Security: max-age=31536000; includeSubDomains\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"cipher-suite\">Cipher suite\u003C/h3>\n\u003Cp>Use recent and strong ciphers. This is where my knowledge hits its limit… I’m having a really hard time understanding what to use and why.\u003C/p>\n\u003Cp>I’ve based my initial choices of ciphers on \u003Ca href=\"https://tls.imirhil.fr/ciphers\">this list\u003C/a>, cross referencing it with (older?) \u003Ca href=\"https://tls.imirhil.fr/suite\">browser compatibility\u003C/a>.\u003C/p>\n\u003Cp>I then asked \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, the creator of \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, about it and he advised me to use the following:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>In order to achieve a perfect score, we can be a little more restrictive with:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES256:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":419,"imagePaths":463,"frontmatter":464},[420,423,426,429,432,435,438,441,444,447,450,453,456,459,460],{"depth":80,"slug":421,"text":422},"disclaimer","Disclaimer",{"depth":80,"slug":424,"text":425},"requirements","Requirements",{"depth":120,"slug":427,"text":428},"installing-acmesh","Installing acme.sh",{"depth":120,"slug":430,"text":431},"changing-default-authority","Changing default authority",{"depth":80,"slug":433,"text":434},"using-your-dns-api","Using your DNS api",{"depth":120,"slug":436,"text":437},"define-an-api-key","Define an api key",{"depth":120,"slug":439,"text":440},"issue-the-cert","Issue the cert",{"depth":80,"slug":442,"text":443},"using-standalone-mode","Using standalone mode",{"depth":80,"slug":445,"text":446},"examples","Examples",{"depth":120,"slug":448,"text":449},"multi-domains-standalone","Multi domains standalone",{"depth":120,"slug":451,"text":452},"wildcard-domain-dns","Wildcard domain DNS",{"depth":80,"slug":454,"text":455},"next-steps","Next steps",{"depth":120,"slug":457,"text":458},"tls-version","TLS version",{"depth":120,"slug":246,"text":247},{"depth":120,"slug":461,"text":462},"cipher-suite","Cipher suite",[],{"title":407,"subtitle":408,"lang":409,"slug":404,"createdAt":253,"excerpt":465,"tags":466,"type":372},"Real cert have curves.",[411],"en-array-vs-array",{"id":467,"data":469,"body":474,"filePath":475,"digest":476,"rendered":477},{"title":470,"subtitle":471,"lang":409,"tags":472,"type":372,"slug":467,"createdAt":473},"Filter an array against another array","Array vs Array.",[262],["Date","2022-06-08T14:24:06.000Z"],"## Context\n\nFor a project, I had to come up with a way to filter an array of objects based on another array of strings.\n\nIn other words, I needed to include every object which `user` property was found in the second array.\n\nHere is an example:\n\n```javascript\nconst skills = [\n\t{\n\t\tname: 'Be awesome',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Great jokes',\n\t\tuser: 'Jacques'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Beatriz'\n\t}\n]\n\nconst selectedUsers = ['Jean', 'Beatriz']\n```\n\nI thought it would be pretty easy but I guess I'm not familiar enough with javascript 😬\n\n## My solution\n\nAfter a bit of thinking, I came up with the following statement:\n\n> I need to filter the skills based on which users are selected. So I need to loop over the `selectedUsers` array and filter the skills according to their `user` value.\n\nAfter a bit more trials and errors, this is the code I ended up using in a `computed property`:\n\n```javascript\n// index.vue\nconst filteredSkills = selectedUsers.map((user) => {\n\treturn skills.filter((skill) => {\n\t\treturn skill.user === user\n\t})\n})\n```\n\nI used `map()` in order to loop on the second array and used its string value to only include the corresponding skills with `filter()`.\n\nI'm pretty sure there is a better way to do it though…","src/content/fragments/en/array-vs-array.md","c63ba57b1049cf4c",{"html":478,"metadata":479},"\u003Ch2 id=\"context\">Context\u003C/h2>\n\u003Cp>For a project, I had to come up with a way to filter an array of objects based on another array of strings.\u003C/p>\n\u003Cp>In other words, I needed to include every object which \u003Ccode>user\u003C/code> property was found in the second array.\u003C/p>\n\u003Cp>Here is an example:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> skills\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Be awesome'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jean'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Great jokes'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jacques'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jean'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Beatriz'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> selectedUsers\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jean'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Beatriz'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>I thought it would be pretty easy but I guess I’m not familiar enough with javascript 😬\u003C/p>\n\u003Ch2 id=\"my-solution\">My solution\u003C/h2>\n\u003Cp>After a bit of thinking, I came up with the following statement:\u003C/p>\n\u003Cblockquote>\n\u003Cp>I need to filter the skills based on which users are selected. So I need to loop over the \u003Ccode>selectedUsers\u003C/code> array and filter the skills according to their \u003Ccode>user\u003C/code> value.\u003C/p>\n\u003C/blockquote>\n\u003Cp>After a bit more trials and errors, this is the code I ended up using in a \u003Ccode>computed property\u003C/code>:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> filteredSkills\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> selectedUsers.\u003C/span>\u003Cspan style=\"color:#B392F0\">map\u003C/span>\u003Cspan style=\"color:#E1E4E8\">((\u003C/span>\u003Cspan style=\"color:#FFAB70\">user\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">=>\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">\treturn\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> skills.\u003C/span>\u003Cspan style=\"color:#B392F0\">filter\u003C/span>\u003Cspan style=\"color:#E1E4E8\">((\u003C/span>\u003Cspan style=\"color:#FFAB70\">skill\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">=>\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">\t\treturn\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> skill.user \u003C/span>\u003Cspan style=\"color:#F97583\">===\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> user\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t})\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">})\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>I used \u003Ccode>map()\u003C/code> in order to loop on the second array and used its string value to only include the corresponding skills with \u003Ccode>filter()\u003C/code>.\u003C/p>\n\u003Cp>I’m pretty sure there is a better way to do it though…\u003C/p>",{"headings":480,"imagePaths":487,"frontmatter":488},[481,484],{"depth":80,"slug":482,"text":483},"context","Context",{"depth":80,"slug":485,"text":486},"my-solution","My solution",[],{"title":470,"subtitle":471,"lang":409,"slug":467,"createdAt":253,"excerpt":489,"tags":490,"type":372},"My peak javascript",[262],"en-buttons",{"id":491,"data":493,"body":498,"filePath":499,"digest":500,"rendered":501},{"title":494,"subtitle":495,"lang":409,"tags":496,"type":372,"slug":491,"createdAt":497,"code":264,"draft":264},"Buttons hover","Simple, but nice.",[281],["Date","2020-10-08T09:00:00.000Z"],"## General rules\n\nAll the buttons use these styles as a “reset”:\n\n> Don't forget to prefix if necessary!\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Add an icon\n\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('~assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double shutter down\n\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Animated gradient\n\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Non destructive scale\n\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/en/buttons.md","ea9a5513a5a4cef4",{"html":502,"metadata":503},"\u003Ch2 id=\"general-rules\">General rules\u003C/h2>\n\u003Cp>All the buttons use these styles as a “reset”:\u003C/p>\n\u003Cblockquote>\n\u003Cp>Don’t forget to prefix if necessary!\u003C/p>\n\u003C/blockquote>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tmargin\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">20\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tpadding\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">12\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 26\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">relative\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tdisplay\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">inline-block\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\toverflow\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hidden\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tfont-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">20\u003C/span>\u003Cspan style=\"color:#F97583\">rem\u003C/span>\u003Cspan style=\"color:#E1E4E8\">; \u003C/span>\u003Cspan style=\"color:#6A737D\">/* 20px */\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tline-height\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">1.6\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttext-align\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">center\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttext-decoration\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tfont-weight\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">bold\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcursor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">pointer\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder-radius\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t-moz-appearance\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t-webkit-appearance\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">white\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hotpink\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: background-color \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"add-an-icon\">Add an icon\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hotpink\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">url\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'~assets/svg/arrow-right-white.svg'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">20\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttop\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tright\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translate\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">40\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">-50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">ease\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:hover\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:focus\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">darkorchid\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:hover::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:focus::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translate\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-10\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">-50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon\u003C/span>\u003Cspan style=\"color:#F97583\"> >\u003C/span>\u003Cspan style=\"color:#85E89D\"> span\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tdisplay\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">inline-block\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\theight\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:hover\u003C/span>\u003Cspan style=\"color:#F97583\"> >\u003C/span>\u003Cspan style=\"color:#85E89D\"> span\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:focus\u003C/span>\u003Cspan style=\"color:#F97583\"> >\u003C/span>\u003Cspan style=\"color:#85E89D\"> span\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translateX\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-10\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"double-shutter-down\">Double shutter down\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> solid\u003C/span>\u003Cspan style=\"color:#79B8FF\"> #10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">#10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">transparent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">color\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">white\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hotpink\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">darkorchid\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\theight\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbottom\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tleft\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tz-index\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">-1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition-timing-function\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition-timing-function\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">cubic-bezier\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">0.75\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.125\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:focus::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:focus::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translateY\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:focus::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition-delay\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.175\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"animated-gradient\">Animated gradient\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-gradient\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">linear-gradient\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-45\u003C/span>\u003Cspan style=\"color:#F97583\">deg\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#ee7752\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#e73c7e\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#23a6d5\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#23d5ab\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">400\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 400\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tanimation\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: GradientReverse \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.5\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:#79B8FF\"> normal\u003C/span>\u003Cspan style=\"color:#79B8FF\"> forwards\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-gradient:hover\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-gradient:focus\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tanimation\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: Gradient \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.5\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:#79B8FF\"> normal\u003C/span>\u003Cspan style=\"color:#79B8FF\"> forwards\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">@keyframes\u003C/span>\u003Cspan style=\"color:#FFAB70\"> Gradient\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t0%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t100%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">@keyframes\u003C/span>\u003Cspan style=\"color:#FFAB70\"> GradientReverse\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t0%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t100%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"non-destructive-scale\">Non destructive scale\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\toverflow\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">visible\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">#10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">transparent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttop\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tleft\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbottom\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> solid\u003C/span>\u003Cspan style=\"color:#79B8FF\"> #10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder-radius\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale:hover::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale:focus::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">scale\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">1.1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":504,"imagePaths":520,"frontmatter":521},[505,508,511,514,517],{"depth":80,"slug":506,"text":507},"general-rules","General rules",{"depth":80,"slug":509,"text":510},"add-an-icon","Add an icon",{"depth":80,"slug":512,"text":513},"double-shutter-down","Double shutter down",{"depth":80,"slug":515,"text":516},"animated-gradient","Animated gradient",{"depth":80,"slug":518,"text":519},"non-destructive-scale","Non destructive scale",[],{"title":494,"subtitle":495,"lang":409,"slug":491,"draft":264,"excerpt":522,"tags":523,"code":264,"type":372,"createdAt":524},"Easy to grab and use hover effects.",[281],"2020-10-08T09:00:00.000Z","en-image-full",{"id":525,"data":527,"body":533,"filePath":534,"digest":535,"deferredRender":264},{"title":528,"subtitle":529,"lang":409,"tags":530,"type":372,"slug":525,"createdAt":531,"updatedAt":532,"draft":264},"Full width image","Translation in progress, stay tuned ;)",[281],["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"[Go back to available snippets](/en/snippets)","src/content/fragments/en/image-full.mdx","2e3dddf593f6d72f","en-nuxt-graphql-static",{"id":536,"data":538,"body":544,"filePath":545,"digest":546,"rendered":547},{"title":539,"subtitle":540,"lang":409,"tags":541,"type":372,"slug":536,"createdAt":542,"updatedAt":543},"Static website and GraphQL queries with Nuxt.js","Graphql client is king.",[262],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## The problem\n\nI encountered a nasty bug while using static generation with Nuxt and [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (new tab)') client.\nI found [the issue](https://github.com/nuxt-community/apollo-module/issues/339 'Github issue on nuxt/apollo repository (new tab)') already reported on github.\n\nIt seems the module doesn't handle static generation correctly with `nuxt generate`.\n\nI could find request to my local API url after the static generation. Moreover, it also seemed like `\u003Cnuxt-link>` navigation was broken.\n\n## The solution 🙌\n\nFortunately, there is another Nuxt module that handles GraphQL requests!\n\n[Nuxt graphql request to the rescue!](https://github.com/gomah/nuxt-graphql-request)\n\n### The conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### The request\n\nThe best approach so far is to use `asyncData` in pages and `fetch` in components. Using `fetch` in pages does not work well at all with `nuxt generate`.\n\nI also install the `graphql-tag` package (only in `devDependencies`) to be able to import directly `.gql` files.\n\nQuery example:\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Inside a page\n\n```javascript\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n async asyncData({ $graphql }) {\n const data = await $graphql.default.request(homepageQuery)\n return { data }\n },\n}\n\u003C/script>\n```\n\n#### Inside a component\n\nIt is safer to wait until `fetch` has received a response before displaying anything. You can use `$fetchState` to be sure ([documentation](https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation on the fetch hook (new tab)')).\n\n```javascript\n// Header.vue\n\u003Ctemplate>\n \u003Cheader v-if=\"!$fetchState.pending\">\n …\n \u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n data() {\n return {\n data: {},\n }\n },\n async fetch() {\n try {\n const data = await this.$graphql.default.request(headerQuery)\n this.data = data\n } catch (error) {\n console.error(JSON.stringify(error, undefined, 2))\n }\n },\n}\n\u003C/script>\n```\n\n### Options\n\nTo pass options to the request, for example for a multilingual version with [nuxt/i18n](https://i18n.nuxtjs.org/) and/or a url parameter in a dynamic page:\n\n```javascript\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n async asyncData({ $graphql, app, params }) {\n const locale = app.i18n.localeProperties.iso\n const data = await $graphql.default.request(articleQuery, {\n code: locale,\n slug: params.slug,\n })\n return { data }\n },\n}\n\u003C/script>\n```","src/content/fragments/en/nuxt-graphql-static.md","181e8091294eb858",{"html":548,"metadata":549},"\u003Ch2 id=\"the-problem\">The problem\u003C/h2>\n\u003Cp>I encountered a nasty bug while using static generation with Nuxt and \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (new tab)\">nuxt apollo\u003C/a> client.\nI found \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Github issue on nuxt/apollo repository (new tab)\">the issue\u003C/a> already reported on github.\u003C/p>\n\u003Cp>It seems the module doesn’t handle static generation correctly with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I could find request to my local API url after the static generation. Moreover, it also seemed like \u003Ccode><nuxt-link>\u003C/code> navigation was broken.\u003C/p>\n\u003Ch2 id=\"the-solution\">The solution 🙌\u003C/h2>\n\u003Cp>Fortunately, there is another Nuxt module that handles GraphQL requests!\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\">Nuxt graphql request to the rescue!\u003C/a>\u003C/p>\n\u003Ch3 id=\"the-conf\">The conf\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// nuxt.config.js\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">buildModules\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\"> 'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">graphql\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> clients\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> default\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> endpoint: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> options: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> headers: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> authorization: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">},\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"the-request\">The request\u003C/h3>\n\u003Cp>The best approach so far is to use \u003Ccode>asyncData\u003C/code> in pages and \u003Ccode>fetch\u003C/code> in components. Using \u003Ccode>fetch\u003C/code> in pages does not work well at all with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I also install the \u003Ccode>graphql-tag\u003C/code> package (only in \u003Ccode>devDependencies\u003C/code>) to be able to import directly \u003Ccode>.gql\u003C/code> files.\u003C/p>\n\u003Cp>Query example:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"graphql\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># homepage.gql\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">query\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\thomepage\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\ttitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\tsubtitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\thero\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\tid\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\talt\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"inside-a-page\">Inside a page\u003C/h4>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import homepageQuery from '~/graphql/queries/singles/homepage'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(homepageQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"inside-a-component\">Inside a component\u003C/h4>\n\u003Cp>It is safer to wait until \u003Ccode>fetch\u003C/code> has received a response before displaying anything. You can use \u003Ccode>$fetchState\u003C/code> to be sure (\u003Ca href=\"https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation on the fetch hook (new tab)\">documentation\u003C/a>).\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// Header.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> <\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#B392F0\"> v-if\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"!$fetchState.pending\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> …\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> </\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import headerQuery from '~/graphql/queries/singles/header'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">fetch\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> try {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> data\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.$graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(headerQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> data\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> } catch (error) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> console.\u003C/span>\u003Cspan style=\"color:#B392F0\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(JSON.stringify(\u003C/span>\u003Cspan style=\"color:#FFAB70\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">undefined\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, 2))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"options\">Options\u003C/h3>\n\u003Cp>To pass options to the request, for example for a multilingual version with \u003Ca href=\"https://i18n.nuxtjs.org/\">nuxt/i18n\u003C/a> and/or a url parameter in a dynamic page:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// _slug.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import articleQuery from '~/graphql/queries/articles'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql, app, params }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const locale \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> app.i18n.localeProperties.iso\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(articleQuery, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> code: locale,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> slug: params.slug,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> })\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":550,"imagePaths":572,"frontmatter":573},[551,554,557,560,563,566,569],{"depth":80,"slug":552,"text":553},"the-problem","The problem",{"depth":80,"slug":555,"text":556},"the-solution","The solution 🙌",{"depth":120,"slug":558,"text":559},"the-conf","The conf",{"depth":120,"slug":561,"text":562},"the-request","The request",{"depth":325,"slug":564,"text":565},"inside-a-page","Inside a page",{"depth":325,"slug":567,"text":568},"inside-a-component","Inside a component",{"depth":120,"slug":570,"text":571},"options","Options",[],{"title":539,"subtitle":540,"lang":409,"slug":536,"createdAt":253,"updatedAt":336,"excerpt":574,"tags":575,"type":372},"When the most used gql module doesn't work…",[262],"en-super-cookies",{"id":576,"data":578,"body":584,"filePath":585,"digest":586,"deferredRender":264},{"title":579,"subtitle":580,"lang":409,"tags":581,"type":372,"slug":576,"createdAt":583},"The best cookies","Consentless biscuits.",[582],"food",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 tablespoon of baking powder\n- 3/4 of aquafaba from 400g of chickpea (chickpea water)\n- 125 grams of coconut oil\n- 2 teaspoons of maple syrup\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- if necessary, melt the coconut oil over low heat\n- meanwhile, mix all the dry ingredients\n- add all liquid ingredients (oil, aquafaba, maple syrup)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Non vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 table spoon of baking powder\n- 1 egg\n- 125 grams of melted butter\n- 2 teaspoons of honey\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- melt butter over low heat\n- meanwhile, mix all dry ingredients\n- add all liquid ingredients (melted butter, egg, honey)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Notes\n\nChocolate can be replaced by anything like nuts, raisins, legos... (don't eat legos be reasonable).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='All ingredients mixed together to form a brown paste.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='The cookies are round and soft after baking.'\n/>","src/content/fragments/en/super-cookies.mdx","b0c67adad40c177c","en-toulouse-fun",{"id":587,"data":589,"body":593,"filePath":594,"digest":595,"rendered":596},{"title":353,"subtitle":590,"lang":409,"tags":591,"type":372,"slug":587,"createdAt":592},"Only the bestest",[355],["Date","2022-06-22T15:34:45.000Z"],"Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite. \n**It's always a good idea to make a reservation!**\n\n## Restaurants\n\n### French cuisine\n\n- [Solides](https://www.solides.fr/) — semi-gastronomic\n- [Les impulsifs](https://les-impulsifs-toulouse.eatbu.com/?lang=en) — semi-gastronomic\n- [Sixta](https://sixta-toulouse.fr/) — vege/vegan/gluten friendly\n- [Attila](https://attila.site-solocal.com/) — great **fish restaurant,** just above the Victor Hugo market\n- [Chez Emile](https://www.restaurant-emile.com/) - best [cassoulet](https://en.wikipedia.org/wiki/Cassoulet) in town (or so I'm told)\n\n### Korean\n\n- [Le ptit Louis](https://leptitlouis.fr/) — best of its kind, **only for lunch**\n- [Kongbap](https://kong-bap.com/) — street-food like\n\n### Japanese\n\n- [Iori](https://www.iori.fr/) — best ramen\n- [Japoyaki](https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402) — best sushi/sashimis\n\n## Drinks and snacks\n\n### Bars\n\n- [Le Bièrographe](https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327) — all time favourite, **check out the typical toulouse basement**\n- [A Taula](https://www.facebook.com/ataulatolosa/) — all time favourite in summer, **amazing terrace,** also: great tapas\n- [The Hopscotch Pub](https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385) — good beers, good whiskies, good cocktials, good food\n\n### Cafés & tea rooms\n\n- [Bapz](https://www.bapz.fr/contact) — Excellent pastries / hot beverages\n- [Ô thé divin](https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/) — nice lunch options\n- [Les Rêveries d’Hercule](https://www.lesreveriesdhercule.com/) — Pottery Café, relaxing activity (ceramics need to be baked, there'll be a delay to get them back)\n- Bonus: the best bakeries in [Carmes](https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872) and [Saint-Aubin](https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694) — croissants, baguettes **traditions**, chocolatines and more\n\n### Wine shops\n\n- [l'envie du sud](https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930) — amazing selection of wines and other spirits, excellent advice from the staff\n- [enoteca](https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952) — smaller selection but more beers and great advice from the staff as well\n\n## Other delights\n\n### Ice creams\n\n- [Forno gusto](https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450) — only in the summer\n- [Moustache](https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540) — lots of flavours\n\n### Cheese shop\n\n- [Xavier](https://xavier.fr/) — one of the **best of the country**, two shops in Toulouse, including one at Victor Hugo market\n- [Massembea](https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490) — a serious contender in Toulouse (weird hours)\n\n### Delicatessen\n\n- [Café Bacquié](http://cafe-bacquie.com/) — stock up on fine foods, coffees, teas and other great quality products","src/content/fragments/en/toulouse-fun.md","370491cc68079e8c",{"html":597,"metadata":598},"\u003Cp>Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite.\u003Cbr>\n\u003Cstrong>It’s always a good idea to make a reservation!\u003C/strong>\u003C/p>\n\u003Ch2 id=\"restaurants\">Restaurants\u003C/h2>\n\u003Ch3 id=\"french-cuisine\">French cuisine\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.solides.fr/\">Solides\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://les-impulsifs-toulouse.eatbu.com/?lang=en\">Les impulsifs\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://sixta-toulouse.fr/\">Sixta\u003C/a> — vege/vegan/gluten friendly\u003C/li>\n\u003Cli>\u003Ca href=\"https://attila.site-solocal.com/\">Attila\u003C/a> — great \u003Cstrong>fish restaurant,\u003C/strong> just above the Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.restaurant-emile.com/\">Chez Emile\u003C/a> - best \u003Ca href=\"https://en.wikipedia.org/wiki/Cassoulet\">cassoulet\u003C/a> in town (or so I’m told)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"korean\">Korean\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://leptitlouis.fr/\">Le ptit Louis\u003C/a> — best of its kind, \u003Cstrong>only for lunch\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://kong-bap.com/\">Kongbap\u003C/a> — street-food like\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"japanese\">Japanese\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.iori.fr/\">Iori\u003C/a> — best ramen\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402\">Japoyaki\u003C/a> — best sushi/sashimis\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"drinks-and-snacks\">Drinks and snacks\u003C/h2>\n\u003Ch3 id=\"bars\">Bars\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327\">Le Bièrographe\u003C/a> — all time favourite, \u003Cstrong>check out the typical toulouse basement\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.facebook.com/ataulatolosa/\">A Taula\u003C/a> — all time favourite in summer, \u003Cstrong>amazing terrace,\u003C/strong> also: great tapas\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385\">The Hopscotch Pub\u003C/a> — good beers, good whiskies, good cocktials, good food\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cafés--tea-rooms\">Cafés & tea rooms\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.bapz.fr/contact\">Bapz\u003C/a> — Excellent pastries / hot beverages\u003C/li>\n\u003Cli>\u003Ca href=\"https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/\">Ô thé divin\u003C/a> — nice lunch options\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lesreveriesdhercule.com/\">Les Rêveries d’Hercule\u003C/a> — Pottery Café, relaxing activity (ceramics need to be baked, there’ll be a delay to get them back)\u003C/li>\n\u003Cli>Bonus: the best bakeries in \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872\">Carmes\u003C/a> and \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694\">Saint-Aubin\u003C/a> — croissants, baguettes \u003Cstrong>traditions\u003C/strong>, chocolatines and more\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"wine-shops\">Wine shops\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930\">l’envie du sud\u003C/a> — amazing selection of wines and other spirits, excellent advice from the staff\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952\">enoteca\u003C/a> — smaller selection but more beers and great advice from the staff as well\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"other-delights\">Other delights\u003C/h2>\n\u003Ch3 id=\"ice-creams\">Ice creams\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450\">Forno gusto\u003C/a> — only in the summer\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540\">Moustache\u003C/a> — lots of flavours\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cheese-shop\">Cheese shop\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://xavier.fr/\">Xavier\u003C/a> — one of the \u003Cstrong>best of the country\u003C/strong>, two shops in Toulouse, including one at Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490\">Massembea\u003C/a> — a serious contender in Toulouse (weird hours)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"delicatessen\">Delicatessen\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"http://cafe-bacquie.com/\">Café Bacquié\u003C/a> — stock up on fine foods, coffees, teas and other great quality products\u003C/li>\n\u003C/ul>",{"headings":599,"imagePaths":636,"frontmatter":637},[600,603,606,609,612,615,618,621,624,627,630,633],{"depth":80,"slug":601,"text":602},"restaurants","Restaurants",{"depth":120,"slug":604,"text":605},"french-cuisine","French cuisine",{"depth":120,"slug":607,"text":608},"korean","Korean",{"depth":120,"slug":610,"text":611},"japanese","Japanese",{"depth":80,"slug":613,"text":614},"drinks-and-snacks","Drinks and snacks",{"depth":120,"slug":616,"text":617},"bars","Bars",{"depth":120,"slug":619,"text":620},"cafés--tea-rooms","Cafés & tea rooms",{"depth":120,"slug":622,"text":623},"wine-shops","Wine shops",{"depth":80,"slug":625,"text":626},"other-delights","Other delights",{"depth":120,"slug":628,"text":629},"ice-creams","Ice creams",{"depth":120,"slug":631,"text":632},"cheese-shop","Cheese shop",{"depth":120,"slug":634,"text":635},"delicatessen","Delicatessen",[],{"title":353,"subtitle":590,"lang":409,"slug":587,"excerpt":638,"tags":639,"type":372,"createdAt":364},"Gonna have to trust me on this ¯\\_(ツ)_/¯",[355],"en-visited-links",{"id":640,"data":642,"body":533,"filePath":646,"digest":647,"rendered":648},{"title":643,"subtitle":529,"lang":409,"tags":644,"type":372,"slug":640,"createdAt":645,"draft":264},"Visited links and visuel aid",[18],["Date","2023-06-06T18:34:00.000Z"],"src/content/fragments/en/visited-links.md","cb7c11c12c25067e",{"html":649,"metadata":650},"\u003Cp>\u003Ca href=\"/en/snippets\">Go back to available snippets\u003C/a>\u003C/p>",{"headings":651,"imagePaths":652,"frontmatter":653},[],[],{"title":643,"subtitle":529,"lang":409,"draft":264,"slug":640,"excerpt":401,"tags":654,"type":372,"createdAt":403},[18],"articles",["Map",657,658,670,671,704,705,738,739,749,750,766,767,781,782,792,793,805,806],"sci-hub-blocage",{"id":657,"data":659,"body":667,"filePath":668,"digest":669,"deferredRender":264},{"title":660,"subtitle":661,"lang":16,"tags":662,"type":655,"slug":657,"createdAt":665,"updatedAt":666},"Sci-hub bloqué, comment contourner","La science du partage.",[663,664],"Internet","Science",["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nL'adresse actuelle de sci-hub est : [sci-hub.se](https://sci-hub.se)\n\n## Résumé de la situation\n\nN’étant pas moi-même directement chercheur, je vous laisse regarder [cette vidéo](https://youtu.be/rcgxY__YXEc) explicative extrêmement bien faite sur le sujet de la publication scientifique.\n\n> “ Mais c’est scandaleux ! ”​\n\nJ’ai constaté que le blocage était actif chez SFR. Je n’ai pas encore pu vérifier pour les autres fournisseurs mais j’imagine qu’ils se sont tous conformés à la décision de justice.\nLe blocage mis en place est assez basique. Il s’agit d’un blocage “ DNS ”.\n\nUn DNS est un serveur qui sert à faire le lien entre un nom de domaine : **sci-hub.tw** et une adresse IP : **186.2.163.90**.\n\nC’est en quelque sorte l’annuaire d’internet. Sans l’adresse, impossible de contacter le domaine. Ce que les FAI ont certainement fait : bloquer les requêtes au nom de domaine [sci-hub.se.](http://sci-hub.se/) Ainsi, aucune adresse IP n’est renvoyée et le site n’est pas accessible.\n\n## Comment contourner ce blocage ?\n\n- Soit en utilisant un VPN\n- Soit en modifiant les serveurs DNS de vos ordinateurs/box internet\n\nJe recommande la deuxième solution car elle permet de se prémunir contre de futurs blocages/filtrages/censures de la part de votre FAI et ne nécessite pas de contrepartie financière.\nJe vais me focaliser sur le changement depuis un ordinateur car il sera effectif où que vous soyez.\n\n### Sur MacOs\n\nOuvrez :\n\n1. Préférences système\n1. Réseau\n1. Ethernet et/ou Wi-fi\n1. Avancé\n1. DNS\n1. Serveurs DNS\n\nDe là, vous pouvez ajouter des serveurs DNS en cliquant sur l'icône +. Cliquez sur ok et appliquez les nouveaux paramètres. Vous devrez peut-être redémarrer votre ordinateur pour que les changements fonctionnent.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS réglages réseau et DNS'\n/>\n\n### Sur Windows (ici 10)\n\nOuvrez :\n\n1. Réglages\n1. Réseau et internet\n1. Modifier les options de l'adaptateur\n1. Clic droit sur les propriétés de votre interface réseau\n1. Selectionnez « protocole Internet version 4 » (et/ou 6)\n1. Propriétés\n1. Utiliser l’adresse de serveur DNS suivante\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Réglages windows'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows réglages réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows régalges connections réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows options adaptateur réseau'\n/>\n\n## Quels serveurs DNS utiliser ?\n\nIl y a de nombreux serveurs DNS accessibles. Les plus connus étant ceux de Google, Cloudflare et OpenDNS. Si vous tenez vraiment à utiliser ceux de Google, je vous laisse chercher leur adresse. Voici mes recommandations par ordre de préférence.\n\nPlusieurs fournisseurs :\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMes favoris puisqu’il s’agit d’une [association française.](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net/fr)\n\nQuand9 est une fondation à but non lucratif proposant des serveurs DNS publics et gratuits. Leurs serveur classiques offrent un filtrage de domaines malveillants identifiés. Ils ne collectent pas de données et sont conforment au \u003Cabbr title=\"Règlement général sur la protection des données\">RGPD\u003C/abbr>.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## C'est tout.\n\nEn modifiant ces réglages, vous vous affranchissez de vos fournisseurs d’accès et de leurs règles de filtrage du contenu.\n\nPour l’instant, ces blocages sont presque symboliques car si Sci-hub venait à changer d’url, le blocage ne fonctionnerait plus. Mais la victoire des éditeurs au tribunal montre qu’ils n’ont pas dit leur dernier mot. Nous ne sommes donc pas à l’abri d’un futur blocage plus large et plus dur à contrer.\n\nSi vous voulez en apprendre plus sur le combat de ces gens qui se battent pour que la recherche ne soit pas une marchandise, je vous conseille [ce documentaire](https://youtu.be/y_CQATGOX2w) sur Aaron Shwartz. Ou plus simplement [cet article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) sur la fondatrice de Sci-hub.\n\nEn attendant, bonnes lectures à tou·te·s. On est avec vous !","src/content/articles/fr/sci-hub-blocage.mdx","6438fdc02b91ec59","en-2022",{"id":670,"data":672,"body":678,"filePath":679,"digest":680,"rendered":681},{"title":673,"subtitle":674,"lang":409,"tags":675,"type":655,"slug":670,"createdAt":677},"Nico v2.0","2022 update of many things.",[676],"Freelance",["Date","2022-06-08T14:24:06.000Z"],"After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\n\n## Services\n\n### No more print\n\nEven though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for \"classic\" graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\n\n### Internet all the way\n\nOn the other hand, I spend my time **doing web stuff.** A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer **more specific web offerings,** in which I have specialised.\n\nThus, **accessibility** and **eco-design** become integrated expertises in my practice. They are no longer options on a quote but **my core business.**\n\n## The website\n\nI have reworked my website, especially the homepage and its content, to better reflect these decisions.\n\nI have also made several behavioural changes:\n\n- external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven't found a good reason to continue using this behaviour;\n- I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu);\n- \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\n- I only trigger animations if the user has not asked the system to reduce the amount motion [(reference)](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).\n\nI am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello [astro](https://astro.build/) 👀).\n\n## Le Nico\n\nOn a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\n\nI have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.","src/content/articles/en/2022.md","7b98592763cb0929",{"html":682,"metadata":683},"\u003Cp>After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\u003C/p>\n\u003Ch2 id=\"services\">Services\u003C/h2>\n\u003Ch3 id=\"no-more-print\">No more print\u003C/h3>\n\u003Cp>Even though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for “classic” graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\u003C/p>\n\u003Ch3 id=\"internet-all-the-way\">Internet all the way\u003C/h3>\n\u003Cp>On the other hand, I spend my time \u003Cstrong>doing web stuff.\u003C/strong> A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer \u003Cstrong>more specific web offerings,\u003C/strong> in which I have specialised.\u003C/p>\n\u003Cp>Thus, \u003Cstrong>accessibility\u003C/strong> and \u003Cstrong>eco-design\u003C/strong> become integrated expertises in my practice. They are no longer options on a quote but \u003Cstrong>my core business.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Cp>I have reworked my website, especially the homepage and its content, to better reflect these decisions.\u003C/p>\n\u003Cp>I have also made several behavioural changes:\u003C/p>\n\u003Cul>\n\u003Cli>external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven’t found a good reason to continue using this behaviour;\u003C/li>\n\u003Cli>I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a>;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\u003C/li>\n\u003Cli>I only trigger animations if the user has not asked the system to reduce the amount motion \u003Ca href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion\">(reference)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>I am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello \u003Ca href=\"https://astro.build/\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>On a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\u003C/p>\n\u003Cp>I have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.\u003C/p>",{"headings":684,"imagePaths":700,"frontmatter":701},[685,688,691,694,697],{"depth":80,"slug":686,"text":687},"services","Services",{"depth":120,"slug":689,"text":690},"no-more-print","No more print",{"depth":120,"slug":692,"text":693},"internet-all-the-way","Internet all the way",{"depth":80,"slug":695,"text":696},"the-website","The website",{"depth":80,"slug":698,"text":699},"le-nico","Le Nico",[],{"title":673,"subtitle":674,"lang":409,"slug":670,"excerpt":702,"tags":703,"type":655,"createdAt":253},"Changes in my services, the website and myself.",[676],"en-2023",{"id":704,"data":706,"body":712,"filePath":713,"digest":714,"rendered":715},{"title":707,"subtitle":708,"lang":409,"tags":709,"type":655,"slug":704,"createdAt":710,"updatedAt":711},"Nico v2.5","Update 2023.",[676],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"This article will be updated when I have something new to share during the year 2023.\n\n## The website\n\n### Technologies\n\nOops... I (re)did it again.\n\nI have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself [in 2022 !](/en/articles/2022/#the-website)\n\nI will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\n\nMy \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I'm back to a solid **95/100** without any particular optimization. With some small efforts, I've reached the good old 100/100.\n\nI then did a work of modernization of the codebase. Hello CSS variables and goodbye `media queries`. In no particular order, here are some of the improvements I made:\n\n- `flexbox` and `grid` to adapt the layout to different screen sizes;\n- CSS variables for colors, font sizes and margins;\n- some `container queries`, just to try;\n- logical CSS properties (`inline` and `block` instead of `width` and `height` for example).\n\nI took this opportunity to publish [the source code](https://git.nardu.in/nardu.in/website-astro) on my git repository.\n\n**Update #1:** I've added [an RSS feed](/en/rss.xml) as I find myself using it more and more on other websites.\n\n### Analytics\n\nI removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\n\nIt's nice to see that your site is consulted, but if there is no other purpose behind it, it's an extra resource loaded for nothing by visitors. Maybe I'll reactivate the tracking when I have a use for it (other than flattering my ego).\n\nPrevious visit reports can be found at [this link.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Content\n\n- I've added a [work](/en/work/) page to list some of my projects.\n- I've also added [a page](/en/veille/) where I list some interesting things from around the web.\n\n## Additional projects\n\nI'm still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at [3-w.fr](https://3-w.fr/) (an address I am very proud of).\n\nI have to update it more regularly but I hope that the platform will help students progress!\n\n**More to come soon!**","src/content/articles/en/2023.md","489c650e66cced63",{"html":716,"metadata":717},"\u003Cp>This article will be updated when I have something new to share during the year 2023.\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oops… I (re)did it again.\u003C/p>\n\u003Cp>I have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself \u003Ca href=\"/en/articles/2022/#the-website\">in 2022 !\u003C/a>\u003C/p>\n\u003Cp>I will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\u003C/p>\n\u003Cp>My \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I’m back to a solid \u003Cstrong>95/100\u003C/strong> without any particular optimization. With some small efforts, I’ve reached the good old 100/100.\u003C/p>\n\u003Cp>I then did a work of modernization of the codebase. Hello CSS variables and goodbye \u003Ccode>media queries\u003C/code>. In no particular order, here are some of the improvements I made:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> and \u003Ccode>grid\u003C/code> to adapt the layout to different screen sizes;\u003C/li>\n\u003Cli>CSS variables for colors, font sizes and margins;\u003C/li>\n\u003Cli>some \u003Ccode>container queries\u003C/code>, just to try;\u003C/li>\n\u003Cli>logical CSS properties (\u003Ccode>inline\u003C/code> and \u003Ccode>block\u003C/code> instead of \u003Ccode>width\u003C/code> and \u003Ccode>height\u003C/code> for example).\u003C/li>\n\u003C/ul>\n\u003Cp>I took this opportunity to publish \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">the source code\u003C/a> on my git repository.\u003C/p>\n\u003Cp>\u003Cstrong>Update #1:\u003C/strong> I’ve added \u003Ca href=\"/en/rss.xml\">an RSS feed\u003C/a> as I find myself using it more and more on other websites.\u003C/p>\n\u003Ch3 id=\"analytics\">Analytics\u003C/h3>\n\u003Cp>I removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\u003C/p>\n\u003Cp>It’s nice to see that your site is consulted, but if there is no other purpose behind it, it’s an extra resource loaded for nothing by visitors. Maybe I’ll reactivate the tracking when I have a use for it (other than flattering my ego).\u003C/p>\n\u003Cp>Previous visit reports can be found at \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">this link.\u003C/a>\u003C/p>\n\u003Ch3 id=\"content\">Content\u003C/h3>\n\u003Cul>\n\u003Cli>I’ve added a \u003Ca href=\"/en/work/\">work\u003C/a> page to list some of my projects.\u003C/li>\n\u003Cli>I’ve also added \u003Ca href=\"/en/veille/\">a page\u003C/a> where I list some interesting things from around the web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"additional-projects\">Additional projects\u003C/h2>\n\u003Cp>I’m still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (an address I am very proud of).\u003C/p>\n\u003Cp>I have to update it more regularly but I hope that the platform will help students progress!\u003C/p>\n\u003Cp>\u003Cstrong>More to come soon!\u003C/strong>\u003C/p>",{"headings":718,"imagePaths":732,"frontmatter":733},[719,720,723,726,729],{"depth":80,"slug":695,"text":696},{"depth":120,"slug":721,"text":722},"technologies","Technologies",{"depth":120,"slug":724,"text":725},"analytics","Analytics",{"depth":120,"slug":727,"text":728},"content","Content",{"depth":80,"slug":730,"text":731},"additional-projects","Additional projects",[],{"title":707,"subtitle":708,"lang":409,"slug":704,"excerpt":734,"tags":735,"type":655,"createdAt":736,"updatedAt":737},"New changes.",[676],"2023-02-03T17:41:00.000Z","2023-05-17T17:41:00.000Z","en-after-effects-expressions",{"id":738,"data":740,"body":746,"filePath":747,"digest":748,"deferredRender":264},{"title":741,"subtitle":742,"lang":409,"tags":743,"type":655,"slug":738,"createdAt":745,"code":264},"After Effects Expressions","Animation on steroïds.",[744],"Design",["Date","2019-04-24T09:00:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## An ever lasting battle\n\nThere is very little documentation and the existing one is hard to find or very old. Very often I just don't have the time to dive into expression learning while animating even though it could help the entire project on the long term.\nSo the last time I had to do a complex animation, **I took the damn time!**\n\n## The begining of the end (of keyframes).\n\nEveryone uses expressions whether they know it or not. Most of the time it's a rather transparent process for the animator. For example: when parenting a property to another one, After Effects creates an expression for us.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/basic_expression_d81b12f1ac.jpeg'\n\twidth='728'\n\theight='80'\n\talt='Parenting the position of the form to a null creates an expression.'\n/>\n\nOver the last updates, Adobe has made an effort to make expressions more accessible to everyone. For example, the expression box is now resembling a code editor thanks to code-coloring and auto-completion features. After Effects expression feel like JavaScript with custom functions.\n\nThose custom functions can be called through a menu once you enabled the expressions on a property. It offers organized shortcut and proper syntax to all of AE native functions and a bunch of JavaScript standard ones.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/shortcut_39cc19d383.jpeg'\n\twidth='728'\n\theight='322'\n\talt='Alt + Click the stopwatch to access the shortcuts.'\n/>\n\n## So I need to learn javascript to do motion design now?\n\n### Why bother?\n\nI know that most animators don't have any kind of development background. However, if Adobe thought it best to let us use expressions, I think we ought to, at least, try.\n\n> A lot of incredible professionals like [Mt Mograph](https://www.mtmograph.com/) and [Video Copilot](https://videocopilot.net/) use expressions.\n\nLike every optimization process, building an expressions knowledge takes time. However, like all optimization process, you will benefit from it afterwards.\n\n### Where to learn\n\nI've gathered a list of my favourite learning grounds. Plenty more exist, **go get'em!**\n\n- [Adobe official expression starter guide (FR)](https://helpx.adobe.com/fr/after-effects/using/expression-language-reference.html)\n- [Adobe official expression basic (EN)](https://helpx.adobe.com/after-effects/using/expression-basics.html)\n- [Adobe forums for expressions](https://community.adobe.com/t5/after-effects/bd-p/after-effects?page=1&sort=latest_replies&filter=all&topics=label-expressions)\n- [Creative Cow expressions forums](https://creativecow.net/forums/forum/adobe-after-effects-expressions/)\n- [Youtube channel about expressions](https://www.youtube.com/playlist?list=PLvr5U5ZSt6IzHyvSL9fo0M9NRPsTvra31)\n- [All expressions explained](http://aescript.jecool.net/reference/)\n- [All expressions explained again](http://expressions.aenhancers.com/index.html)\n- [Nice examples of basic expressions](https://www.schoolofmotion.com/tutorials/amazing-expressions-in-after-effects)\n\n## Real world example\n\n### Number counter\n\nLet's say you need to animate a rather simple counter from 0% to 100%.\n\n- Start by creating a text layer. Define your typographic choices, colours, etc.\n- On the effect menu add expression options > slider control\n- Alt + Click the Source text property\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/alt-counter.mp4' type='video/mp4' />\n\u003C/video>\n\n- Parent the source text to the slider control through the pickwhip.\n\n\u003Cvideo width='462' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/pickwhip.mp4' type='video/mp4' />\n\u003C/video>\n\nYou should get something like this in the expressions panel:\n\n```javascript\neffect(\"Slider Control\")(\"Slider\")​\n```\n\n- Set two keyframes on the slider from 0 to 100. The text should update accordingly.\n- By default, After Effects does not round numbers. In the expression panel, wrap your expression with the `Math.round()` function.\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/round.mp4' type='video/mp4' />\n\u003C/video>\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\"))​\n```\n\nGreat! We have a working counter. But we wanted a percentage counter. We could add a % glyph in another text layer but let's not.\n\nStill in the expression panel, we're going to add a string containing the % glyph, using basic JavaScript concatenation: `+ '%'`\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\")) + '%'​\n```\n\n\u003Cvideo width='538' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/percent.mp4' type='video/mp4' />\n\u003C/video>\n\n**And there we go!** A fully functioning and customizable counter using a slider controller and expressions.","src/content/articles/en/after-effects-expressions.mdx","3b6f88fbf35af1a4","en-faq",{"id":749,"data":751,"body":755,"filePath":756,"digest":757,"rendered":758},{"title":752,"subtitle":529,"lang":409,"tags":753,"type":655,"slug":749,"createdAt":754,"draft":264},"Accessibility and sobriety",[676],["Date","2022-06-22T15:34:45.000Z"],"[Go back to available articles](/en/articles)","src/content/articles/en/faq.md","82d516449896f6ca",{"html":759,"metadata":760},"\u003Cp>\u003Ca href=\"/en/articles\">Go back to available articles\u003C/a>\u003C/p>",{"headings":761,"imagePaths":762,"frontmatter":763},[],[],{"title":752,"subtitle":529,"lang":409,"slug":749,"draft":264,"excerpt":764,"tags":765,"type":655,"createdAt":364},"Why, how et and especially what.",[676],"en-gratuiste",{"id":766,"data":768,"body":755,"filePath":772,"digest":773,"rendered":774},{"title":769,"subtitle":529,"lang":409,"tags":770,"type":655,"slug":766,"createdAt":771,"draft":264},"Gratuiste",[744,676],["Date","2017-05-27T07:47:36.000Z"],"src/content/articles/en/gratuiste.md","ebec75d19f0ff741",{"html":759,"metadata":775},{"headings":776,"imagePaths":777,"frontmatter":778},[],[],{"title":769,"subtitle":529,"lang":409,"slug":766,"draft":264,"excerpt":529,"tags":779,"type":655,"createdAt":780},[744,676],"2017-05-27T07:47:36.000Z","en-sci-hub-unblock",{"id":781,"data":783,"body":789,"filePath":790,"digest":791,"deferredRender":264},{"title":784,"subtitle":785,"lang":409,"tags":786,"type":655,"slug":781,"createdAt":787,"updatedAt":788},"Access blocked Sci-hub","The science of sharing.",[663,664],["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nThe current sci-hub address is: \u003Ca href=\"https://sci-hub.se\" rel=\"noreferer noopener\">sci-hub.se\u003C/a>\n\n## What is this about?\n\nNot being a researcher myself, here’s an [extremely well done explanatory video](https://youtu.be/rcgxY__YXEc) on the subject of scientific publication (french audio with auto subtitle).\n\n> “This is outrageous!”​\n\nI noticed that my ISP was indeed blocking access. I have not yet been able to check for the other suppliers, but I imagine that they have all complied with the court decision.\nThe restriction in place is quite basic. This is a “DNS” block. A DNS is a server that is used to link a domain name: **www.sci-hub.tw** to an IP address: **186.2.163.90**\nIt is, in a way, the Internet phone book. Without the address, it is impossible to contact the domain. What ISPs have certainly done: block requests to the [sci-hub.se.](http://sci-hub.se/) domain name. As a result, no IP address is returned and the site is not accessible.\n\n## How to bypass this?\n\n- Either by using a VPN\n- Either by modifying the DNS servers of your computers/Internet box\n\nI would recommend the second solution because it allows you to protect yourself against future blockages/filtering/censorship from your ISP and does not require any financial compensation.\nI will focus on change from a computer because it will be effective wherever you are and not only from your home.\n\n### MacOs\n\nGo to:\n\n1. System Preferences\n1. Network\n1. (wi-fi and/or ethernet)\n1. Advanced\n1. DNS\n\nFrom there, you can add DNS servers by clicking the + icon. Click ok and apply the new settings. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS network and DNS settings'\n/>\n\n### Windows (10)\n\nGo to:\n\n1. System Settings\n1. Network & Internet\n1. Change adapter options\n1. Right click your adapter then “properties”\n1. Select “internet protocol version 4” (and/or 6)\n1. Properties\n1. Use the following DNS server addresses\n\nFrom there, you can add DNS servers. Click save. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Windows system settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows network settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows network connections settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows network adapter settings'\n/>\n\n## Which DNS?\n\nThere are many DNS servers available. The best known are Google, Cloudflare and OpenDNS. If you really want to use Google’s, I’ll let you look up their address. Here are my recommendations in order of preference.\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMy favorite since it is a [french association](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net)\n\nQuand9 is a non-profit foundation offering free public DNS servers. Their classic servers offer filtering of identified malicious domains. They do not collect data and are \u003Cabbr title=\"General Data Protection Regulation\">GDPR\u003C/abbr>-compliant.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## That's it.\n\nBy changing these settings, you are free from your ISPs and their content filtering rules.\n\nFor the moment, these restrictions are almost symbolic because if Sci-hub were to change its url, the block would no longer work. But the publishers’ victory in court shows that they have not had their last word. We are therefore not immune to a wider and stronger block in the future.\n\nIf you want to learn more about the struggle of the people who fight to ensure that research is not a paid commodity, I recommend [this documentary](https://youtu.be/y_CQATGOX2w) on Aaron Shwartz. Or [this article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) about the founder of Sci-hub.\n\nIn the meantime, good readings to all of you. We stand with you!","src/content/articles/en/sci-hub-blocage.mdx","8959506d941cdcc5","en-the-day-I-jamd",{"id":792,"data":794,"body":802,"filePath":803,"digest":804,"deferredRender":264},{"title":795,"subtitle":796,"lang":409,"tags":797,"type":655,"slug":792,"createdAt":800,"updatedAt":801},"The day I Jam’d","A story of unusual tools and fun gambles.",[798,799],"Dev","Jamstack",["Date","2020-10-08T09:00:00.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## The not so easy choice\n\nWhen I was still using Wordpress for my personal website, I thought it would be nice to try [OpenLiteSpeed](https://openlitespeed.org) webserver. Being a designer, I always like to have a graphical interface and I heard OLS had very nice caching and overall performances.\n\n## FIGHT!\n\nA few years later, I learned about Jamstack and its incredible potential. Not being impulsive at all, I chose to entirely remake my website with tools like [11ty](https://www.11ty.dev/) and [Strapi](https://strapi.io/).\n\nI remember Strapi still being in alpha/beta and colleagues telling me it was a risky gamble, especially since I was pretty new to the node.js world.\n\n> Open source and french? Sign me up!\n\nSo I started recreating my website identically with 11ty and Strapi. Same hosting on a Digital Ocean droplet, same webserver, same content. I had done a fair amout of performance optimizations on my wordpress install so I was eager to compare the results with the new static version.\n\nBoy did they exceed my expectations! With almost no optimization on the static side, I got the following results.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 53/100 on Wordpress.'\n/>\n\nDespite a lot of efforts I could not do better. I’m no expert in caching, do not use CDN and relied on plugins to achieve a lot of stuff (php not being my strongest skill 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 97/100 on jamstack.'\n/>\n\nAlmost **zero** special configuration (I was too anxious to test) and I reached an awesome score. I know lighthouse scores are not everything but hey, **53 vs 97**… I’ll take it!\n\n## Now kiss 🥰\n\nBoth of these approaches have their benefits and drawbacks. As a freelance, my clients often prefer or ask for Wordpress because of its reputation. I always present a Jamstack alternative when possible but it’s still scary to most compared to Wordpress. I feel however that it’s going to be easier to use Jamstack with time.\n\n## I did it again…\n\nHere we are now, a quarantine and a few months later and this website is running with… [Nuxt.js](https://nuxtjs.org/). I know, I’m sorry, I couldn’t resist the latest [nuxt content](https://content.nuxtjs.org/) functionnality.\n\nSo I re-did everything again… and let me just say: **wow**, what an experience!\nI **love** developing with Nuxt. Using nuxt content allowed me to focus on design and, well, content.\nNo more Apollo client and graphQL query, only markdown and a few promises.\n\nDon’t get me wrong, I really like working with Strapi and its graphQL capabilities but for the purpose of this website, nuxt content does it (extremely well).\n\nI’m still using Strapi as a way to upload, store and manage images, videos, gifs, etc. It might be too much for this use case but I like to know that I can still go back to it if I want to! Also, I spent quite a bit of time setting it up with OpenLiteSpeed and I’m still too attached to this accomplishment to let it go.\n\n## In the end\n\nWordpress, Jamstack, vanilla everything… Does it really matter? For me, the dev experience was far more enjoyable working with 11ty, nuxt.js and strapi than with Wordpress.\n\nOn the performance and accessibility side, it also seems to be the better/smarter choice. It might not be everytime! ¯\\\\\\_(ツ)\\_/¯\n\nCan’t wait to learn [astro](https://astro.build/) and start from scratch again!","src/content/articles/en/the-day-I-jamd.mdx","60b77e216e02f618","en-video-compression",{"id":805,"data":807,"body":813,"filePath":814,"digest":815,"deferredRender":264},{"title":808,"subtitle":809,"lang":409,"tags":810,"type":655,"slug":805,"createdAt":811,"updatedAt":812},"Video compression","Encode like you mean it.",[744],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Let's play.\n\nVideos are everywhere. **EVERYWHERE!** But videos can and will be huge when 4k becomes an internet standard. Currently, 1920x1080 is king and we usually have no problem hosting or playing this resolution.\n\n## Because we can doesn't mean we should.\n\nRight now, the (good) trend of web performance is on the rise. Everyone wants a blazing fast loading website, which might not be possible if we send requests to 100mb (or even more) videos.\n\nWith a good connection, users will not see the difference. But if we go down that path, nor will they with a 300mb one. So the goal is to make every asset as small as possible. It's already the case with images. But it's simpler and faster than video encoding.\n\n## Small size, best quality.\n\nLet's say we exported​ a 1920x1080 video from Premiere Pro with these basic settings:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-premiere-1.jpeg'\n\twidth='673'\n\theight='800'\n/>\n\nIt's gorgeous, it's Full HD, it's 1:30 minute of excellent editing but it's 50mb… What a shame.\n\n> We can already bring down the size from Premiere or Media Encoder by selecting CBR instead of VBR and using a low bitrate (like 2 or 3).\n\nLet's now use [Handbrake!](https://handbrake.fr/) It's free, open source and multi platform. You can also read this great article from [Ueno](https://loremipsum.ueno.co/dear-ueno-how-do-you-compress-videos-6657ebd9dd28?gi=930afecec398) on video encoding.\n\n**Please please PLEASE. Never export videos from within After Effects.**\n\n## Handbrake\n\n### Summary screen\n\nWhile it's not as nice as Premiere Pro, it has way more exporting capabilities. Follow these steps to use good standard settings:\n\n1. Open your source video\n1. Select a preset corresponding to your future usage like Fast 1080p30\n1. Check Web Optimized\n1. Keep MPEG-4 as the format\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-1.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Video screen\n\n1. Keep H.264 (x264) or use H.264 nvidia nvenc if you can (crazy fast encoding by nvidia)\n1. Choose Constant Quality and try a value between 20 and 30​ (higher = smaller size but lower quality)\n1. Choose Peak Framerate. If you don't know the framerate, keep the default setting\n1. Choose the type of video you are encoding (film, animation…)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-2.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Audio screen\n\nIf you don't have audio, be sure to set the audio channel to none.\nIf you have an audio channel, these settings are great and will not influence the size much​:\n\n1. Codec AAC\n1. Samplerate 44.1\n1. Bitrate 192 to 256 (your choice)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-3.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Export!\n\nI used a RF of 25 for this example and no audio.\n\n1. My Premiere Pro video was 50,6mb\n1. My Handbrake video is 5,5mb​\n\n> What a save!\n\n​I ended up dividing the original size by 10. Which is cool.\nI tried with a RF of 30. The video was still pretty good and only 3,3mb.\n\n## Exporting for the web\n\nNow that we know how to properly compress videos, let's go further. Say we have a website with a lot of videos on the same page. We still want to load the content as fast as possible. So our videos need to be as small as possible. We won't do better than previously seen using mp4/H.264. However, we can use **webm/VP9.**\nWebm is an html video format and VP9 is its latest codec.\n\nUsing Handbrake and webm/VP9, we can achieve really great compression without losing too much quality (or none at all depending on the settings). I was able to divide by 4 the size of a video using these presets:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-4.jpg'\n\twidth='728'\n\theight='313'\n\talt=''\n/>\n\nThe only down side is that it takes some time to encode. It will depend on the video length and your computing power.\n\nI tried various settings but I read [here](https://trac.ffmpeg.org/wiki/Encode/VP9) that VP9 is supposed to be used with two-pass encoding. You then have to find the right bitrate (here 1000) for your situation.","src/content/articles/en/video-compression.mdx","5bb9f69df6c651d1"] \ No newline at end of file +[["Map",1,2,9,10,61,62,427,428,888,889,998,999],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.1.1","content-config-digest","8021b3469f132349","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"site\":\"https://www.nardu.in\",\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[\"assets.nardu.in\"],\"remotePatterns\":[{\"protocol\":\"https\"}]},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":\"shiki\",\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"i18n\":{\"defaultLocale\":\"fr\",\"locales\":[\"fr\",\"en\"],\"routing\":{\"prefixDefaultLocale\":false,\"redirectToDefaultLocale\":true,\"fallbackType\":\"redirect\"}},\"security\":{\"checkOrigin\":true},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"responsiveImages\":false},\"legacy\":{\"collections\":false}}","references",["Map",11,12,25,26,39,40,50,51],"3w",{"id":11,"data":13,"filePath":21,"digest":22,"rendered":23},{"title":11,"subtitle":14,"url":15,"lang":16,"slug":11,"tags":17,"createdAt":20},"J'ai fait de la doc!","https://3-w.fr","fr",[18,19],"Front-end","documentation",["Date","2022-10-19T18:02:00.000Z"],"src/content/references/3w.md","0d3d94c8af754e1b",{"html":24},"","natureo",{"id":25,"data":27,"filePath":36,"digest":37,"rendered":38},{"title":28,"subtitle":29,"url":30,"lang":16,"slug":25,"tags":31,"createdAt":35},"Nature en Occitanie","La sobriété au naturel.","https://www.natureo.org/",[18,32,33,34],"accessibilité","éco-conception","CMS",["Date","2023-04-19T18:02:00.000Z"],"src/content/references/natureo.md","6a7169b855b57024",{"html":24},"parole-expression",{"id":39,"data":41,"filePath":47,"digest":48,"rendered":49},{"title":42,"subtitle":43,"url":44,"lang":16,"slug":39,"tags":45,"createdAt":46},"Parole Expression","Un nouveau site pour l'association.","https://www.paroleexpression.fr/",[18,33,34],["Date","2022-04-19T17:11:00.000Z"],"src/content/references/parole-expression.md","ec95a408f8c3e99c",{"html":24},"rose-primaire",{"id":50,"data":52,"filePath":58,"digest":59,"rendered":60},{"title":53,"subtitle":54,"url":55,"lang":16,"slug":50,"tags":56,"createdAt":57},"Rose Primaire","Une agence comme on l'aime.","https://roseprimaire.com/",[18,32,33,34],["Date","2023-04-19T17:11:00.000Z"],"src/content/references/rose-primaire.md","a0133200cf1bee58",{"html":24},"articles",["Map",63,64,76,77,89,90,102,103,113,114,124,125,134,135,171,172,205,206,224,225,239,240,269,270,298,299,315,316,366,367,410,411],"en-after-effects-expressions",{"id":63,"data":65,"body":73,"filePath":74,"digest":75,"deferredRender":72},{"title":66,"subtitle":67,"lang":68,"tags":69,"type":61,"slug":63,"createdAt":71,"code":72},"After Effects Expressions","Animation on steroïds.","en",[70],"Design",["Date","2019-04-24T09:00:00.000Z"],true,"import AstroImage from '../../../components/AstroImage.astro'\n\n## An ever lasting battle\n\nThere is very little documentation and the existing one is hard to find or very old. Very often I just don't have the time to dive into expression learning while animating even though it could help the entire project on the long term.\nSo the last time I had to do a complex animation, **I took the damn time!**\n\n## The begining of the end (of keyframes).\n\nEveryone uses expressions whether they know it or not. Most of the time it's a rather transparent process for the animator. For example: when parenting a property to another one, After Effects creates an expression for us.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/basic_expression_d81b12f1ac.jpeg'\n\twidth='728'\n\theight='80'\n\talt='Parenting the position of the form to a null creates an expression.'\n/>\n\nOver the last updates, Adobe has made an effort to make expressions more accessible to everyone. For example, the expression box is now resembling a code editor thanks to code-coloring and auto-completion features. After Effects expression feel like JavaScript with custom functions.\n\nThose custom functions can be called through a menu once you enabled the expressions on a property. It offers organized shortcut and proper syntax to all of AE native functions and a bunch of JavaScript standard ones.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/shortcut_39cc19d383.jpeg'\n\twidth='728'\n\theight='322'\n\talt='Alt + Click the stopwatch to access the shortcuts.'\n/>\n\n## So I need to learn javascript to do motion design now?\n\n### Why bother?\n\nI know that most animators don't have any kind of development background. However, if Adobe thought it best to let us use expressions, I think we ought to, at least, try.\n\n> A lot of incredible professionals like [Mt Mograph](https://www.mtmograph.com/) and [Video Copilot](https://videocopilot.net/) use expressions.\n\nLike every optimization process, building an expressions knowledge takes time. However, like all optimization process, you will benefit from it afterwards.\n\n### Where to learn\n\nI've gathered a list of my favourite learning grounds. Plenty more exist, **go get'em!**\n\n- [Adobe official expression starter guide (FR)](https://helpx.adobe.com/fr/after-effects/using/expression-language-reference.html)\n- [Adobe official expression basic (EN)](https://helpx.adobe.com/after-effects/using/expression-basics.html)\n- [Adobe forums for expressions](https://community.adobe.com/t5/after-effects/bd-p/after-effects?page=1&sort=latest_replies&filter=all&topics=label-expressions)\n- [Creative Cow expressions forums](https://creativecow.net/forums/forum/adobe-after-effects-expressions/)\n- [Youtube channel about expressions](https://www.youtube.com/playlist?list=PLvr5U5ZSt6IzHyvSL9fo0M9NRPsTvra31)\n- [All expressions explained](http://aescript.jecool.net/reference/)\n- [All expressions explained again](http://expressions.aenhancers.com/index.html)\n- [Nice examples of basic expressions](https://www.schoolofmotion.com/tutorials/amazing-expressions-in-after-effects)\n\n## Real world example\n\n### Number counter\n\nLet's say you need to animate a rather simple counter from 0% to 100%.\n\n- Start by creating a text layer. Define your typographic choices, colours, etc.\n- On the effect menu add expression options > slider control\n- Alt + Click the Source text property\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/alt-counter.mp4' type='video/mp4' />\n\u003C/video>\n\n- Parent the source text to the slider control through the pickwhip.\n\n\u003Cvideo width='462' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/pickwhip.mp4' type='video/mp4' />\n\u003C/video>\n\nYou should get something like this in the expressions panel:\n\n```javascript\neffect(\"Slider Control\")(\"Slider\")​\n```\n\n- Set two keyframes on the slider from 0 to 100. The text should update accordingly.\n- By default, After Effects does not round numbers. In the expression panel, wrap your expression with the `Math.round()` function.\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/round.mp4' type='video/mp4' />\n\u003C/video>\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\"))​\n```\n\nGreat! We have a working counter. But we wanted a percentage counter. We could add a % glyph in another text layer but let's not.\n\nStill in the expression panel, we're going to add a string containing the % glyph, using basic JavaScript concatenation: `+ '%'`\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\")) + '%'​\n```\n\n\u003Cvideo width='538' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/percent.mp4' type='video/mp4' />\n\u003C/video>\n\n**And there we go!** A fully functioning and customizable counter using a slider controller and expressions.","src/content/articles/en/after-effects-expressions.mdx","3b6f88fbf35af1a4","en-sci-hub-unblock",{"id":76,"data":78,"body":86,"filePath":87,"digest":88,"deferredRender":72},{"title":79,"subtitle":80,"lang":68,"tags":81,"type":61,"slug":76,"createdAt":84,"updatedAt":85},"Access blocked Sci-hub","The science of sharing.",[82,83],"Internet","Science",["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nThe current sci-hub address is: \u003Ca href=\"https://sci-hub.se\" rel=\"noreferer noopener\">sci-hub.se\u003C/a>\n\n## What is this about?\n\nNot being a researcher myself, here’s an [extremely well done explanatory video](https://youtu.be/rcgxY__YXEc) on the subject of scientific publication (french audio with auto subtitle).\n\n> “This is outrageous!”​\n\nI noticed that my ISP was indeed blocking access. I have not yet been able to check for the other suppliers, but I imagine that they have all complied with the court decision.\nThe restriction in place is quite basic. This is a “DNS” block. A DNS is a server that is used to link a domain name: **www.sci-hub.tw** to an IP address: **186.2.163.90**\nIt is, in a way, the Internet phone book. Without the address, it is impossible to contact the domain. What ISPs have certainly done: block requests to the [sci-hub.se.](http://sci-hub.se/) domain name. As a result, no IP address is returned and the site is not accessible.\n\n## How to bypass this?\n\n- Either by using a VPN\n- Either by modifying the DNS servers of your computers/Internet box\n\nI would recommend the second solution because it allows you to protect yourself against future blockages/filtering/censorship from your ISP and does not require any financial compensation.\nI will focus on change from a computer because it will be effective wherever you are and not only from your home.\n\n### MacOs\n\nGo to:\n\n1. System Preferences\n1. Network\n1. (wi-fi and/or ethernet)\n1. Advanced\n1. DNS\n\nFrom there, you can add DNS servers by clicking the + icon. Click ok and apply the new settings. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS network and DNS settings'\n/>\n\n### Windows (10)\n\nGo to:\n\n1. System Settings\n1. Network & Internet\n1. Change adapter options\n1. Right click your adapter then “properties”\n1. Select “internet protocol version 4” (and/or 6)\n1. Properties\n1. Use the following DNS server addresses\n\nFrom there, you can add DNS servers. Click save. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Windows system settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows network settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows network connections settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows network adapter settings'\n/>\n\n## Which DNS?\n\nThere are many DNS servers available. The best known are Google, Cloudflare and OpenDNS. If you really want to use Google’s, I’ll let you look up their address. Here are my recommendations in order of preference.\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMy favorite since it is a [french association](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net)\n\nQuand9 is a non-profit foundation offering free public DNS servers. Their classic servers offer filtering of identified malicious domains. They do not collect data and are \u003Cabbr title=\"General Data Protection Regulation\">GDPR\u003C/abbr>-compliant.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## That's it.\n\nBy changing these settings, you are free from your ISPs and their content filtering rules.\n\nFor the moment, these restrictions are almost symbolic because if Sci-hub were to change its url, the block would no longer work. But the publishers’ victory in court shows that they have not had their last word. We are therefore not immune to a wider and stronger block in the future.\n\nIf you want to learn more about the struggle of the people who fight to ensure that research is not a paid commodity, I recommend [this documentary](https://youtu.be/y_CQATGOX2w) on Aaron Shwartz. Or [this article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) about the founder of Sci-hub.\n\nIn the meantime, good readings to all of you. We stand with you!","src/content/articles/en/sci-hub-blocage.mdx","8959506d941cdcc5","en-the-day-I-jamd",{"id":89,"data":91,"body":99,"filePath":100,"digest":101,"deferredRender":72},{"title":92,"subtitle":93,"lang":68,"tags":94,"type":61,"slug":89,"createdAt":97,"updatedAt":98},"The day I Jam’d","A story of unusual tools and fun gambles.",[95,96],"Dev","Jamstack",["Date","2020-10-08T09:00:00.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## The not so easy choice\n\nWhen I was still using Wordpress for my personal website, I thought it would be nice to try [OpenLiteSpeed](https://openlitespeed.org) webserver. Being a designer, I always like to have a graphical interface and I heard OLS had very nice caching and overall performances.\n\n## FIGHT!\n\nA few years later, I learned about Jamstack and its incredible potential. Not being impulsive at all, I chose to entirely remake my website with tools like [11ty](https://www.11ty.dev/) and [Strapi](https://strapi.io/).\n\nI remember Strapi still being in alpha/beta and colleagues telling me it was a risky gamble, especially since I was pretty new to the node.js world.\n\n> Open source and french? Sign me up!\n\nSo I started recreating my website identically with 11ty and Strapi. Same hosting on a Digital Ocean droplet, same webserver, same content. I had done a fair amout of performance optimizations on my wordpress install so I was eager to compare the results with the new static version.\n\nBoy did they exceed my expectations! With almost no optimization on the static side, I got the following results.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 53/100 on Wordpress.'\n/>\n\nDespite a lot of efforts I could not do better. I’m no expert in caching, do not use CDN and relied on plugins to achieve a lot of stuff (php not being my strongest skill 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 97/100 on jamstack.'\n/>\n\nAlmost **zero** special configuration (I was too anxious to test) and I reached an awesome score. I know lighthouse scores are not everything but hey, **53 vs 97**… I’ll take it!\n\n## Now kiss 🥰\n\nBoth of these approaches have their benefits and drawbacks. As a freelance, my clients often prefer or ask for Wordpress because of its reputation. I always present a Jamstack alternative when possible but it’s still scary to most compared to Wordpress. I feel however that it’s going to be easier to use Jamstack with time.\n\n## I did it again…\n\nHere we are now, a quarantine and a few months later and this website is running with… [Nuxt.js](https://nuxtjs.org/). I know, I’m sorry, I couldn’t resist the latest [nuxt content](https://content.nuxtjs.org/) functionnality.\n\nSo I re-did everything again… and let me just say: **wow**, what an experience!\nI **love** developing with Nuxt. Using nuxt content allowed me to focus on design and, well, content.\nNo more Apollo client and graphQL query, only markdown and a few promises.\n\nDon’t get me wrong, I really like working with Strapi and its graphQL capabilities but for the purpose of this website, nuxt content does it (extremely well).\n\nI’m still using Strapi as a way to upload, store and manage images, videos, gifs, etc. It might be too much for this use case but I like to know that I can still go back to it if I want to! Also, I spent quite a bit of time setting it up with OpenLiteSpeed and I’m still too attached to this accomplishment to let it go.\n\n## In the end\n\nWordpress, Jamstack, vanilla everything… Does it really matter? For me, the dev experience was far more enjoyable working with 11ty, nuxt.js and strapi than with Wordpress.\n\nOn the performance and accessibility side, it also seems to be the better/smarter choice. It might not be everytime! ¯\\\\\\_(ツ)\\_/¯\n\nCan’t wait to learn [astro](https://astro.build/) and start from scratch again!","src/content/articles/en/the-day-I-jamd.mdx","60b77e216e02f618","en-video-compression",{"id":102,"data":104,"body":110,"filePath":111,"digest":112,"deferredRender":72},{"title":105,"subtitle":106,"lang":68,"tags":107,"type":61,"slug":102,"createdAt":108,"updatedAt":109},"Video compression","Encode like you mean it.",[70],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Let's play.\n\nVideos are everywhere. **EVERYWHERE!** But videos can and will be huge when 4k becomes an internet standard. Currently, 1920x1080 is king and we usually have no problem hosting or playing this resolution.\n\n## Because we can doesn't mean we should.\n\nRight now, the (good) trend of web performance is on the rise. Everyone wants a blazing fast loading website, which might not be possible if we send requests to 100mb (or even more) videos.\n\nWith a good connection, users will not see the difference. But if we go down that path, nor will they with a 300mb one. So the goal is to make every asset as small as possible. It's already the case with images. But it's simpler and faster than video encoding.\n\n## Small size, best quality.\n\nLet's say we exported​ a 1920x1080 video from Premiere Pro with these basic settings:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-premiere-1.jpeg'\n\twidth='673'\n\theight='800'\n/>\n\nIt's gorgeous, it's Full HD, it's 1:30 minute of excellent editing but it's 50mb… What a shame.\n\n> We can already bring down the size from Premiere or Media Encoder by selecting CBR instead of VBR and using a low bitrate (like 2 or 3).\n\nLet's now use [Handbrake!](https://handbrake.fr/) It's free, open source and multi platform. You can also read this great article from [Ueno](https://loremipsum.ueno.co/dear-ueno-how-do-you-compress-videos-6657ebd9dd28?gi=930afecec398) on video encoding.\n\n**Please please PLEASE. Never export videos from within After Effects.**\n\n## Handbrake\n\n### Summary screen\n\nWhile it's not as nice as Premiere Pro, it has way more exporting capabilities. Follow these steps to use good standard settings:\n\n1. Open your source video\n1. Select a preset corresponding to your future usage like Fast 1080p30\n1. Check Web Optimized\n1. Keep MPEG-4 as the format\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-1.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Video screen\n\n1. Keep H.264 (x264) or use H.264 nvidia nvenc if you can (crazy fast encoding by nvidia)\n1. Choose Constant Quality and try a value between 20 and 30​ (higher = smaller size but lower quality)\n1. Choose Peak Framerate. If you don't know the framerate, keep the default setting\n1. Choose the type of video you are encoding (film, animation…)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-2.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Audio screen\n\nIf you don't have audio, be sure to set the audio channel to none.\nIf you have an audio channel, these settings are great and will not influence the size much​:\n\n1. Codec AAC\n1. Samplerate 44.1\n1. Bitrate 192 to 256 (your choice)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-3.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Export!\n\nI used a RF of 25 for this example and no audio.\n\n1. My Premiere Pro video was 50,6mb\n1. My Handbrake video is 5,5mb​\n\n> What a save!\n\n​I ended up dividing the original size by 10. Which is cool.\nI tried with a RF of 30. The video was still pretty good and only 3,3mb.\n\n## Exporting for the web\n\nNow that we know how to properly compress videos, let's go further. Say we have a website with a lot of videos on the same page. We still want to load the content as fast as possible. So our videos need to be as small as possible. We won't do better than previously seen using mp4/H.264. However, we can use **webm/VP9.**\nWebm is an html video format and VP9 is its latest codec.\n\nUsing Handbrake and webm/VP9, we can achieve really great compression without losing too much quality (or none at all depending on the settings). I was able to divide by 4 the size of a video using these presets:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-4.jpg'\n\twidth='728'\n\theight='313'\n\talt=''\n/>\n\nThe only down side is that it takes some time to encode. It will depend on the video length and your computing power.\n\nI tried various settings but I read [here](https://trac.ffmpeg.org/wiki/Encode/VP9) that VP9 is supposed to be used with two-pass encoding. You then have to find the right bitrate (here 1000) for your situation.","src/content/articles/en/video-compression.mdx","5bb9f69df6c651d1","sci-hub-blocage",{"id":113,"data":115,"body":121,"filePath":122,"digest":123,"deferredRender":72},{"title":116,"subtitle":117,"lang":16,"tags":118,"type":61,"slug":113,"createdAt":119,"updatedAt":120},"Sci-hub bloqué, comment contourner","La science du partage.",[82,83],["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nL'adresse actuelle de sci-hub est : [sci-hub.se](https://sci-hub.se)\n\n## Résumé de la situation\n\nN’étant pas moi-même directement chercheur, je vous laisse regarder [cette vidéo](https://youtu.be/rcgxY__YXEc) explicative extrêmement bien faite sur le sujet de la publication scientifique.\n\n> “ Mais c’est scandaleux ! ”​\n\nJ’ai constaté que le blocage était actif chez SFR. Je n’ai pas encore pu vérifier pour les autres fournisseurs mais j’imagine qu’ils se sont tous conformés à la décision de justice.\nLe blocage mis en place est assez basique. Il s’agit d’un blocage “ DNS ”.\n\nUn DNS est un serveur qui sert à faire le lien entre un nom de domaine : **sci-hub.tw** et une adresse IP : **186.2.163.90**.\n\nC’est en quelque sorte l’annuaire d’internet. Sans l’adresse, impossible de contacter le domaine. Ce que les FAI ont certainement fait : bloquer les requêtes au nom de domaine [sci-hub.se.](http://sci-hub.se/) Ainsi, aucune adresse IP n’est renvoyée et le site n’est pas accessible.\n\n## Comment contourner ce blocage ?\n\n- Soit en utilisant un VPN\n- Soit en modifiant les serveurs DNS de vos ordinateurs/box internet\n\nJe recommande la deuxième solution car elle permet de se prémunir contre de futurs blocages/filtrages/censures de la part de votre FAI et ne nécessite pas de contrepartie financière.\nJe vais me focaliser sur le changement depuis un ordinateur car il sera effectif où que vous soyez.\n\n### Sur MacOs\n\nOuvrez :\n\n1. Préférences système\n1. Réseau\n1. Ethernet et/ou Wi-fi\n1. Avancé\n1. DNS\n1. Serveurs DNS\n\nDe là, vous pouvez ajouter des serveurs DNS en cliquant sur l'icône +. Cliquez sur ok et appliquez les nouveaux paramètres. Vous devrez peut-être redémarrer votre ordinateur pour que les changements fonctionnent.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS réglages réseau et DNS'\n/>\n\n### Sur Windows (ici 10)\n\nOuvrez :\n\n1. Réglages\n1. Réseau et internet\n1. Modifier les options de l'adaptateur\n1. Clic droit sur les propriétés de votre interface réseau\n1. Selectionnez « protocole Internet version 4 » (et/ou 6)\n1. Propriétés\n1. Utiliser l’adresse de serveur DNS suivante\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Réglages windows'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows réglages réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows régalges connections réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows options adaptateur réseau'\n/>\n\n## Quels serveurs DNS utiliser ?\n\nIl y a de nombreux serveurs DNS accessibles. Les plus connus étant ceux de Google, Cloudflare et OpenDNS. Si vous tenez vraiment à utiliser ceux de Google, je vous laisse chercher leur adresse. Voici mes recommandations par ordre de préférence.\n\nPlusieurs fournisseurs :\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMes favoris puisqu’il s’agit d’une [association française.](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net/fr)\n\nQuand9 est une fondation à but non lucratif proposant des serveurs DNS publics et gratuits. Leurs serveur classiques offrent un filtrage de domaines malveillants identifiés. Ils ne collectent pas de données et sont conforment au \u003Cabbr title=\"Règlement général sur la protection des données\">RGPD\u003C/abbr>.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## C'est tout.\n\nEn modifiant ces réglages, vous vous affranchissez de vos fournisseurs d’accès et de leurs règles de filtrage du contenu.\n\nPour l’instant, ces blocages sont presque symboliques car si Sci-hub venait à changer d’url, le blocage ne fonctionnerait plus. Mais la victoire des éditeurs au tribunal montre qu’ils n’ont pas dit leur dernier mot. Nous ne sommes donc pas à l’abri d’un futur blocage plus large et plus dur à contrer.\n\nSi vous voulez en apprendre plus sur le combat de ces gens qui se battent pour que la recherche ne soit pas une marchandise, je vous conseille [ce documentaire](https://youtu.be/y_CQATGOX2w) sur Aaron Shwartz. Ou plus simplement [cet article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) sur la fondatrice de Sci-hub.\n\nEn attendant, bonnes lectures à tou·te·s. On est avec vous !","src/content/articles/fr/sci-hub-blocage.mdx","6438fdc02b91ec59","the-day-I-jamd",{"id":124,"data":126,"body":131,"filePath":132,"digest":133,"deferredRender":72},{"title":92,"subtitle":127,"lang":16,"tags":128,"type":61,"slug":124,"createdAt":129,"updatedAt":130},"Des paris, des outils et du fun.",[95,96],["Date","2020-10-08T07:47:36.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## La solution de non facilité\n\nLorsque j’utilisais encore Wordpress pour mon site web personnel, j’ai voulu essayer le serveur web \u003Ca href=\"https://openlitespeed.org\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">OpenLiteSpeed (en anglais)\u003C/a>. En tant que designer, j’ai toujours aimé avoir une interface graphique et j’avais entendu dire qu’OLS jouissait de bonnes performances en général et de cache en particulier.\n\n## Battez-vous!\n\nQuelques années plus tard, je découvrais l’univers Jamstack et son incroyable potentiel. N’étant pas du tout impulsif, j’ai choisi de refaire entièrement mon site web avec des outils comme \u003Ca href=\"https://www.11ty.dev/\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">11ty (en anglais)\u003C/a> et \u003Ca href=\"https://strapi.io/\" hreflang=\"en\">Strapi (en anglais)\u003C/a>.\n\nJe me souviens que Strapi était encore en alpha/beta et que certains collègues me disaient que c’était un pari risqué, surtout que je découvrais à peine le monde de node.js.\n\n> Open source et français ? Je dis banco !\n\nJ’ai donc commencé à recréer mon site web à l’identique avec 11ty et Strapi. Même hébergement chez Digital Ocean, même serveur web, même contenu. J’avais fait pas mal d’optimisations de performances sur mon installation wordpress, j’étais donc impatient de comparer les résultats avec la nouvelle version statique.\n\nJ’en suis resté pantois ! Quasiment sans optimisation du côté statique, j’ai obtenu les résultats ci-dessous.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 53/100 sur Wordpress.'\n/>\n\nMalgré beaucoup d’efforts, je n’ai pas pu faire mieux. Je ne suis pas un expert en cache, je n’utilise pas de CDN et je me suis appuyé sur des plugins pour réaliser beaucoup de choses (php n’étant pas ma spécialité 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 97/100 en Jamstack.'\n/>\n\nPresque **zéro** configuration spéciale (j’étais trop impatient de tester) et j’ai atteint un score impressionnant. Je sais que les scores lighthouse ne font pas tout mais **53 contre 97**… Ça me va !\n\n## Embrassez-vous 🥰\n\nCes deux approches ont leurs avantages et leurs inconvénients. En tant que freelance, mes clients préfèrent ou demandent souvent Wordpress en raison de sa réputation. Je présente toujours une alternative Jamstack lorsque c’est possible, mais cela reste effrayant la plupart du temps par rapport à Wordpress. Je pense cependant qu’il sera plus facile d’utiliser la Jamstack avec le temps.\n\n## Encore et encore…\n\nNous voici maintenant une quarantaine et quelques mois plus tard et ce site fonctionne avec… [Nuxt.js](https://fr.nuxtjs.org/). Je sais, je suis désolé, je n’ai pas pu résister à la dernière fonctionnalité [\u003Cspan lang=\"en\">nuxt content\u003C/span>](https://content.nuxtjs.org/fr) de Nuxt.\n\nDu coup j’ai tout refait… et laissez-moi vous dire : **wow**, quelle expérience !\nJ’adore développer avec Nuxt. L’utilisation de \u003Cspan lang=\"en\">nuxt content\u003C/span> m’a permis de me concentrer sur le design et, évidemment, sur le contenu.\nPlus de client Apollo ni de requête graphQL, seulement du \u003Cspan lang=\"en\">markdown\u003C/span> et quelques promesses.\n\nAttention, j’aime beaucoup travailler avec Strapi et son interface graphQL mais pour les besoins de ce site, \u003Cspan lang=\"en\">nuxt content\u003C/span> fait le \u003Cspan lang=\"en\">job\u003C/span> (extrêmement bien).\n\nJ’utilise toujours Strapi pour téléverser, stocker et gérer les images, vidéos, gifs, etc. C’est peut-être trop pour ce que j’en fait mais j’aime savoir que je peux toujours y revenir si j’ai envie ! De plus, j’ai passé pas mal de temps à le mettre en place avec \u003Cspan lang=\"en\">OpenLiteSpeed\u003C/span> et je suis encore trop attaché à cette réussite pour la laisser tomber.\n\n## Et en fait à la fin\n\nWordpress, Jamstack, fait main… Est-ce vraiment important ? Pour moi, l’expérience de développement a été bien plus agréable en travaillant avec 11ty, nuxt.js et strapi qu’avec Wordpress.\n\nDu point de vue de la performance et de l’accessibilité, il semble également que ce soit le choix le plus judicieux. Ce n’est peut-être pas le cas à chaque fois ! ¯\\\\\\_(ツ)\\_/¯\n\nJ’ai hâte d’apprendre \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> et de tout recommencer à zéro !","src/content/articles/fr/the-day-I-jamd.mdx","57bd292bda8b6632","en-2022",{"id":134,"data":136,"body":142,"filePath":143,"digest":144,"rendered":145},{"title":137,"subtitle":138,"lang":68,"tags":139,"type":61,"slug":134,"createdAt":141},"Nico v2.0","2022 update of many things.",[140],"Freelance",["Date","2022-06-08T14:24:06.000Z"],"After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\n\n## Services\n\n### No more print\n\nEven though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for \"classic\" graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\n\n### Internet all the way\n\nOn the other hand, I spend my time **doing web stuff.** A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer **more specific web offerings,** in which I have specialised.\n\nThus, **accessibility** and **eco-design** become integrated expertises in my practice. They are no longer options on a quote but **my core business.**\n\n## The website\n\nI have reworked my website, especially the homepage and its content, to better reflect these decisions.\n\nI have also made several behavioural changes:\n\n- external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven't found a good reason to continue using this behaviour;\n- I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu);\n- \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\n- I only trigger animations if the user has not asked the system to reduce the amount motion [(reference)](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).\n\nI am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello [astro](https://astro.build/) 👀).\n\n## Le Nico\n\nOn a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\n\nI have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.","src/content/articles/en/2022.md","7b98592763cb0929",{"html":146,"metadata":147},"\u003Cp>After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\u003C/p>\n\u003Ch2 id=\"services\">Services\u003C/h2>\n\u003Ch3 id=\"no-more-print\">No more print\u003C/h3>\n\u003Cp>Even though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for “classic” graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\u003C/p>\n\u003Ch3 id=\"internet-all-the-way\">Internet all the way\u003C/h3>\n\u003Cp>On the other hand, I spend my time \u003Cstrong>doing web stuff.\u003C/strong> A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer \u003Cstrong>more specific web offerings,\u003C/strong> in which I have specialised.\u003C/p>\n\u003Cp>Thus, \u003Cstrong>accessibility\u003C/strong> and \u003Cstrong>eco-design\u003C/strong> become integrated expertises in my practice. They are no longer options on a quote but \u003Cstrong>my core business.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Cp>I have reworked my website, especially the homepage and its content, to better reflect these decisions.\u003C/p>\n\u003Cp>I have also made several behavioural changes:\u003C/p>\n\u003Cul>\n\u003Cli>external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven’t found a good reason to continue using this behaviour;\u003C/li>\n\u003Cli>I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a>;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\u003C/li>\n\u003Cli>I only trigger animations if the user has not asked the system to reduce the amount motion \u003Ca href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion\">(reference)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>I am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello \u003Ca href=\"https://astro.build/\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>On a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\u003C/p>\n\u003Cp>I have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.\u003C/p>",{"headings":148,"imagePaths":166,"frontmatter":167},[149,153,157,160,163],{"depth":150,"slug":151,"text":152},2,"services","Services",{"depth":154,"slug":155,"text":156},3,"no-more-print","No more print",{"depth":154,"slug":158,"text":159},"internet-all-the-way","Internet all the way",{"depth":150,"slug":161,"text":162},"the-website","The website",{"depth":150,"slug":164,"text":165},"le-nico","Le Nico",[],{"title":137,"subtitle":138,"lang":68,"slug":134,"excerpt":168,"tags":169,"type":61,"createdAt":170},"Changes in my services, the website and myself.",[140],"2022-06-08T14:24:06.000Z","en-2023",{"id":171,"data":173,"body":179,"filePath":180,"digest":181,"rendered":182},{"title":174,"subtitle":175,"lang":68,"tags":176,"type":61,"slug":171,"createdAt":177,"updatedAt":178},"Nico v2.5","Update 2023.",[140],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"This article will be updated when I have something new to share during the year 2023.\n\n## The website\n\n### Technologies\n\nOops... I (re)did it again.\n\nI have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself [in 2022 !](/en/articles/2022/#the-website)\n\nI will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\n\nMy \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I'm back to a solid **95/100** without any particular optimization. With some small efforts, I've reached the good old 100/100.\n\nI then did a work of modernization of the codebase. Hello CSS variables and goodbye `media queries`. In no particular order, here are some of the improvements I made:\n\n- `flexbox` and `grid` to adapt the layout to different screen sizes;\n- CSS variables for colors, font sizes and margins;\n- some `container queries`, just to try;\n- logical CSS properties (`inline` and `block` instead of `width` and `height` for example).\n\nI took this opportunity to publish [the source code](https://git.nardu.in/nardu.in/website-astro) on my git repository.\n\n**Update #1:** I've added [an RSS feed](/en/rss.xml) as I find myself using it more and more on other websites.\n\n### Analytics\n\nI removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\n\nIt's nice to see that your site is consulted, but if there is no other purpose behind it, it's an extra resource loaded for nothing by visitors. Maybe I'll reactivate the tracking when I have a use for it (other than flattering my ego).\n\nPrevious visit reports can be found at [this link.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Content\n\n- I've added a [work](/en/work/) page to list some of my projects.\n- I've also added [a page](/en/veille/) where I list some interesting things from around the web.\n\n## Additional projects\n\nI'm still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at [3-w.fr](https://3-w.fr/) (an address I am very proud of).\n\nI have to update it more regularly but I hope that the platform will help students progress!\n\n**More to come soon!**","src/content/articles/en/2023.md","489c650e66cced63",{"html":183,"metadata":184},"\u003Cp>This article will be updated when I have something new to share during the year 2023.\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oops… I (re)did it again.\u003C/p>\n\u003Cp>I have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself \u003Ca href=\"/en/articles/2022/#the-website\">in 2022 !\u003C/a>\u003C/p>\n\u003Cp>I will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\u003C/p>\n\u003Cp>My \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I’m back to a solid \u003Cstrong>95/100\u003C/strong> without any particular optimization. With some small efforts, I’ve reached the good old 100/100.\u003C/p>\n\u003Cp>I then did a work of modernization of the codebase. Hello CSS variables and goodbye \u003Ccode>media queries\u003C/code>. In no particular order, here are some of the improvements I made:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> and \u003Ccode>grid\u003C/code> to adapt the layout to different screen sizes;\u003C/li>\n\u003Cli>CSS variables for colors, font sizes and margins;\u003C/li>\n\u003Cli>some \u003Ccode>container queries\u003C/code>, just to try;\u003C/li>\n\u003Cli>logical CSS properties (\u003Ccode>inline\u003C/code> and \u003Ccode>block\u003C/code> instead of \u003Ccode>width\u003C/code> and \u003Ccode>height\u003C/code> for example).\u003C/li>\n\u003C/ul>\n\u003Cp>I took this opportunity to publish \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">the source code\u003C/a> on my git repository.\u003C/p>\n\u003Cp>\u003Cstrong>Update #1:\u003C/strong> I’ve added \u003Ca href=\"/en/rss.xml\">an RSS feed\u003C/a> as I find myself using it more and more on other websites.\u003C/p>\n\u003Ch3 id=\"analytics\">Analytics\u003C/h3>\n\u003Cp>I removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\u003C/p>\n\u003Cp>It’s nice to see that your site is consulted, but if there is no other purpose behind it, it’s an extra resource loaded for nothing by visitors. Maybe I’ll reactivate the tracking when I have a use for it (other than flattering my ego).\u003C/p>\n\u003Cp>Previous visit reports can be found at \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">this link.\u003C/a>\u003C/p>\n\u003Ch3 id=\"content\">Content\u003C/h3>\n\u003Cul>\n\u003Cli>I’ve added a \u003Ca href=\"/en/work/\">work\u003C/a> page to list some of my projects.\u003C/li>\n\u003Cli>I’ve also added \u003Ca href=\"/en/veille/\">a page\u003C/a> where I list some interesting things from around the web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"additional-projects\">Additional projects\u003C/h2>\n\u003Cp>I’m still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (an address I am very proud of).\u003C/p>\n\u003Cp>I have to update it more regularly but I hope that the platform will help students progress!\u003C/p>\n\u003Cp>\u003Cstrong>More to come soon!\u003C/strong>\u003C/p>",{"headings":185,"imagePaths":199,"frontmatter":200},[186,187,190,193,196],{"depth":150,"slug":161,"text":162},{"depth":154,"slug":188,"text":189},"technologies","Technologies",{"depth":154,"slug":191,"text":192},"analytics","Analytics",{"depth":154,"slug":194,"text":195},"content","Content",{"depth":150,"slug":197,"text":198},"additional-projects","Additional projects",[],{"title":174,"subtitle":175,"lang":68,"slug":171,"excerpt":201,"tags":202,"type":61,"createdAt":203,"updatedAt":204},"New changes.",[140],"2023-02-03T17:41:00.000Z","2023-05-17T17:41:00.000Z","en-faq",{"id":205,"data":207,"body":212,"filePath":213,"digest":214,"rendered":215},{"title":208,"subtitle":209,"lang":68,"tags":210,"type":61,"slug":205,"createdAt":211,"draft":72},"Accessibility and sobriety","Translation in progress, stay tuned ;)",[140],["Date","2022-06-22T15:34:45.000Z"],"[Go back to available articles](/en/articles)","src/content/articles/en/faq.md","82d516449896f6ca",{"html":216,"metadata":217},"\u003Cp>\u003Ca href=\"/en/articles\">Go back to available articles\u003C/a>\u003C/p>",{"headings":218,"imagePaths":219,"frontmatter":220},[],[],{"title":208,"subtitle":209,"lang":68,"slug":205,"draft":72,"excerpt":221,"tags":222,"type":61,"createdAt":223},"Why, how et and especially what.",[140],"2022-06-22T15:34:45.000Z","en-gratuiste",{"id":224,"data":226,"body":212,"filePath":230,"digest":231,"rendered":232},{"title":227,"subtitle":209,"lang":68,"tags":228,"type":61,"slug":224,"createdAt":229,"draft":72},"Gratuiste",[70,140],["Date","2017-05-27T07:47:36.000Z"],"src/content/articles/en/gratuiste.md","ebec75d19f0ff741",{"html":216,"metadata":233},{"headings":234,"imagePaths":235,"frontmatter":236},[],[],{"title":227,"subtitle":209,"lang":68,"slug":224,"draft":72,"excerpt":209,"tags":237,"type":61,"createdAt":238},[70,140],"2017-05-27T07:47:36.000Z","2022",{"id":239,"data":241,"body":245,"filePath":246,"digest":247,"rendered":248},{"title":137,"subtitle":242,"lang":16,"tags":243,"type":61,"slug":239,"createdAt":244},"Mise à jour 2022 de plein de trucs.",[140],["Date","2022-06-08T14:24:06.000Z"],"Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\n\n## Les services\n\n### J’arrête le print\n\nMême si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\n\n### J’internet à fond\n\nÀ l’inverse, je passe mon temps à **faire du web.** Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer **des offres web plus précises,** dans lesquelles je me suis spécialisé.\n\nAinsi, **l’accessibilité numérique** et **l’éco-conception** deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien **mon cœur de métier.**\n\n## Le site\n\nJ’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\n\nJ’ai également fait plusieurs changements de comportements :\n\n- les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\n- j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec [cette analyse](https://twitter.com/HTeuMeuLeu/status/1370310316496728065) de [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu) ;\n- [idem pour la favicon](https://twitter.com/HTeuMeuLeu/status/1370310312214339586) ;\n- je ne déclenche les animations que si l'utilisateur n'a pas demandé au système de minimiser la quantité d'animation ou de mouvement [(référence de l'option)](https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion).\n\nJe suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> 👀).\n\n## Le Nico\n\nD’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif [Good-it!](https://www.good-it.org/) et en participant activement à son développement.\n\nJ’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.","src/content/articles/fr/2022.md","2589166172138721",{"html":249,"metadata":250},"\u003Cp>Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\u003C/p>\n\u003Ch2 id=\"les-services\">Les services\u003C/h2>\n\u003Ch3 id=\"jarrête-le-print\">J’arrête le print\u003C/h3>\n\u003Cp>Même si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\u003C/p>\n\u003Ch3 id=\"jinternet-à-fond\">J’internet à fond\u003C/h3>\n\u003Cp>À l’inverse, je passe mon temps à \u003Cstrong>faire du web.\u003C/strong> Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer \u003Cstrong>des offres web plus précises,\u003C/strong> dans lesquelles je me suis spécialisé.\u003C/p>\n\u003Cp>Ainsi, \u003Cstrong>l’accessibilité numérique\u003C/strong> et \u003Cstrong>l’éco-conception\u003C/strong> deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien \u003Cstrong>mon cœur de métier.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Cp>J’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\u003C/p>\n\u003Cp>J’ai également fait plusieurs changements de comportements :\u003C/p>\n\u003Cul>\n\u003Cli>les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\u003C/li>\n\u003Cli>j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\">cette analyse\u003C/a> de \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a> ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\">idem pour la favicon\u003C/a> ;\u003C/li>\n\u003Cli>je ne déclenche les animations que si l’utilisateur n’a pas demandé au système de minimiser la quantité d’animation ou de mouvement \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion\">(référence de l’option)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>Je suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>D’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif \u003Ca href=\"https://www.good-it.org/\">Good-it!\u003C/a> et en participant activement à son développement.\u003C/p>\n\u003Cp>J’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.\u003C/p>",{"headings":251,"imagePaths":265,"frontmatter":266},[252,255,258,261,264],{"depth":150,"slug":253,"text":254},"les-services","Les services",{"depth":154,"slug":256,"text":257},"jarrête-le-print","J’arrête le print",{"depth":154,"slug":259,"text":260},"jinternet-à-fond","J’internet à fond",{"depth":150,"slug":262,"text":263},"le-site","Le site",{"depth":150,"slug":164,"text":165},[],{"title":137,"subtitle":242,"lang":16,"slug":239,"excerpt":267,"tags":268,"type":61,"createdAt":170},"Évolution des services, du site et de moi-même.",[140],"2023",{"id":269,"data":271,"body":276,"filePath":277,"digest":278,"rendered":279},{"title":174,"subtitle":272,"lang":16,"tags":273,"type":61,"slug":269,"createdAt":274,"updatedAt":275},"Mise à jour 2023.",[140],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"Cet article sera mis à jour lorsque j'aurai des nouveautés à partager au cours de l'année 2023.\n\n## Le site\n\n### Technologies\n\nOups… je l'ai encore (re)fait.\n\nJ'ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même [en 2022 !](/articles/2022/#le-site)\n\nJe ferai certainement un ou deux articles/fragments sur Astro et les extensions que j'ai utilisées. En tout cas c'était super comme expérience. Nuxt v2 n'étant plus vraiment à jour, les performances n'étaient plus au rendez-vous. Astro a complètement corrigé ça.\n\nMon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide **95/100** sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\n\nJ'ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les `media queries`. En vrac, voici certaines améliorations que j'ai mises en place :\n\n- `flexbox` et `grid` pour adapter la mise en page aux différentes tailles d'écran ;\n- variables CSS pour les couleurs, les tailles de polices et les marges ;\n- quelques \u003Cspan lang=\"en\">`container queries`\u003C/span> pour essayer ;\n- propriétés logiques CSS (\u003Cspan lang=\"en\">`inline`\u003C/span> et \u003Cspan lang=\"en\">`block`\u003C/span> à la place de \u003Cspan lang=\"en\">`width`\u003C/span> et \u003Cspan lang=\"en\">`height`\u003C/span> par exemple).\n\nJ'en ai profité pour publier [le code source](https://git.nardu.in/nardu.in/website-astro) sur mon dépôt git.\n\n**Mise à jour #1 :** J'ai ajouté [un flux RSS](/rss.xml) car j'utilise de plus en plus le RSS sur d'autres sites web.\n\n### Suivi des visites\n\nJ’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n'était collectée et je consultais rarement les rapports.\n\nC'est sympa de voir que son site est visité, mais s'il n'y a aucun autre but derrière, c'est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j'en aurai l'utilité (autre que flatter mon égo).\n\nLes rapports de visites précédents sont consultables sur [ce lien.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Contenu\n\n- J'ai ajouté une page [références](/references/) pour lister certains de mes projets.\n- J'ai également ajouté [une page](/veille/) où je répertorie des choses intéressantes trouvées sur le web.\n\n## Projets annexes\n\nJe continue d'enseigner le développement web cette année. Afin d'étoffer mes supports de cours, j'ai mis en place un mini site de documentation disponible à l'adresse [3-w.fr](https://3-w.fr/) (adresse dont je suis très fier).\n\nIl faut que j'arrive à être plus régulier dans sa mise à jour mais j'ai bon espoir que la plateforme aide les élèves à progresser !\n\n**Plus de trucs bientôt!**","src/content/articles/fr/2023.md","d97f4a5af975333f",{"html":280,"metadata":281},"\u003Cp>Cet article sera mis à jour lorsque j’aurai des nouveautés à partager au cours de l’année 2023.\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oups… je l’ai encore (re)fait.\u003C/p>\n\u003Cp>J’ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même \u003Ca href=\"/articles/2022/#le-site\">en 2022 !\u003C/a>\u003C/p>\n\u003Cp>Je ferai certainement un ou deux articles/fragments sur Astro et les extensions que j’ai utilisées. En tout cas c’était super comme expérience. Nuxt v2 n’étant plus vraiment à jour, les performances n’étaient plus au rendez-vous. Astro a complètement corrigé ça.\u003C/p>\n\u003Cp>Mon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide \u003Cstrong>95/100\u003C/strong> sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\u003C/p>\n\u003Cp>J’ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les \u003Ccode>media queries\u003C/code>. En vrac, voici certaines améliorations que j’ai mises en place :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> et \u003Ccode>grid\u003C/code> pour adapter la mise en page aux différentes tailles d’écran ;\u003C/li>\n\u003Cli>variables CSS pour les couleurs, les tailles de polices et les marges ;\u003C/li>\n\u003Cli>quelques \u003Cspan lang=\"en\">\u003Ccode>container queries\u003C/code>\u003C/span> pour essayer ;\u003C/li>\n\u003Cli>propriétés logiques CSS (\u003Cspan lang=\"en\">\u003Ccode>inline\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>block\u003C/code>\u003C/span> à la place de \u003Cspan lang=\"en\">\u003Ccode>width\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>height\u003C/code>\u003C/span> par exemple).\u003C/li>\n\u003C/ul>\n\u003Cp>J’en ai profité pour publier \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">le code source\u003C/a> sur mon dépôt git.\u003C/p>\n\u003Cp>\u003Cstrong>Mise à jour #1 :\u003C/strong> J’ai ajouté \u003Ca href=\"/rss.xml\">un flux RSS\u003C/a> car j’utilise de plus en plus le RSS sur d’autres sites web.\u003C/p>\n\u003Ch3 id=\"suivi-des-visites\">Suivi des visites\u003C/h3>\n\u003Cp>J’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n’était collectée et je consultais rarement les rapports.\u003C/p>\n\u003Cp>C’est sympa de voir que son site est visité, mais s’il n’y a aucun autre but derrière, c’est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j’en aurai l’utilité (autre que flatter mon égo).\u003C/p>\n\u003Cp>Les rapports de visites précédents sont consultables sur \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">ce lien.\u003C/a>\u003C/p>\n\u003Ch3 id=\"contenu\">Contenu\u003C/h3>\n\u003Cul>\n\u003Cli>J’ai ajouté une page \u003Ca href=\"/references/\">références\u003C/a> pour lister certains de mes projets.\u003C/li>\n\u003Cli>J’ai également ajouté \u003Ca href=\"/veille/\">une page\u003C/a> où je répertorie des choses intéressantes trouvées sur le web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"projets-annexes\">Projets annexes\u003C/h2>\n\u003Cp>Je continue d’enseigner le développement web cette année. Afin d’étoffer mes supports de cours, j’ai mis en place un mini site de documentation disponible à l’adresse \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (adresse dont je suis très fier).\u003C/p>\n\u003Cp>Il faut que j’arrive à être plus régulier dans sa mise à jour mais j’ai bon espoir que la plateforme aide les élèves à progresser !\u003C/p>\n\u003Cp>\u003Cstrong>Plus de trucs bientôt!\u003C/strong>\u003C/p>",{"headings":282,"imagePaths":294,"frontmatter":295},[283,284,285,288,291],{"depth":150,"slug":262,"text":263},{"depth":154,"slug":188,"text":189},{"depth":154,"slug":286,"text":287},"suivi-des-visites","Suivi des visites",{"depth":154,"slug":289,"text":290},"contenu","Contenu",{"depth":150,"slug":292,"text":293},"projets-annexes","Projets annexes",[],{"title":174,"subtitle":272,"lang":16,"slug":269,"excerpt":296,"tags":297,"type":61,"createdAt":203,"updatedAt":204},"Suite des évolutions.",[140],"after-effects-expressions",{"id":298,"data":300,"body":304,"filePath":305,"digest":306,"rendered":307},{"title":66,"subtitle":301,"lang":16,"tags":302,"type":61,"slug":298,"createdAt":303,"draft":72},"En cours de traduction, revenez bientôt ;)",[70],["Date","2019-04-24T09:00:00.000Z"],"[Retour aux articles](/articles)","src/content/articles/fr/after-effects-expressions.md","884d725859a7bab5",{"html":308,"metadata":309},"\u003Cp>\u003Ca href=\"/articles\">Retour aux articles\u003C/a>\u003C/p>",{"headings":310,"imagePaths":311,"frontmatter":312},[],[],{"title":66,"subtitle":301,"lang":16,"draft":72,"slug":298,"excerpt":301,"tags":313,"type":61,"createdAt":314},[70],"2019-04-24T09:00:00.000Z","faq",{"id":315,"data":317,"body":322,"filePath":323,"digest":324,"rendered":325},{"title":318,"subtitle":319,"lang":16,"tags":320,"type":61,"slug":315,"createdAt":321},"Accessibilité, sobriété et F.A.Q.","Explications sur ma vision et mon fonctionnement.",[140],["Date","2022-06-22T15:34:45.000Z"],"## l'Accessibilité\n\n### Quèsaco ?\n\nD'après [access42 :](https://access42.net)\n\n> L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\n\nAinsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que **n'importe quel visiteur** puisse l'utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais **ce n'est pas le cas !**\n\nLorsqu'un site est pensé et conçu avec l'accessibilité en tête, il ne prend **pas plus de temps** qu'un projet qui ne le fait pas. En revanche, **corriger** un site existant qui n'a pas bénéficié de cette réflexion en amont **demande beaucoup plus d'efforts.**\n\n### Pourquoi c'est important ?\n\nAprès avoir été sensibilisé à l'accessibilité et aux [situations frustrantes voire bloquantes](https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles) que rencontrent les personnes handicapées sur le web, j'ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m'a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\n\n## l'Éco-conception\n\n### Quèsaco ?\n\nD'après le collectif [\u003Cspan lang=\"en\">green it\u003C/span> :](https://www.greenit.fr)\n\n> L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\n\nIl s'agit ici pour moi de créer des produits les plus sobres possibles. C'est-à-dire de développer ou d'utiliser une fonctionnalité uniquement si elle est indispensable.\n\nPar exemple, mettre en place **un formulaire de contact** sur un site web implique plusieurs choses :\n\n- développer un formulaire\n- envoyer les données au serveur\n- vérifier les données envoyées\n- envoyer les données par mail\n- confirmer l'envoi du mail (en fournissant une copie)\n- gérer les erreurs à chaque étape\n\nUn site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d'effectuer ces opérations (ou un prestataire qui s'en charge). C'est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu'un formulaire. Dans le cas d'un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\n\n### Pourquoi c'est important ?\n\nL'éco-conception fait beaucoup de bien à la qualité globale d'un site et à l'expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\n\n## F.A.Q.\n\n### Cette démarche est-elle opportuniste ?\n\n**Non.** Il est vrai que l'accessibilité et, surtout, l'éco-conception, commencent à être « tendance ». On pourrait donc croire que j'en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c'est ma responsabilité de créer des sites web accessibles et éco-conçus **par défaut.**\n\n### Un site accessible est-il plus cher ?\n\n**Oui et non.** Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l'accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j'augmente mes tarifs suite à l'obtention de certifications relatives à mon activité.\n\n### Mon site sera-t-il 100 % accessible ?\n\n**Non,** je ne suis pas en mesure de garantir ou de certifier la conformité totale d'un site au [référentiel général d'amélioration de l'accessibilité.](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d'un site. Cependant, je peux vous accompagner avant et après l'audit afin d'anticiper puis de corriger les critères d'accessibilité requis. [Access42](https://access42.net/) et [Tanaguru](https://www.tanaguru.com/) font parties de ces entreprises spécialisées.\n\n### Pourquoi ne pas utiliser un outil automatique ?\n\nCar ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom [sous peine de procès](https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/)), ne sont pas des solutions micracles. Lisez [cet article](https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/) d'une experte en accessibilité et/ou [ce test](https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/) de différents outils pour en savoir plus.\n\n### Un site éco-conçu et accessible peut-il être beau ?\n\n**Oui, évidemment.** Je vous laisse juger par vous-même avec [cette liste](https://lowww.directory/) de sites éco-conçus. En ce qui concerne l'accessibilité, elle n'impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d'un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l'utilisation d'un produit.","src/content/articles/fr/faq.md","65e9e60bcd00806c",{"html":326,"metadata":327},"\u003Ch2 id=\"laccessibilité\">l’Accessibilité\u003C/h2>\n\u003Ch3 id=\"quèsaco\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après \u003Ca href=\"https://access42.net\">access42 :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Ainsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que \u003Cstrong>n’importe quel visiteur\u003C/strong> puisse l’utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais \u003Cstrong>ce n’est pas le cas !\u003C/strong>\u003C/p>\n\u003Cp>Lorsqu’un site est pensé et conçu avec l’accessibilité en tête, il ne prend \u003Cstrong>pas plus de temps\u003C/strong> qu’un projet qui ne le fait pas. En revanche, \u003Cstrong>corriger\u003C/strong> un site existant qui n’a pas bénéficié de cette réflexion en amont \u003Cstrong>demande beaucoup plus d’efforts.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>Après avoir été sensibilisé à l’accessibilité et aux \u003Ca href=\"https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles\">situations frustrantes voire bloquantes\u003C/a> que rencontrent les personnes handicapées sur le web, j’ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m’a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\u003C/p>\n\u003Ch2 id=\"léco-conception\">l’Éco-conception\u003C/h2>\n\u003Ch3 id=\"quèsaco-1\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après le collectif \u003Ca href=\"https://www.greenit.fr\">\u003Cspan lang=\"en\">green it\u003C/span> :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Il s’agit ici pour moi de créer des produits les plus sobres possibles. C’est-à-dire de développer ou d’utiliser une fonctionnalité uniquement si elle est indispensable.\u003C/p>\n\u003Cp>Par exemple, mettre en place \u003Cstrong>un formulaire de contact\u003C/strong> sur un site web implique plusieurs choses :\u003C/p>\n\u003Cul>\n\u003Cli>développer un formulaire\u003C/li>\n\u003Cli>envoyer les données au serveur\u003C/li>\n\u003Cli>vérifier les données envoyées\u003C/li>\n\u003Cli>envoyer les données par mail\u003C/li>\n\u003Cli>confirmer l’envoi du mail (en fournissant une copie)\u003C/li>\n\u003Cli>gérer les erreurs à chaque étape\u003C/li>\n\u003C/ul>\n\u003Cp>Un site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d’effectuer ces opérations (ou un prestataire qui s’en charge). C’est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu’un formulaire. Dans le cas d’un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important-1\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>L’éco-conception fait beaucoup de bien à la qualité globale d’un site et à l’expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\u003C/p>\n\u003Ch2 id=\"faq\">F.A.Q.\u003C/h2>\n\u003Ch3 id=\"cette-démarche-est-elle-opportuniste\">Cette démarche est-elle opportuniste ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non.\u003C/strong> Il est vrai que l’accessibilité et, surtout, l’éco-conception, commencent à être « tendance ». On pourrait donc croire que j’en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c’est ma responsabilité de créer des sites web accessibles et éco-conçus \u003Cstrong>par défaut.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"un-site-accessible-est-il-plus-cher\">Un site accessible est-il plus cher ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui et non.\u003C/strong> Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l’accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j’augmente mes tarifs suite à l’obtention de certifications relatives à mon activité.\u003C/p>\n\u003Ch3 id=\"mon-site-sera-t-il-100-accessible\">Mon site sera-t-il 100 % accessible ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non,\u003C/strong> je ne suis pas en mesure de garantir ou de certifier la conformité totale d’un site au \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité.\u003C/a> Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d’un site. Cependant, je peux vous accompagner avant et après l’audit afin d’anticiper puis de corriger les critères d’accessibilité requis. \u003Ca href=\"https://access42.net/\">Access42\u003C/a> et \u003Ca href=\"https://www.tanaguru.com/\">Tanaguru\u003C/a> font parties de ces entreprises spécialisées.\u003C/p>\n\u003Ch3 id=\"pourquoi-ne-pas-utiliser-un-outil-automatique\">Pourquoi ne pas utiliser un outil automatique ?\u003C/h3>\n\u003Cp>Car ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom \u003Ca href=\"https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/\">sous peine de procès\u003C/a>), ne sont pas des solutions micracles. Lisez \u003Ca href=\"https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/\">cet article\u003C/a> d’une experte en accessibilité et/ou \u003Ca href=\"https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/\">ce test\u003C/a> de différents outils pour en savoir plus.\u003C/p>\n\u003Ch3 id=\"un-site-éco-conçu-et-accessible-peut-il-être-beau\">Un site éco-conçu et accessible peut-il être beau ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui, évidemment.\u003C/strong> Je vous laisse juger par vous-même avec \u003Ca href=\"https://lowww.directory/\">cette liste\u003C/a> de sites éco-conçus. En ce qui concerne l’accessibilité, elle n’impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d’un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l’utilisation d’un produit.\u003C/p>",{"headings":328,"imagePaths":362,"frontmatter":363},[329,332,335,338,341,343,345,347,350,353,356,359],{"depth":150,"slug":330,"text":331},"laccessibilité","l’Accessibilité",{"depth":154,"slug":333,"text":334},"quèsaco","Quèsaco ?",{"depth":154,"slug":336,"text":337},"pourquoi-cest-important","Pourquoi c’est important ?",{"depth":150,"slug":339,"text":340},"léco-conception","l’Éco-conception",{"depth":154,"slug":342,"text":334},"quèsaco-1",{"depth":154,"slug":344,"text":337},"pourquoi-cest-important-1",{"depth":150,"slug":315,"text":346},"F.A.Q.",{"depth":154,"slug":348,"text":349},"cette-démarche-est-elle-opportuniste","Cette démarche est-elle opportuniste ?",{"depth":154,"slug":351,"text":352},"un-site-accessible-est-il-plus-cher","Un site accessible est-il plus cher ?",{"depth":154,"slug":354,"text":355},"mon-site-sera-t-il-100-accessible","Mon site sera-t-il 100 % accessible ?",{"depth":154,"slug":357,"text":358},"pourquoi-ne-pas-utiliser-un-outil-automatique","Pourquoi ne pas utiliser un outil automatique ?",{"depth":154,"slug":360,"text":361},"un-site-éco-conçu-et-accessible-peut-il-être-beau","Un site éco-conçu et accessible peut-il être beau ?",[],{"title":318,"subtitle":319,"lang":16,"slug":315,"excerpt":364,"tags":365,"type":61,"createdAt":223},"Pourquoi, comment et surtout quèsaco.",[140],"gratuiste",{"id":366,"data":368,"body":374,"filePath":375,"digest":376,"rendered":377},{"title":227,"subtitle":369,"lang":16,"tags":370,"type":61,"slug":366,"createdAt":372,"updatedAt":373},"Ou le travail gratuit.",[371,140],"Graphisme",["Date","2017-05-27T07:47:36.000Z"],["Date","2022-12-27T15:36:06.000Z"],"## Gratuiste, qu’est-ce que c’est ?\n\nDans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc. \nDe plus en plus, la communauté s’élève contre ces pratiques et les [dénonce.](https://twitter.com/PayeTonAffiche)\n\n> “ On n’est pas des gratuistes ! ”\n\nComprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez [cette vidéo](https://youtu.be/essNmNOrQto) qui transpose ces pratiques à des métiers “ standards ” et [celle-ci](https://youtu.be/DsstOs-K7gk) qui explique en détails le processus actuel.\n\n## T’es débile du coup ?\n\nJ’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\n\nÉtant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre. \nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\n\n## Le concept\n\nJe compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux. \nCe type de prestation porte le nom de “ **pro bono publico** ” – “ **pour le bien public** ”.\n\nCette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\n\n> Graphiste pro bono, pourquoi pas ?\n\n## Quels genres de services ?\n\nEn toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\n\n### En résumé :\n\n- maquette de site web\n- intégration front-end (en dur ou via wordpress) du site\n- gestion de la mise en ligne du site\n- newsletter (design et/ou intégration)\n- flyers\n- autres petites demandes\n\nVous pouvez avoir un aperçu de mon travail [sur ce même site.](/) J’ai déjà eu l’occasion de travailler pour :\n\n- [Cygnal](/projets/cygnal)\n- [OpenMole](https://openmole.org/)\n- [Good-it](https://good-it.org)\n\n## Dans quelles conditions ?\n\n- l’association doit être active\n- elle doit porter des valeurs que je partage\n- elle doit pouvoir me montrer ses actions\n- elle ne doit pas avoir les moyens de se payer un graphiste\n\n## C’est un peu trop beau pour être vrai ton truc…\n\nIl faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\n\nSi vous êtes intéressés, [envoyez-moi un mail !](mailto:contac@nardu.in)\n\n## Qu’est-ce que t’y gagnes toi ?\n\nSimplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.","src/content/articles/fr/gratuiste.md","80c20493583a842c",{"html":378,"metadata":379},"\u003Ch2 id=\"gratuiste-quest-ce-que-cest\">Gratuiste, qu’est-ce que c’est ?\u003C/h2>\n\u003Cp>Dans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc.\u003Cbr>\nDe plus en plus, la communauté s’élève contre ces pratiques et les \u003Ca href=\"https://twitter.com/PayeTonAffiche\">dénonce.\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“ On n’est pas des gratuistes ! ”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Comprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez \u003Ca href=\"https://youtu.be/essNmNOrQto\">cette vidéo\u003C/a> qui transpose ces pratiques à des métiers “ standards ” et \u003Ca href=\"https://youtu.be/DsstOs-K7gk\">celle-ci\u003C/a> qui explique en détails le processus actuel.\u003C/p>\n\u003Ch2 id=\"tes-débile-du-coup\">T’es débile du coup ?\u003C/h2>\n\u003Cp>J’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\u003C/p>\n\u003Cp>Étant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre.\u003Cbr>\nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\u003C/p>\n\u003Ch2 id=\"le-concept\">Le concept\u003C/h2>\n\u003Cp>Je compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux.\u003Cbr>\nCe type de prestation porte le nom de “ \u003Cstrong>pro bono publico\u003C/strong> ” – “ \u003Cstrong>pour le bien public\u003C/strong> ”.\u003C/p>\n\u003Cp>Cette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Graphiste pro bono, pourquoi pas ?\u003C/p>\n\u003C/blockquote>\n\u003Ch2 id=\"quels-genres-de-services\">Quels genres de services ?\u003C/h2>\n\u003Cp>En toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\u003C/p>\n\u003Ch3 id=\"en-résumé\">En résumé :\u003C/h3>\n\u003Cul>\n\u003Cli>maquette de site web\u003C/li>\n\u003Cli>intégration front-end (en dur ou via wordpress) du site\u003C/li>\n\u003Cli>gestion de la mise en ligne du site\u003C/li>\n\u003Cli>newsletter (design et/ou intégration)\u003C/li>\n\u003Cli>flyers\u003C/li>\n\u003Cli>autres petites demandes\u003C/li>\n\u003C/ul>\n\u003Cp>Vous pouvez avoir un aperçu de mon travail \u003Ca href=\"/\">sur ce même site.\u003C/a> J’ai déjà eu l’occasion de travailler pour :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"/projets/cygnal\">Cygnal\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://openmole.org/\">OpenMole\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://good-it.org\">Good-it\u003C/a>\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"dans-quelles-conditions\">Dans quelles conditions ?\u003C/h2>\n\u003Cul>\n\u003Cli>l’association doit être active\u003C/li>\n\u003Cli>elle doit porter des valeurs que je partage\u003C/li>\n\u003Cli>elle doit pouvoir me montrer ses actions\u003C/li>\n\u003Cli>elle ne doit pas avoir les moyens de se payer un graphiste\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"cest-un-peu-trop-beau-pour-être-vrai-ton-truc\">C’est un peu trop beau pour être vrai ton truc…\u003C/h2>\n\u003Cp>Il faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\u003C/p>\n\u003Cp>Si vous êtes intéressés, \u003Ca href=\"mailto:contac@nardu.in\">envoyez-moi un mail !\u003C/a>\u003C/p>\n\u003Ch2 id=\"quest-ce-que-ty-gagnes-toi\">Qu’est-ce que t’y gagnes toi ?\u003C/h2>\n\u003Cp>Simplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.\u003C/p>",{"headings":380,"imagePaths":405,"frontmatter":406},[381,384,387,390,393,396,399,402],{"depth":150,"slug":382,"text":383},"gratuiste-quest-ce-que-cest","Gratuiste, qu’est-ce que c’est ?",{"depth":150,"slug":385,"text":386},"tes-débile-du-coup","T’es débile du coup ?",{"depth":150,"slug":388,"text":389},"le-concept","Le concept",{"depth":150,"slug":391,"text":392},"quels-genres-de-services","Quels genres de services ?",{"depth":154,"slug":394,"text":395},"en-résumé","En résumé :",{"depth":150,"slug":397,"text":398},"dans-quelles-conditions","Dans quelles conditions ?",{"depth":150,"slug":400,"text":401},"cest-un-peu-trop-beau-pour-être-vrai-ton-truc","C’est un peu trop beau pour être vrai ton truc…",{"depth":150,"slug":403,"text":404},"quest-ce-que-ty-gagnes-toi","Qu’est-ce que t’y gagnes toi ?",[],{"title":227,"subtitle":369,"lang":16,"slug":366,"excerpt":407,"tags":408,"type":61,"createdAt":238,"updatedAt":409},"J’ai cherché un moyen de mettre mes compétences au service d’autrui et je pense avoir trouvé: je vais travailler gratuitement pour des associations.",[371,140],"2022-12-27T15:36:06.000Z","video-compression",{"id":410,"data":412,"body":304,"filePath":417,"digest":418,"rendered":419},{"title":413,"subtitle":301,"lang":16,"tags":414,"type":61,"slug":410,"createdAt":415,"updatedAt":416,"draft":72},"Compression vidéo",[70],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"src/content/articles/fr/video-compression.md","2296c41874b23b3d",{"html":308,"metadata":420},{"headings":421,"imagePaths":422,"frontmatter":423},[],[],{"title":413,"subtitle":301,"lang":16,"draft":72,"slug":410,"excerpt":424,"tags":425,"type":61,"createdAt":426,"updatedAt":170},"Pas encore traduit",[70],"2021-05-05T09:00:00.000Z","fragments",["Map",429,430,441,442,452,453,462,463,473,474,484,485,539,540,556,557,574,575,587,588,651,652,713,714,748,749,782,783,806,807,848,849],"en-image-full",{"id":429,"data":431,"body":438,"filePath":439,"digest":440,"deferredRender":72},{"title":432,"subtitle":209,"lang":68,"tags":433,"type":435,"slug":429,"createdAt":436,"updatedAt":437,"draft":72},"Full width image",[434],"CSS","snippets",["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"[Go back to available snippets](/en/snippets)","src/content/fragments/en/image-full.mdx","2e3dddf593f6d72f","en-super-cookies",{"id":441,"data":443,"body":449,"filePath":450,"digest":451,"deferredRender":72},{"title":444,"subtitle":445,"lang":68,"tags":446,"type":435,"slug":441,"createdAt":448},"The best cookies","Consentless biscuits.",[447],"food",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 tablespoon of baking powder\n- 3/4 of aquafaba from 400g of chickpea (chickpea water)\n- 125 grams of coconut oil\n- 2 teaspoons of maple syrup\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- if necessary, melt the coconut oil over low heat\n- meanwhile, mix all the dry ingredients\n- add all liquid ingredients (oil, aquafaba, maple syrup)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Non vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 table spoon of baking powder\n- 1 egg\n- 125 grams of melted butter\n- 2 teaspoons of honey\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- melt butter over low heat\n- meanwhile, mix all dry ingredients\n- add all liquid ingredients (melted butter, egg, honey)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Notes\n\nChocolate can be replaced by anything like nuts, raisins, legos... (don't eat legos be reasonable).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='All ingredients mixed together to form a brown paste.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='The cookies are round and soft after baking.'\n/>","src/content/fragments/en/super-cookies.mdx","b0c67adad40c177c","buttons",{"id":452,"data":454,"body":459,"filePath":460,"digest":461,"deferredRender":72},{"title":455,"subtitle":456,"lang":16,"tags":457,"type":427,"slug":452,"createdAt":458,"code":72,"draft":72},"Effets de survol de boutons","Simples mais efficaces.",[434],["Date","2020-10-08T09:00:00.000Z"],"## Styles généraux\n\nTous les boutons présents utilisent ces styles comme base en guise de « reset » :\n\n> N'oubliez pas de préfixer si besoin !\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Ajout d'icône\n\n\u003Cbutton role='none' class='btn btn-icon'>\n\t\u003Cspan>Icône\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('./assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double volet\n\n\u003Cbutton role='none' class='btn btn-rideau'>\n\t\u003Cspan>Volet\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Dégradé animé\n\n\u003Cbutton role='none' class='btn btn-gradient'>\n\t\u003Cspan>Dégradé\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Échelle non desctructrice\n\n\u003Cbutton role='none' class='btn btn-scale'>\n\t\u003Cspan>Échelle\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/fr/buttons.mdx","f5d7b03520f96b04","image-full",{"id":462,"data":464,"body":470,"filePath":471,"digest":472,"deferredRender":72},{"title":465,"subtitle":466,"lang":16,"tags":467,"type":427,"slug":462,"createdAt":468,"updatedAt":469},"Image pleine largeur","Casser le conteneur.",[434],["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Image inline\n\nOn est parfois obligé d'utiliser des images dans des balises `img` plutôt que dans un `background` en css. Comment faire alors pour que l'image sorte de son conteneur pour en faire une bannière ? Exemple pratique à partir de ce même site.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_container_9e3939b3ae.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Contexte\n\nConsidérons le html suivant :\n\n```html\n\u003Csection class=\"container\">\n\t\u003Cdiv class=\"hero\">\n\t\t\u003Cimg class=\"hero__image\" src=\"hero.img\" />\n\t\u003C/div>\n\u003C/section>\n```\n\nEt le style suivant :\n\n```css\n.container {\n\tpadding: 0 14px;\n\tmargin-left: auto;\n\tmargin-right: auto;\n\tmax-width: 1040px;\n}\nimg {\n\tmax-width: 100%;\n\theight: auto;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_original_d49f0d11bf.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Déborder du conteneur\n\nAfin de faire prendre à l'image toute la largeur, on agit sur son conteneur :\n\n```css\n.hero {\n\tmargin-left: calc(50% - 50vw);\n\tposition: relative;\n\twidth: 100vw;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_full_2a902f9539.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Faire une bannière\n\nOn peut alors réduire la hauteur du conteneur pour obtenir une bannière plutôt que l'image entière et faire correspondre la hauteur de l'image à la hauteur du conteneur :\n\n```css\n.hero {\n\theight: 200px;\n}\n.hero__image {\n\theight: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_height_81b4ce969a.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nIl faut ensuite forcer l'image à prendre toute la largeur du conteneur :\n\n```css\n.hero__image {\n\twidth: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_deformed_479046d2cb.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nPas top…\n\n### J'ai cassé l'image…\n\n**ENFIN** le code magique pour redonner son ratio à l'image sans la déformer :\n\n```css\n.hero__image {\n\tobject-fit: cover;\n\tobject-position: center; /* à positionner comme on veut */\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_6c164e82b3.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nCette technique s'apparente à l'utilisation d'une image de background mais en dur 😁\n\n## TL;DR\n\nLe code complet :\n\n```css\n.hero {\n\tmargin-left: calc(50% - 50vw);\n\tposition: relative;\n\twidth: 100vw;\n\theight: 200px;\n}\n.hero__image {\n\twidth: 100%;\n\theight: 100%;\n\t-o-object-fit: cover;\n\tobject-fit: cover;\n\t-o-object-position: center;\n\tobject-position: center;\n}\n```","src/content/fragments/fr/image-full.mdx","91ebd97eef5cb8a4","super-cookies",{"id":473,"data":475,"body":481,"filePath":482,"digest":483,"deferredRender":72},{"title":476,"subtitle":477,"lang":16,"tags":478,"type":427,"slug":473,"createdAt":480},"Les meilleurs cookies","Des gâteaux sans consentement.",[479],"cuisine",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Version végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 3/4 de l'aquafaba de 400g de pois chiche (l'eau des pois chiche)\n- 125 grammes d'huile de noix de coco\n- 2 cuillères à café de sirop d'érable\n- 1 plaquette de chocolat (noir) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre si besoin l'huile de noix de coco à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (huile, aquafaba, sirop d'érable)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Version non végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 1 œuf\n- 125 grammes de beurre fondu\n- 2 cuillères à café de miel\n- 1 plaquette de chocolat (noir/blanc/les deux) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre le beurre à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (beurre fondu, œuf, miel)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Notes\n\nLe chocolat peut-être remplacé par n'importe quoi comme des noix, des raisins secs, des légos… (mangez pas des légos soyez sérieux).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Tous les ingrédients mélangés forment une pâte marron.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Les cookies cuits sont bombés et très moelleux.'\n/>","src/content/fragments/fr/super-cookies.mdx","f7a802e0b68cb04a","en-toulouse-fun",{"id":484,"data":486,"body":492,"filePath":493,"digest":494,"rendered":495},{"title":487,"subtitle":488,"lang":68,"tags":489,"type":435,"slug":484,"createdAt":491},"Toulouse yourself","Only the bestest",[490],"lifestyle",["Date","2022-06-22T15:34:45.000Z"],"Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite. \n**It's always a good idea to make a reservation!**\n\n## Restaurants\n\n### French cuisine\n\n- [Solides](https://www.solides.fr/) — semi-gastronomic\n- [Les impulsifs](https://les-impulsifs-toulouse.eatbu.com/?lang=en) — semi-gastronomic\n- [Sixta](https://sixta-toulouse.fr/) — vege/vegan/gluten friendly\n- [Attila](https://attila.site-solocal.com/) — great **fish restaurant,** just above the Victor Hugo market\n- [Chez Emile](https://www.restaurant-emile.com/) - best [cassoulet](https://en.wikipedia.org/wiki/Cassoulet) in town (or so I'm told)\n\n### Korean\n\n- [Le ptit Louis](https://leptitlouis.fr/) — best of its kind, **only for lunch**\n- [Kongbap](https://kong-bap.com/) — street-food like\n\n### Japanese\n\n- [Iori](https://www.iori.fr/) — best ramen\n- [Japoyaki](https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402) — best sushi/sashimis\n\n## Drinks and snacks\n\n### Bars\n\n- [Le Bièrographe](https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327) — all time favourite, **check out the typical toulouse basement**\n- [A Taula](https://www.facebook.com/ataulatolosa/) — all time favourite in summer, **amazing terrace,** also: great tapas\n- [The Hopscotch Pub](https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385) — good beers, good whiskies, good cocktials, good food\n\n### Cafés & tea rooms\n\n- [Bapz](https://www.bapz.fr/contact) — Excellent pastries / hot beverages\n- [Ô thé divin](https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/) — nice lunch options\n- [Les Rêveries d’Hercule](https://www.lesreveriesdhercule.com/) — Pottery Café, relaxing activity (ceramics need to be baked, there'll be a delay to get them back)\n- Bonus: the best bakeries in [Carmes](https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872) and [Saint-Aubin](https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694) — croissants, baguettes **traditions**, chocolatines and more\n\n### Wine shops\n\n- [l'envie du sud](https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930) — amazing selection of wines and other spirits, excellent advice from the staff\n- [enoteca](https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952) — smaller selection but more beers and great advice from the staff as well\n\n## Other delights\n\n### Ice creams\n\n- [Forno gusto](https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450) — only in the summer\n- [Moustache](https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540) — lots of flavours\n\n### Cheese shop\n\n- [Xavier](https://xavier.fr/) — one of the **best of the country**, two shops in Toulouse, including one at Victor Hugo market\n- [Massembea](https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490) — a serious contender in Toulouse (weird hours)\n\n### Delicatessen\n\n- [Café Bacquié](http://cafe-bacquie.com/) — stock up on fine foods, coffees, teas and other great quality products","src/content/fragments/en/toulouse-fun.md","370491cc68079e8c",{"html":496,"metadata":497},"\u003Cp>Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite.\u003Cbr>\n\u003Cstrong>It’s always a good idea to make a reservation!\u003C/strong>\u003C/p>\n\u003Ch2 id=\"restaurants\">Restaurants\u003C/h2>\n\u003Ch3 id=\"french-cuisine\">French cuisine\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.solides.fr/\">Solides\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://les-impulsifs-toulouse.eatbu.com/?lang=en\">Les impulsifs\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://sixta-toulouse.fr/\">Sixta\u003C/a> — vege/vegan/gluten friendly\u003C/li>\n\u003Cli>\u003Ca href=\"https://attila.site-solocal.com/\">Attila\u003C/a> — great \u003Cstrong>fish restaurant,\u003C/strong> just above the Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.restaurant-emile.com/\">Chez Emile\u003C/a> - best \u003Ca href=\"https://en.wikipedia.org/wiki/Cassoulet\">cassoulet\u003C/a> in town (or so I’m told)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"korean\">Korean\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://leptitlouis.fr/\">Le ptit Louis\u003C/a> — best of its kind, \u003Cstrong>only for lunch\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://kong-bap.com/\">Kongbap\u003C/a> — street-food like\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"japanese\">Japanese\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.iori.fr/\">Iori\u003C/a> — best ramen\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402\">Japoyaki\u003C/a> — best sushi/sashimis\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"drinks-and-snacks\">Drinks and snacks\u003C/h2>\n\u003Ch3 id=\"bars\">Bars\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327\">Le Bièrographe\u003C/a> — all time favourite, \u003Cstrong>check out the typical toulouse basement\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.facebook.com/ataulatolosa/\">A Taula\u003C/a> — all time favourite in summer, \u003Cstrong>amazing terrace,\u003C/strong> also: great tapas\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385\">The Hopscotch Pub\u003C/a> — good beers, good whiskies, good cocktials, good food\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cafés--tea-rooms\">Cafés & tea rooms\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.bapz.fr/contact\">Bapz\u003C/a> — Excellent pastries / hot beverages\u003C/li>\n\u003Cli>\u003Ca href=\"https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/\">Ô thé divin\u003C/a> — nice lunch options\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lesreveriesdhercule.com/\">Les Rêveries d’Hercule\u003C/a> — Pottery Café, relaxing activity (ceramics need to be baked, there’ll be a delay to get them back)\u003C/li>\n\u003Cli>Bonus: the best bakeries in \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872\">Carmes\u003C/a> and \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694\">Saint-Aubin\u003C/a> — croissants, baguettes \u003Cstrong>traditions\u003C/strong>, chocolatines and more\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"wine-shops\">Wine shops\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930\">l’envie du sud\u003C/a> — amazing selection of wines and other spirits, excellent advice from the staff\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952\">enoteca\u003C/a> — smaller selection but more beers and great advice from the staff as well\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"other-delights\">Other delights\u003C/h2>\n\u003Ch3 id=\"ice-creams\">Ice creams\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450\">Forno gusto\u003C/a> — only in the summer\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540\">Moustache\u003C/a> — lots of flavours\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cheese-shop\">Cheese shop\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://xavier.fr/\">Xavier\u003C/a> — one of the \u003Cstrong>best of the country\u003C/strong>, two shops in Toulouse, including one at Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490\">Massembea\u003C/a> — a serious contender in Toulouse (weird hours)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"delicatessen\">Delicatessen\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"http://cafe-bacquie.com/\">Café Bacquié\u003C/a> — stock up on fine foods, coffees, teas and other great quality products\u003C/li>\n\u003C/ul>",{"headings":498,"imagePaths":535,"frontmatter":536},[499,502,505,508,511,514,517,520,523,526,529,532],{"depth":150,"slug":500,"text":501},"restaurants","Restaurants",{"depth":154,"slug":503,"text":504},"french-cuisine","French cuisine",{"depth":154,"slug":506,"text":507},"korean","Korean",{"depth":154,"slug":509,"text":510},"japanese","Japanese",{"depth":150,"slug":512,"text":513},"drinks-and-snacks","Drinks and snacks",{"depth":154,"slug":515,"text":516},"bars","Bars",{"depth":154,"slug":518,"text":519},"cafés--tea-rooms","Cafés & tea rooms",{"depth":154,"slug":521,"text":522},"wine-shops","Wine shops",{"depth":150,"slug":524,"text":525},"other-delights","Other delights",{"depth":154,"slug":527,"text":528},"ice-creams","Ice creams",{"depth":154,"slug":530,"text":531},"cheese-shop","Cheese shop",{"depth":154,"slug":533,"text":534},"delicatessen","Delicatessen",[],{"title":487,"subtitle":488,"lang":68,"slug":484,"excerpt":537,"tags":538,"type":435,"createdAt":223},"Gonna have to trust me on this ¯\\_(ツ)_/¯",[490],"en-visited-links",{"id":539,"data":541,"body":438,"filePath":545,"digest":546,"rendered":547},{"title":542,"subtitle":209,"lang":68,"tags":543,"type":435,"slug":539,"createdAt":544,"draft":72},"Visited links and visuel aid",[18],["Date","2023-06-06T18:34:00.000Z"],"src/content/fragments/en/visited-links.md","cb7c11c12c25067e",{"html":548,"metadata":549},"\u003Cp>\u003Ca href=\"/en/snippets\">Go back to available snippets\u003C/a>\u003C/p>",{"headings":550,"imagePaths":551,"frontmatter":552},[],[],{"title":542,"subtitle":209,"lang":68,"draft":72,"slug":539,"excerpt":553,"tags":554,"type":435,"createdAt":555},"Petit hack CSS",[18],"2023-06-06T18:34:00.000Z","array-vs-array",{"id":556,"data":558,"body":564,"filePath":565,"digest":566,"rendered":567},{"title":559,"subtitle":560,"lang":16,"tags":561,"type":427,"slug":556,"createdAt":563,"draft":72},"Filtrer un array avec un autre array","En cours de traduction.",[562],"nuxt.js",["Date","2022-06-08T14:24:06.000Z"],"[Voir les fragments disponibles](/fragments)","src/content/fragments/fr/array-vs-array.md","7321d444177c3841",{"html":568,"metadata":569},"\u003Cp>\u003Ca href=\"/fragments\">Voir les fragments disponibles\u003C/a>\u003C/p>",{"headings":570,"imagePaths":571,"frontmatter":572},[],[],{"title":559,"subtitle":560,"lang":16,"draft":72,"slug":556,"createdAt":170,"excerpt":560,"tags":573,"type":427},[562],"toulouse-fun",{"id":574,"data":576,"body":564,"filePath":579,"digest":580,"rendered":581},{"title":487,"subtitle":560,"lang":16,"tags":577,"type":427,"slug":574,"createdAt":578,"draft":72},[490],["Date","2022-06-22T15:34:45.000Z"],"src/content/fragments/fr/toulouse-fun.md","a0c25b438b34c05e",{"html":568,"metadata":582},{"headings":583,"imagePaths":584,"frontmatter":585},[],[],{"title":487,"subtitle":560,"lang":16,"draft":72,"slug":574,"createdAt":223,"excerpt":560,"tags":586,"type":427},[490],"en-acme-sh-tls-cert",{"id":587,"data":589,"body":595,"filePath":596,"digest":597,"rendered":598},{"title":590,"subtitle":591,"lang":68,"tags":592,"type":435,"slug":587,"createdAt":594},"Strong TLS certificates with acme.sh","384-bit of https",[593],"security",["Date","2022-06-08T14:24:06.000Z"],"## Disclaimer\n\nI'm, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs. \nThis is why I've switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nYou can learn (far) more by reading [this topic](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) and its linked resources.\n\n## Requirements\n\n### Installing acme.sh\n\nFor automation and ease of use purposes, I'm using [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# for using standalone mode, you might have to install as sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changing default authority\n\nBy default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let's Encrypt because according to acme.sh, they're the only ones offering ECC capabilities.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Using your DNS api\n\nIf available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports [a lot](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) of DNS providers.\n\n### Define an api key\n\nFollow the [docs](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) for your DNS provider, usually:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Issue the cert\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Using standalone mode\n\nIf you don't have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\n\nPort `80` must be free.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Examples\n\n### Multi domains standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domain DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Next steps\n\nThe ECC certificate alone will not grant you a high/perfect score.\n\n### TLS version\n\nLimit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a [5% compatibility gap](https://caniuse.com/?search=tls%201.) with 1.2).\n\n### HSTS\n\nUse the [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/) header.\n\n```\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Cipher suite\n\nUse recent and strong ciphers. This is where my knowledge hits its limit… I'm having a really hard time understanding what to use and why.\n\nI've based my initial choices of ciphers on [this list](https://tls.imirhil.fr/ciphers), cross referencing it with (older?) [browser compatibility](https://tls.imirhil.fr/suite).\n\nI then asked [Aeris](https://twitter.com/aeris22), the creator of [tls.imirhil.fr](https://tls.imirhil.fr), about it and he advised me to use the following:\n\n```\nECDHE+AES:ECDHE+CHACHA20\n```\n\nIn order to achieve a perfect score, we can be a little more restrictive with:\n\n```\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/en/acme-sh-tls-cert.md","41577e8aee884f85",{"html":599,"metadata":600},"\u003Ch2 id=\"disclaimer\">Disclaimer\u003C/h2>\n\u003Cp>I’m, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs.\u003Cbr>\nThis is why I’ve switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>You can learn (far) more by reading \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">this topic\u003C/a> and its linked resources.\u003C/p>\n\u003Ch2 id=\"requirements\">Requirements\u003C/h2>\n\u003Ch3 id=\"installing-acmesh\">Installing acme.sh\u003C/h3>\n\u003Cp>For automation and ease of use purposes, I’m using \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># for using standalone mode, you might have to install as sudo\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">curl\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> https://get.acme.sh\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#B392F0\"> sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -s\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> email=mail@domain.tld\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"changing-default-authority\">Changing default authority\u003C/h3>\n\u003Cp>By default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let’s Encrypt because according to acme.sh, they’re the only ones offering ECC capabilities.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --set-default-ca\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --server\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> letsencrypt\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"using-your-dns-api\">Using your DNS api\u003C/h2>\n\u003Cp>If available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">a lot\u003C/a> of DNS providers.\u003C/p>\n\u003Ch3 id=\"define-an-api-key\">Define an api key\u003C/h3>\n\u003Cp>Follow the \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">docs\u003C/a> for your DNS provider, usually:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">export\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> PROVIDER_Key\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"YOUR_API_KEY\"\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"issue-the-cert\">Issue the cert\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"using-standalone-mode\">Using standalone mode\u003C/h2>\n\u003Cp>If you don’t have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\u003C/p>\n\u003Cp>Port \u003Ccode>80\u003C/code> must be free.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"examples\">Examples\u003C/h2>\n\u003Ch3 id=\"multi-domains-standalone\">Multi domains standalone\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> www.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> subdomain.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"wildcard-domain-dns\">Wildcard domain DNS\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '*.domain.tld'\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"next-steps\">Next steps\u003C/h2>\n\u003Cp>The ECC certificate alone will not grant you a high/perfect score.\u003C/p>\n\u003Ch3 id=\"tls-version\">TLS version\u003C/h3>\n\u003Cp>Limit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a \u003Ca href=\"https://caniuse.com/?search=tls%201.\">5% compatibility gap\u003C/a> with 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Use the \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a> header.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>Strict-Transport-Security: max-age=31536000; includeSubDomains\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"cipher-suite\">Cipher suite\u003C/h3>\n\u003Cp>Use recent and strong ciphers. This is where my knowledge hits its limit… I’m having a really hard time understanding what to use and why.\u003C/p>\n\u003Cp>I’ve based my initial choices of ciphers on \u003Ca href=\"https://tls.imirhil.fr/ciphers\">this list\u003C/a>, cross referencing it with (older?) \u003Ca href=\"https://tls.imirhil.fr/suite\">browser compatibility\u003C/a>.\u003C/p>\n\u003Cp>I then asked \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, the creator of \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, about it and he advised me to use the following:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>In order to achieve a perfect score, we can be a little more restrictive with:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES256:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":601,"imagePaths":647,"frontmatter":648},[602,605,608,611,614,617,620,623,626,629,632,635,638,641,644],{"depth":150,"slug":603,"text":604},"disclaimer","Disclaimer",{"depth":150,"slug":606,"text":607},"requirements","Requirements",{"depth":154,"slug":609,"text":610},"installing-acmesh","Installing acme.sh",{"depth":154,"slug":612,"text":613},"changing-default-authority","Changing default authority",{"depth":150,"slug":615,"text":616},"using-your-dns-api","Using your DNS api",{"depth":154,"slug":618,"text":619},"define-an-api-key","Define an api key",{"depth":154,"slug":621,"text":622},"issue-the-cert","Issue the cert",{"depth":150,"slug":624,"text":625},"using-standalone-mode","Using standalone mode",{"depth":150,"slug":627,"text":628},"examples","Examples",{"depth":154,"slug":630,"text":631},"multi-domains-standalone","Multi domains standalone",{"depth":154,"slug":633,"text":634},"wildcard-domain-dns","Wildcard domain DNS",{"depth":150,"slug":636,"text":637},"next-steps","Next steps",{"depth":154,"slug":639,"text":640},"tls-version","TLS version",{"depth":154,"slug":642,"text":643},"hsts","HSTS",{"depth":154,"slug":645,"text":646},"cipher-suite","Cipher suite",[],{"title":590,"subtitle":591,"lang":68,"slug":587,"createdAt":170,"excerpt":649,"tags":650,"type":435},"Real cert have curves.",[593],"acme-sh-tls-cert",{"id":651,"data":653,"body":659,"filePath":660,"digest":661,"rendered":662},{"title":654,"subtitle":655,"lang":16,"tags":656,"type":427,"slug":651,"createdAt":658},"Certificates TLS robustes avec acme.sh","384-bit de https",[657],"sécurité",["Date","2022-06-08T14:24:06.000Z"],"## Attention\n\nJe ne suis pas du tout un expert en sécurité. J'aime juste les trucs nouveaux et stylés des internets. \nC'est pourquoi j'ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J'ai maintenant un joli 100/100 sur [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nVous pouvez en apprendre (beaucoup) plus [ici](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) et sur les liens cités (en anglais).\n\n## Prérequis\n\n### Installer acme.sh\n\nPour des raisons de simplicité et d'automatisation, j'utilise [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changer l'authorité par défaut\n\nPar défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let's Encrypt car, d'après acme.sh, ils sont les seuls à proposer des certificats ECC.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Utiliser l'api DNS\n\nSi vous en avez la possibilité, la façon la plus simple de générer un certificat est via l'api de votre fournisseur DNS. acme.sh supporte [énormément](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) de fournisseurs DNS.\n\n### Definir la clé api\n\nSuivez la [documentation](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) pour votre fournisseur DNS, généralement:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Émettre le certificat\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Utiliser le mode standalone\n\nSi vous n'avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s'occupe de toutes les vérifications.\n\nLe port `80` doit être disponible.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Exemples\n\n### Multi domaines standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domaine DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Étapes supplémentaires\n\nLe certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\n\n### Version TLS\n\nLimiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu [la différence de compatibilité de 5%](https://caniuse.com/?search=tls%201.) avec 1.2).\n\n### HSTS\n\nUtiliser le header [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/).\n\n```\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Suite cryptographique\n\nUtiliser une suite cryptographique récente et robuste. C'est ici que mes connaissances deviennent limitées… J'ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\n\nJ'avais basé ma première suite sur [cette liste](https://tls.imirhil.fr/ciphers), en la comparant avec celle de la compatibilité (d'anciens ?) [navigateurs](https://tls.imirhil.fr/suite).\n\nJ'ai ensuite demandé à [Aeris](https://twitter.com/aeris22), le créateur de [tls.imirhil.fr](https://tls.imirhil.fr), ses conseils sur cette suite. Il m'a recommandé d'utiliser :\n\n```\nECDHE+AES:ECDHE+CHACHA20\n```\n\nAfin d'atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\n\n```\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/fr/acme-sh-tls-cert.md","82e6d91747c28ea5",{"html":663,"metadata":664},"\u003Ch2 id=\"attention\">Attention\u003C/h2>\n\u003Cp>Je ne suis pas du tout un expert en sécurité. J’aime juste les trucs nouveaux et stylés des internets.\u003Cbr>\nC’est pourquoi j’ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J’ai maintenant un joli 100/100 sur \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>Vous pouvez en apprendre (beaucoup) plus \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">ici\u003C/a> et sur les liens cités (en anglais).\u003C/p>\n\u003Ch2 id=\"prérequis\">Prérequis\u003C/h2>\n\u003Ch3 id=\"installer-acmesh\">Installer acme.sh\u003C/h3>\n\u003Cp>Pour des raisons de simplicité et d’automatisation, j’utilise \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">curl\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> https://get.acme.sh\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#B392F0\"> sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -s\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> email=mail@domain.tld\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"changer-lauthorité-par-défaut\">Changer l’authorité par défaut\u003C/h3>\n\u003Cp>Par défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let’s Encrypt car, d’après acme.sh, ils sont les seuls à proposer des certificats ECC.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --set-default-ca\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --server\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> letsencrypt\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"utiliser-lapi-dns\">Utiliser l’api DNS\u003C/h2>\n\u003Cp>Si vous en avez la possibilité, la façon la plus simple de générer un certificat est via l’api de votre fournisseur DNS. acme.sh supporte \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">énormément\u003C/a> de fournisseurs DNS.\u003C/p>\n\u003Ch3 id=\"definir-la-clé-api\">Definir la clé api\u003C/h3>\n\u003Cp>Suivez la \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">documentation\u003C/a> pour votre fournisseur DNS, généralement:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">export\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> PROVIDER_Key\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"YOUR_API_KEY\"\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"émettre-le-certificat\">Émettre le certificat\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"utiliser-le-mode-standalone\">Utiliser le mode standalone\u003C/h2>\n\u003Cp>Si vous n’avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s’occupe de toutes les vérifications.\u003C/p>\n\u003Cp>Le port \u003Ccode>80\u003C/code> doit être disponible.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"exemples\">Exemples\u003C/h2>\n\u003Ch3 id=\"multi-domaines-standalone\">Multi domaines standalone\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> www.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> subdomain.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"wildcard-domaine-dns\">Wildcard domaine DNS\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '*.domain.tld'\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"étapes-supplémentaires\">Étapes supplémentaires\u003C/h2>\n\u003Cp>Le certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\u003C/p>\n\u003Ch3 id=\"version-tls\">Version TLS\u003C/h3>\n\u003Cp>Limiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu \u003Ca href=\"https://caniuse.com/?search=tls%201.\">la différence de compatibilité de 5%\u003C/a> avec 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Utiliser le header \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a>.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>Strict-Transport-Security: max-age=31536000; includeSubDomains\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"suite-cryptographique\">Suite cryptographique\u003C/h3>\n\u003Cp>Utiliser une suite cryptographique récente et robuste. C’est ici que mes connaissances deviennent limitées… J’ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\u003C/p>\n\u003Cp>J’avais basé ma première suite sur \u003Ca href=\"https://tls.imirhil.fr/ciphers\">cette liste\u003C/a>, en la comparant avec celle de la compatibilité (d’anciens ?) \u003Ca href=\"https://tls.imirhil.fr/suite\">navigateurs\u003C/a>.\u003C/p>\n\u003Cp>J’ai ensuite demandé à \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, le créateur de \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, ses conseils sur cette suite. Il m’a recommandé d’utiliser :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Afin d’atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES256:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":665,"imagePaths":709,"frontmatter":710},[666,669,672,675,678,681,684,687,690,693,696,699,702,705,706],{"depth":150,"slug":667,"text":668},"attention","Attention",{"depth":150,"slug":670,"text":671},"prérequis","Prérequis",{"depth":154,"slug":673,"text":674},"installer-acmesh","Installer acme.sh",{"depth":154,"slug":676,"text":677},"changer-lauthorité-par-défaut","Changer l’authorité par défaut",{"depth":150,"slug":679,"text":680},"utiliser-lapi-dns","Utiliser l’api DNS",{"depth":154,"slug":682,"text":683},"definir-la-clé-api","Definir la clé api",{"depth":154,"slug":685,"text":686},"émettre-le-certificat","Émettre le certificat",{"depth":150,"slug":688,"text":689},"utiliser-le-mode-standalone","Utiliser le mode standalone",{"depth":150,"slug":691,"text":692},"exemples","Exemples",{"depth":154,"slug":694,"text":695},"multi-domaines-standalone","Multi domaines standalone",{"depth":154,"slug":697,"text":698},"wildcard-domaine-dns","Wildcard domaine DNS",{"depth":150,"slug":700,"text":701},"étapes-supplémentaires","Étapes supplémentaires",{"depth":154,"slug":703,"text":704},"version-tls","Version TLS",{"depth":154,"slug":642,"text":643},{"depth":154,"slug":707,"text":708},"suite-cryptographique","Suite cryptographique",[],{"title":654,"subtitle":655,"lang":16,"slug":651,"createdAt":170,"excerpt":711,"tags":712,"type":427},"La sécurité avec des courbes.",[657],"visited-links",{"id":713,"data":715,"body":721,"filePath":722,"digest":723,"rendered":724},{"title":716,"subtitle":717,"lang":16,"tags":718,"type":435,"slug":713,"createdAt":719,"draft":720},"Liens visités et indication visuelle","Comment différencier les liens déjà cliqués",[18],["Date","2023-06-06T18:34:00.000Z"],false,"## La théorie\n\nIl est possible sur le web d'appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu'un lien visité est violet.\n\nGénéralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L'information qu'un lien a déjà été visité ne semble pas indispensable à la navigation. C'est sûrement vrai, mais personnellement, je suis assez content d'avoir un rappel des pages que j'ai déjà consultées lorsque je navigue.\n\nUne information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J'ai alors cherché un moyen d'ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n'est certainement pas idéale, elle se rapproche plus d'une expérience, à priori inoffensive pour l'internaute.\n\n## La spécification\n\nQuand je me suis intéressé à ce qu'il était possible de faire avec les liens déjà visités, j'ai découvert qu'extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu'il était possible de récupérer l'historique de navigation d'un utilisateur grâce aux styles des liens visités. Le sélecteur `:visited` a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. [Plus d'informations dans cet article.](https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector)\n\n## La pratique\n\nQue faire alors, en terme de style, quand on ne peut changer que des couleurs ?\n\nD'après MDN, les propriétés suivantes sont modifiables :\n\n- `color`\n- `background-color`\n- `border-color` (et les propriétés détaillées associées),\n- `column-rule-color`\n- `outline-color`\n- `text-decoration-color`\n- `text-emphasis-color`\n- Les composantes de couleur liées aux attributs SVG `fill` et `stroke`.\n\nChanger la couleur d'un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\n\nEn revanche, il est possible de \" masquer \" un élément en modifiant sa couleur pour qu'elle corresponde à la couleur du fond de la page ou de l'élément parent. On pourrait ainsi imaginer masquer une `border` ou un `outline`.\n\nJ'ai personnellement choisi de faire différemment. J'ai décidé d'utiliser un pseudo-élément `::before` sur l'état non visité du lien puis de le masquer quand celui-ci devient visité.\n\n### Le code\n\n```css\na {\n\tposition: relative;\n\ttext-decoration: none;\n}\na::before {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 0;\n\tinline-size: 2px;\n\tblock-size: 2px;\n\tborder-radius: 4px;\n\ttransform: translate(-6px, 0);\n\tbackground-color: grey;\n}\na:visited::before {\n\tbackground-color: white;\n}\n```\n\nCes règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\n\n### Accessibilité\n\nOn pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété `content` mais les lecteurs d'écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d'écrans annoncent déjà si un lien est visité avant de lire son intitulé.\n\n## Aller plus loin\n\nAfin de pousser l'expérience un peu plus loin, j'ai tenté d'utiliser des éléments plus explicites pour signifier l'état visité du lien. Bien qu'encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\n\nL'idée est d'avoir un `::before` et un `::after`, chacun contenant une icône en base 64 blanche en tant qu'image de fond. Quand le lien est non visité, le `::before` contient un fond coloré qui fait apparaître l'icône. Quand le lien passe en visité, le fond du `::before` devient blanc et celui du `::after` devient coloré, ce qui masque la première icône et affiche la deuxième.\n\nIl est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l'une sur l'autre.\n\n[Voir la démo sur codepen.](https://codepen.io/narduin/pen/VwVwmrO)","src/content/fragments/fr/visited-links.md","52385f4f8bc864b2",{"html":725,"metadata":726},"\u003Ch2 id=\"la-théorie\">La théorie\u003C/h2>\n\u003Cp>Il est possible sur le web d’appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu’un lien visité est violet.\u003C/p>\n\u003Cp>Généralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L’information qu’un lien a déjà été visité ne semble pas indispensable à la navigation. C’est sûrement vrai, mais personnellement, je suis assez content d’avoir un rappel des pages que j’ai déjà consultées lorsque je navigue.\u003C/p>\n\u003Cp>Une information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J’ai alors cherché un moyen d’ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n’est certainement pas idéale, elle se rapproche plus d’une expérience, à priori inoffensive pour l’internaute.\u003C/p>\n\u003Ch2 id=\"la-spécification\">La spécification\u003C/h2>\n\u003Cp>Quand je me suis intéressé à ce qu’il était possible de faire avec les liens déjà visités, j’ai découvert qu’extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu’il était possible de récupérer l’historique de navigation d’un utilisateur grâce aux styles des liens visités. Le sélecteur \u003Ccode>:visited\u003C/code> a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector\">Plus d’informations dans cet article.\u003C/a>\u003C/p>\n\u003Ch2 id=\"la-pratique\">La pratique\u003C/h2>\n\u003Cp>Que faire alors, en terme de style, quand on ne peut changer que des couleurs ?\u003C/p>\n\u003Cp>D’après MDN, les propriétés suivantes sont modifiables :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>background-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>border-color\u003C/code> (et les propriétés détaillées associées),\u003C/li>\n\u003Cli>\u003Ccode>column-rule-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>outline-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-decoration-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-emphasis-color\u003C/code>\u003C/li>\n\u003Cli>Les composantes de couleur liées aux attributs SVG \u003Ccode>fill\u003C/code> et \u003Ccode>stroke\u003C/code>.\u003C/li>\n\u003C/ul>\n\u003Cp>Changer la couleur d’un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\u003C/p>\n\u003Cp>En revanche, il est possible de ” masquer ” un élément en modifiant sa couleur pour qu’elle corresponde à la couleur du fond de la page ou de l’élément parent. On pourrait ainsi imaginer masquer une \u003Ccode>border\u003C/code> ou un \u003Ccode>outline\u003C/code>.\u003C/p>\n\u003Cp>J’ai personnellement choisi de faire différemment. J’ai décidé d’utiliser un pseudo-élément \u003Ccode>::before\u003C/code> sur l’état non visité du lien puis de le masquer quand celui-ci devient visité.\u003C/p>\n\u003Ch3 id=\"le-code\">Le code\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">a\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">relative\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttext-decoration\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">a\u003C/span>\u003Cspan style=\"color:#B392F0\">::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttop\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tleft\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tinline-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tblock-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder-radius\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">4\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translate\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-6\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">grey\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">a\u003C/span>\u003Cspan style=\"color:#B392F0\">:visited::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">white\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Ces règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\u003C/p>\n\u003Ch3 id=\"accessibilité\">Accessibilité\u003C/h3>\n\u003Cp>On pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété \u003Ccode>content\u003C/code> mais les lecteurs d’écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d’écrans annoncent déjà si un lien est visité avant de lire son intitulé.\u003C/p>\n\u003Ch2 id=\"aller-plus-loin\">Aller plus loin\u003C/h2>\n\u003Cp>Afin de pousser l’expérience un peu plus loin, j’ai tenté d’utiliser des éléments plus explicites pour signifier l’état visité du lien. Bien qu’encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\u003C/p>\n\u003Cp>L’idée est d’avoir un \u003Ccode>::before\u003C/code> et un \u003Ccode>::after\u003C/code>, chacun contenant une icône en base 64 blanche en tant qu’image de fond. Quand le lien est non visité, le \u003Ccode>::before\u003C/code> contient un fond coloré qui fait apparaître l’icône. Quand le lien passe en visité, le fond du \u003Ccode>::before\u003C/code> devient blanc et celui du \u003Ccode>::after\u003C/code> devient coloré, ce qui masque la première icône et affiche la deuxième.\u003C/p>\n\u003Cp>Il est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l’une sur l’autre.\u003C/p>\n\u003Cp>\u003Ca href=\"https://codepen.io/narduin/pen/VwVwmrO\">Voir la démo sur codepen.\u003C/a>\u003C/p>",{"headings":727,"imagePaths":745,"frontmatter":746},[728,731,734,737,740,742],{"depth":150,"slug":729,"text":730},"la-théorie","La théorie",{"depth":150,"slug":732,"text":733},"la-spécification","La spécification",{"depth":150,"slug":735,"text":736},"la-pratique","La pratique",{"depth":154,"slug":738,"text":739},"le-code","Le code",{"depth":154,"slug":32,"text":741},"Accessibilité",{"depth":150,"slug":743,"text":744},"aller-plus-loin","Aller plus loin",[],{"title":716,"subtitle":717,"lang":16,"draft":720,"slug":713,"excerpt":553,"tags":747,"type":435,"createdAt":555},[18],"en-buttons",{"id":748,"data":750,"body":755,"filePath":756,"digest":757,"rendered":758},{"title":751,"subtitle":752,"lang":68,"tags":753,"type":435,"slug":748,"createdAt":754,"code":72,"draft":72},"Buttons hover","Simple, but nice.",[434],["Date","2020-10-08T09:00:00.000Z"],"## General rules\n\nAll the buttons use these styles as a “reset”:\n\n> Don't forget to prefix if necessary!\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Add an icon\n\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('~assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double shutter down\n\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Animated gradient\n\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Non destructive scale\n\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/en/buttons.md","ea9a5513a5a4cef4",{"html":759,"metadata":760},"\u003Ch2 id=\"general-rules\">General rules\u003C/h2>\n\u003Cp>All the buttons use these styles as a “reset”:\u003C/p>\n\u003Cblockquote>\n\u003Cp>Don’t forget to prefix if necessary!\u003C/p>\n\u003C/blockquote>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tmargin\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">20\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tpadding\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">12\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 26\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">relative\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tdisplay\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">inline-block\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\toverflow\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hidden\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tfont-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">20\u003C/span>\u003Cspan style=\"color:#F97583\">rem\u003C/span>\u003Cspan style=\"color:#E1E4E8\">; \u003C/span>\u003Cspan style=\"color:#6A737D\">/* 20px */\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tline-height\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">1.6\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttext-align\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">center\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttext-decoration\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tfont-weight\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">bold\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcursor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">pointer\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder-radius\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t-moz-appearance\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t-webkit-appearance\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">white\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hotpink\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: background-color \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"add-an-icon\">Add an icon\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hotpink\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">url\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'~assets/svg/arrow-right-white.svg'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">20\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttop\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tright\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translate\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">40\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">-50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">ease\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:hover\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:focus\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">darkorchid\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:hover::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:focus::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translate\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-10\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">-50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon\u003C/span>\u003Cspan style=\"color:#F97583\"> >\u003C/span>\u003Cspan style=\"color:#85E89D\"> span\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tdisplay\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">inline-block\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\theight\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:hover\u003C/span>\u003Cspan style=\"color:#F97583\"> >\u003C/span>\u003Cspan style=\"color:#85E89D\"> span\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:focus\u003C/span>\u003Cspan style=\"color:#F97583\"> >\u003C/span>\u003Cspan style=\"color:#85E89D\"> span\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translateX\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-10\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"double-shutter-down\">Double shutter down\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> solid\u003C/span>\u003Cspan style=\"color:#79B8FF\"> #10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">#10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">transparent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">color\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">white\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hotpink\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">darkorchid\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\theight\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbottom\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tleft\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tz-index\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">-1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition-timing-function\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition-timing-function\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">cubic-bezier\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">0.75\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.125\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:focus::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:focus::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translateY\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:focus::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition-delay\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.175\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"animated-gradient\">Animated gradient\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-gradient\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">linear-gradient\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-45\u003C/span>\u003Cspan style=\"color:#F97583\">deg\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#ee7752\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#e73c7e\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#23a6d5\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#23d5ab\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">400\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 400\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tanimation\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: GradientReverse \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.5\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:#79B8FF\"> normal\u003C/span>\u003Cspan style=\"color:#79B8FF\"> forwards\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-gradient:hover\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-gradient:focus\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tanimation\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: Gradient \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.5\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:#79B8FF\"> normal\u003C/span>\u003Cspan style=\"color:#79B8FF\"> forwards\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">@keyframes\u003C/span>\u003Cspan style=\"color:#FFAB70\"> Gradient\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t0%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t100%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">@keyframes\u003C/span>\u003Cspan style=\"color:#FFAB70\"> GradientReverse\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t0%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t100%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"non-destructive-scale\">Non destructive scale\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\toverflow\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">visible\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">#10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">transparent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttop\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tleft\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbottom\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> solid\u003C/span>\u003Cspan style=\"color:#79B8FF\"> #10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder-radius\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale:hover::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale:focus::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">scale\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">1.1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":761,"imagePaths":777,"frontmatter":778},[762,765,768,771,774],{"depth":150,"slug":763,"text":764},"general-rules","General rules",{"depth":150,"slug":766,"text":767},"add-an-icon","Add an icon",{"depth":150,"slug":769,"text":770},"double-shutter-down","Double shutter down",{"depth":150,"slug":772,"text":773},"animated-gradient","Animated gradient",{"depth":150,"slug":775,"text":776},"non-destructive-scale","Non destructive scale",[],{"title":751,"subtitle":752,"lang":68,"slug":748,"draft":72,"excerpt":779,"tags":780,"code":72,"type":435,"createdAt":781},"Easy to grab and use hover effects.",[434],"2020-10-08T09:00:00.000Z","en-array-vs-array",{"id":782,"data":784,"body":789,"filePath":790,"digest":791,"rendered":792},{"title":785,"subtitle":786,"lang":68,"tags":787,"type":435,"slug":782,"createdAt":788},"Filter an array against another array","Array vs Array.",[562],["Date","2022-06-08T14:24:06.000Z"],"## Context\n\nFor a project, I had to come up with a way to filter an array of objects based on another array of strings.\n\nIn other words, I needed to include every object which `user` property was found in the second array.\n\nHere is an example:\n\n```javascript\nconst skills = [\n\t{\n\t\tname: 'Be awesome',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Great jokes',\n\t\tuser: 'Jacques'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Beatriz'\n\t}\n]\n\nconst selectedUsers = ['Jean', 'Beatriz']\n```\n\nI thought it would be pretty easy but I guess I'm not familiar enough with javascript 😬\n\n## My solution\n\nAfter a bit of thinking, I came up with the following statement:\n\n> I need to filter the skills based on which users are selected. So I need to loop over the `selectedUsers` array and filter the skills according to their `user` value.\n\nAfter a bit more trials and errors, this is the code I ended up using in a `computed property`:\n\n```javascript\n// index.vue\nconst filteredSkills = selectedUsers.map((user) => {\n\treturn skills.filter((skill) => {\n\t\treturn skill.user === user\n\t})\n})\n```\n\nI used `map()` in order to loop on the second array and used its string value to only include the corresponding skills with `filter()`.\n\nI'm pretty sure there is a better way to do it though…","src/content/fragments/en/array-vs-array.md","c63ba57b1049cf4c",{"html":793,"metadata":794},"\u003Ch2 id=\"context\">Context\u003C/h2>\n\u003Cp>For a project, I had to come up with a way to filter an array of objects based on another array of strings.\u003C/p>\n\u003Cp>In other words, I needed to include every object which \u003Ccode>user\u003C/code> property was found in the second array.\u003C/p>\n\u003Cp>Here is an example:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> skills\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Be awesome'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jean'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Great jokes'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jacques'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jean'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Beatriz'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> selectedUsers\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jean'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Beatriz'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>I thought it would be pretty easy but I guess I’m not familiar enough with javascript 😬\u003C/p>\n\u003Ch2 id=\"my-solution\">My solution\u003C/h2>\n\u003Cp>After a bit of thinking, I came up with the following statement:\u003C/p>\n\u003Cblockquote>\n\u003Cp>I need to filter the skills based on which users are selected. So I need to loop over the \u003Ccode>selectedUsers\u003C/code> array and filter the skills according to their \u003Ccode>user\u003C/code> value.\u003C/p>\n\u003C/blockquote>\n\u003Cp>After a bit more trials and errors, this is the code I ended up using in a \u003Ccode>computed property\u003C/code>:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> filteredSkills\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> selectedUsers.\u003C/span>\u003Cspan style=\"color:#B392F0\">map\u003C/span>\u003Cspan style=\"color:#E1E4E8\">((\u003C/span>\u003Cspan style=\"color:#FFAB70\">user\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">=>\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">\treturn\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> skills.\u003C/span>\u003Cspan style=\"color:#B392F0\">filter\u003C/span>\u003Cspan style=\"color:#E1E4E8\">((\u003C/span>\u003Cspan style=\"color:#FFAB70\">skill\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">=>\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">\t\treturn\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> skill.user \u003C/span>\u003Cspan style=\"color:#F97583\">===\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> user\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t})\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">})\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>I used \u003Ccode>map()\u003C/code> in order to loop on the second array and used its string value to only include the corresponding skills with \u003Ccode>filter()\u003C/code>.\u003C/p>\n\u003Cp>I’m pretty sure there is a better way to do it though…\u003C/p>",{"headings":795,"imagePaths":802,"frontmatter":803},[796,799],{"depth":150,"slug":797,"text":798},"context","Context",{"depth":150,"slug":800,"text":801},"my-solution","My solution",[],{"title":785,"subtitle":786,"lang":68,"slug":782,"createdAt":170,"excerpt":804,"tags":805,"type":435},"My peak javascript",[562],"en-nuxt-graphql-static",{"id":806,"data":808,"body":814,"filePath":815,"digest":816,"rendered":817},{"title":809,"subtitle":810,"lang":68,"tags":811,"type":435,"slug":806,"createdAt":812,"updatedAt":813},"Static website and GraphQL queries with Nuxt.js","Graphql client is king.",[562],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## The problem\n\nI encountered a nasty bug while using static generation with Nuxt and [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (new tab)') client.\nI found [the issue](https://github.com/nuxt-community/apollo-module/issues/339 'Github issue on nuxt/apollo repository (new tab)') already reported on github.\n\nIt seems the module doesn't handle static generation correctly with `nuxt generate`.\n\nI could find request to my local API url after the static generation. Moreover, it also seemed like `\u003Cnuxt-link>` navigation was broken.\n\n## The solution 🙌\n\nFortunately, there is another Nuxt module that handles GraphQL requests!\n\n[Nuxt graphql request to the rescue!](https://github.com/gomah/nuxt-graphql-request)\n\n### The conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### The request\n\nThe best approach so far is to use `asyncData` in pages and `fetch` in components. Using `fetch` in pages does not work well at all with `nuxt generate`.\n\nI also install the `graphql-tag` package (only in `devDependencies`) to be able to import directly `.gql` files.\n\nQuery example:\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Inside a page\n\n```javascript\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n async asyncData({ $graphql }) {\n const data = await $graphql.default.request(homepageQuery)\n return { data }\n },\n}\n\u003C/script>\n```\n\n#### Inside a component\n\nIt is safer to wait until `fetch` has received a response before displaying anything. You can use `$fetchState` to be sure ([documentation](https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation on the fetch hook (new tab)')).\n\n```javascript\n// Header.vue\n\u003Ctemplate>\n \u003Cheader v-if=\"!$fetchState.pending\">\n …\n \u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n data() {\n return {\n data: {},\n }\n },\n async fetch() {\n try {\n const data = await this.$graphql.default.request(headerQuery)\n this.data = data\n } catch (error) {\n console.error(JSON.stringify(error, undefined, 2))\n }\n },\n}\n\u003C/script>\n```\n\n### Options\n\nTo pass options to the request, for example for a multilingual version with [nuxt/i18n](https://i18n.nuxtjs.org/) and/or a url parameter in a dynamic page:\n\n```javascript\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n async asyncData({ $graphql, app, params }) {\n const locale = app.i18n.localeProperties.iso\n const data = await $graphql.default.request(articleQuery, {\n code: locale,\n slug: params.slug,\n })\n return { data }\n },\n}\n\u003C/script>\n```","src/content/fragments/en/nuxt-graphql-static.md","181e8091294eb858",{"html":818,"metadata":819},"\u003Ch2 id=\"the-problem\">The problem\u003C/h2>\n\u003Cp>I encountered a nasty bug while using static generation with Nuxt and \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (new tab)\">nuxt apollo\u003C/a> client.\nI found \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Github issue on nuxt/apollo repository (new tab)\">the issue\u003C/a> already reported on github.\u003C/p>\n\u003Cp>It seems the module doesn’t handle static generation correctly with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I could find request to my local API url after the static generation. Moreover, it also seemed like \u003Ccode><nuxt-link>\u003C/code> navigation was broken.\u003C/p>\n\u003Ch2 id=\"the-solution\">The solution 🙌\u003C/h2>\n\u003Cp>Fortunately, there is another Nuxt module that handles GraphQL requests!\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\">Nuxt graphql request to the rescue!\u003C/a>\u003C/p>\n\u003Ch3 id=\"the-conf\">The conf\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// nuxt.config.js\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">buildModules\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\"> 'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">graphql\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> clients\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> default\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> endpoint: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> options: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> headers: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> authorization: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">},\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"the-request\">The request\u003C/h3>\n\u003Cp>The best approach so far is to use \u003Ccode>asyncData\u003C/code> in pages and \u003Ccode>fetch\u003C/code> in components. Using \u003Ccode>fetch\u003C/code> in pages does not work well at all with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I also install the \u003Ccode>graphql-tag\u003C/code> package (only in \u003Ccode>devDependencies\u003C/code>) to be able to import directly \u003Ccode>.gql\u003C/code> files.\u003C/p>\n\u003Cp>Query example:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"graphql\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># homepage.gql\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">query\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\thomepage\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\ttitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\tsubtitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\thero\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\tid\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\talt\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"inside-a-page\">Inside a page\u003C/h4>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import homepageQuery from '~/graphql/queries/singles/homepage'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(homepageQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"inside-a-component\">Inside a component\u003C/h4>\n\u003Cp>It is safer to wait until \u003Ccode>fetch\u003C/code> has received a response before displaying anything. You can use \u003Ccode>$fetchState\u003C/code> to be sure (\u003Ca href=\"https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation on the fetch hook (new tab)\">documentation\u003C/a>).\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// Header.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> <\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#B392F0\"> v-if\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"!$fetchState.pending\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> …\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> </\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import headerQuery from '~/graphql/queries/singles/header'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">fetch\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> try {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> data\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.$graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(headerQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> data\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> } catch (error) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> console.\u003C/span>\u003Cspan style=\"color:#B392F0\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(JSON.stringify(\u003C/span>\u003Cspan style=\"color:#FFAB70\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">undefined\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, 2))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"options\">Options\u003C/h3>\n\u003Cp>To pass options to the request, for example for a multilingual version with \u003Ca href=\"https://i18n.nuxtjs.org/\">nuxt/i18n\u003C/a> and/or a url parameter in a dynamic page:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// _slug.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import articleQuery from '~/graphql/queries/articles'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql, app, params }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const locale \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> app.i18n.localeProperties.iso\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(articleQuery, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> code: locale,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> slug: params.slug,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> })\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":820,"imagePaths":843,"frontmatter":844},[821,824,827,830,833,837,840],{"depth":150,"slug":822,"text":823},"the-problem","The problem",{"depth":150,"slug":825,"text":826},"the-solution","The solution 🙌",{"depth":154,"slug":828,"text":829},"the-conf","The conf",{"depth":154,"slug":831,"text":832},"the-request","The request",{"depth":834,"slug":835,"text":836},4,"inside-a-page","Inside a page",{"depth":834,"slug":838,"text":839},"inside-a-component","Inside a component",{"depth":154,"slug":841,"text":842},"options","Options",[],{"title":809,"subtitle":810,"lang":68,"slug":806,"createdAt":170,"updatedAt":845,"excerpt":846,"tags":847,"type":435},"2022-09-08T13:43:33.000Z","When the most used gql module doesn't work…",[562],"nuxt-graphql-static",{"id":848,"data":850,"body":856,"filePath":857,"digest":858,"rendered":859},{"title":851,"subtitle":852,"lang":16,"tags":853,"type":427,"slug":848,"createdAt":854,"updatedAt":855},"Site statique et requêtes GraphQL avec Nuxt.js","Le client graphql est roi.",[562],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## Le problème\n\nJe me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (nouvel onglet)').\nAprès quelques recherches, voici [le bug constaté par quelqu'un d'autre](https://github.com/nuxt-community/apollo-module/issues/339 'Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)') sur github.\n\nIl semblerait que le module en l'état ne gère pas correctement la génération statique avec `nuxt generate`.\n\nJe trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les `\u003Cnuxt-link>` ne fonctionnait pas.\n\n## La solution 🙌\n\nHeureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\n\n[Nuxt graphql request à la rescousse !](https://github.com/gomah/nuxt-graphql-request 'Dépôt github du module (nouvel onglet)')\n\n### La conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### La requête\n\nLa meilleure méthode à ce jour est d'utiliser `asyncData` dans les pages et `fetch` dans les composants. Utiliser `fetch` dans les pages ne fonctionne pas bien du tout avec `nuxt generate`.\n\nJ'installe également le paquet `graphql-tag` (uniquement en `devDependencies`) afin de pouvoir importer directement des fichiers `.gql`\n\nExemple de fichier :\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Dans une page\n\n```javascript\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n async asyncData({ $graphql }) {\n const data = await $graphql.default.request(homepageQuery)\n return { data }\n },\n}\n\u003C/script>\n```\n\n#### Dans un composant\n\nIl est plus prudent d'attendre que `fetch` ait reçu une réponse avant d'afficher quoi que ce soit. On peut utiliser `$fetchState` afin d'être tranquille ([documentation](https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation sur la méthode fetch (nouvel onglet)')).\n\n```javascript\n// Header.vue\n\u003Ctemplate>\n \u003Cheader v-if=\"!$fetchState.pending\">\n …\n \u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n data() {\n return {\n data: {},\n }\n },\n async fetch() {\n try {\n const data = await this.$graphql.default.request(headerQuery)\n this.data = data\n } catch (error) {\n console.error(JSON.stringify(error, undefined, 2))\n }\n },\n}\n\u003C/script>\n```\n\n### Les options\n\nPour passer des options à la requête, par exemple pour une version multilingue avec [nuxt/i18n](https://i18n.nuxtjs.org/ 'Documentation de nuxt i18n (nouvel onglet)') et/ou un paramètre d'url dans le cadre d'une page dynamique :\n\n```javascript\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n async asyncData({ $graphql, app, params }) {\n const locale = app.i18n.localeProperties.iso\n const data = await $graphql.default.request(articleQuery, {\n code: locale,\n slug: params.slug,\n })\n return { data }\n },\n}\n\u003C/script>\n```","src/content/fragments/fr/nuxt-graphql-static.md","73b6cc6b4fed04f5",{"html":860,"metadata":861},"\u003Ch2 id=\"le-problème\">Le problème\u003C/h2>\n\u003Cp>Je me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (nouvel onglet)\">nuxt apollo\u003C/a>.\nAprès quelques recherches, voici \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)\">le bug constaté par quelqu’un d’autre\u003C/a> sur github.\u003C/p>\n\u003Cp>Il semblerait que le module en l’état ne gère pas correctement la génération statique avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>Je trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les \u003Ccode><nuxt-link>\u003C/code> ne fonctionnait pas.\u003C/p>\n\u003Ch2 id=\"la-solution\">La solution 🙌\u003C/h2>\n\u003Cp>Heureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\" title=\"Dépôt github du module (nouvel onglet)\">Nuxt graphql request à la rescousse !\u003C/a>\u003C/p>\n\u003Ch3 id=\"la-conf\">La conf\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// nuxt.config.js\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">buildModules\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\"> 'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">graphql\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> clients\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> default\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> endpoint: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> options: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> headers: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> authorization: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">},\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"la-requête\">La requête\u003C/h3>\n\u003Cp>La meilleure méthode à ce jour est d’utiliser \u003Ccode>asyncData\u003C/code> dans les pages et \u003Ccode>fetch\u003C/code> dans les composants. Utiliser \u003Ccode>fetch\u003C/code> dans les pages ne fonctionne pas bien du tout avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>J’installe également le paquet \u003Ccode>graphql-tag\u003C/code> (uniquement en \u003Ccode>devDependencies\u003C/code>) afin de pouvoir importer directement des fichiers \u003Ccode>.gql\u003C/code>\u003C/p>\n\u003Cp>Exemple de fichier :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"graphql\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># homepage.gql\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">query\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\thomepage\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\ttitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\tsubtitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\thero\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\tid\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\talt\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"dans-une-page\">Dans une page\u003C/h4>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import homepageQuery from '~/graphql/queries/singles/homepage'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(homepageQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"dans-un-composant\">Dans un composant\u003C/h4>\n\u003Cp>Il est plus prudent d’attendre que \u003Ccode>fetch\u003C/code> ait reçu une réponse avant d’afficher quoi que ce soit. On peut utiliser \u003Ccode>$fetchState\u003C/code> afin d’être tranquille (\u003Ca href=\"https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation sur la méthode fetch (nouvel onglet)\">documentation\u003C/a>).\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// Header.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> <\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#B392F0\"> v-if\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"!$fetchState.pending\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> …\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> </\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import headerQuery from '~/graphql/queries/singles/header'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">fetch\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> try {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> data\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.$graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(headerQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> data\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> } catch (error) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> console.\u003C/span>\u003Cspan style=\"color:#B392F0\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(JSON.stringify(\u003C/span>\u003Cspan style=\"color:#FFAB70\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">undefined\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, 2))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"les-options\">Les options\u003C/h3>\n\u003Cp>Pour passer des options à la requête, par exemple pour une version multilingue avec \u003Ca href=\"https://i18n.nuxtjs.org/\" title=\"Documentation de nuxt i18n (nouvel onglet)\">nuxt/i18n\u003C/a> et/ou un paramètre d’url dans le cadre d’une page dynamique :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// _slug.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import articleQuery from '~/graphql/queries/articles'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql, app, params }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const locale \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> app.i18n.localeProperties.iso\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(articleQuery, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> code: locale,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> slug: params.slug,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> })\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":862,"imagePaths":884,"frontmatter":885},[863,866,869,872,875,878,881],{"depth":150,"slug":864,"text":865},"le-problème","Le problème",{"depth":150,"slug":867,"text":868},"la-solution","La solution 🙌",{"depth":154,"slug":870,"text":871},"la-conf","La conf",{"depth":154,"slug":873,"text":874},"la-requête","La requête",{"depth":834,"slug":876,"text":877},"dans-une-page","Dans une page",{"depth":834,"slug":879,"text":880},"dans-un-composant","Dans un composant",{"depth":154,"slug":882,"text":883},"les-options","Les options",[],{"title":851,"subtitle":852,"lang":16,"slug":848,"createdAt":170,"updatedAt":845,"excerpt":886,"tags":887,"type":427},"Quand le module gql le plus utilisé ne fonctionne pas…",[562],"HPsections",["Map",890,891,911,912,928,929,945,946,970,971],"011-offre",{"id":890,"data":892,"body":899,"filePath":900,"digest":901,"rendered":902},{"type":893,"lang":16,"uid":894,"image":895,"order":896,"quickTitle":897,"quickImage":898,"reference":39},"section","offre","/assets/images/home/offre-1.1.svg",1.1,"Mes offres en freelance","/assets/images/home/icon-desktop.svg","## L'offre site web classique\n\nCette offre est destinée à un public souhaitant **se doter d'un site web**, sans forcément intégrer l'accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du [référentiel général d'amélioration de l'accessibilité](https://accessibilite.numerique.gouv.fr/) (\u003Cabbr>RGAA\u003C/abbr>).\n\nL'objectif principal de cette offre étant d'**établir une présence en ligne** pour le client. Que cette dernière ait un but informatif et/ou éditorial.\n\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->","src/data/HP/011-offre.md","290ecd1ed94a1087",{"html":903,"metadata":904},"\u003Ch2 id=\"loffre-site-web-classique\">L’offre site web classique\u003C/h2>\n\u003Cp>Cette offre est destinée à un public souhaitant \u003Cstrong>se doter d’un site web\u003C/strong>, sans forcément intégrer l’accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du \u003Ca href=\"https://accessibilite.numerique.gouv.fr/\">référentiel général d’amélioration de l’accessibilité\u003C/a> (\u003Cabbr>RGAA\u003C/abbr>).\u003C/p>\n\u003Cp>L’objectif principal de cette offre étant d’\u003Cstrong>établir une présence en ligne\u003C/strong> pour le client. Que cette dernière ait un but informatif et/ou éditorial.\u003C/p>\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->",{"headings":905,"imagePaths":909,"frontmatter":910},[906],{"depth":150,"slug":907,"text":908},"loffre-site-web-classique","L’offre site web classique",[],{"type":893,"uid":894,"lang":16,"image":895,"order":896,"quickTitle":897,"quickImage":898,"reference":39},"012-offre",{"id":911,"data":913,"body":916,"filePath":917,"digest":918,"rendered":919},{"type":893,"lang":16,"image":914,"order":915,"reference":50},"/assets/images/home/offre-1.2.svg",1.2,"## L'offre accessibilité avancée\n\nCette offre s'adresse plus spécifiquement aux entités pour lesquelles **l'accessibilité du site est un critère majeur.** Qu'il s'agisse d'une création ou d'une mise en conformité après un audit d'accessibilité.\n\nLorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\n\n- [Rose Primaire](https://roseprimaire.com/) pour le conseil et l'accompagnement du projet ;\n- [Sylvain Plantier](https://jedessinebien.com/) et/ou [Benoît Etchevery](http://ben-etche.com/) pour l'illustration et la direction artistique.\n\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->","src/data/HP/012-offre.md","2a3bf3411b3c171b",{"html":920,"metadata":921},"\u003Ch2 id=\"loffre-accessibilité-avancée\">L’offre accessibilité avancée\u003C/h2>\n\u003Cp>Cette offre s’adresse plus spécifiquement aux entités pour lesquelles \u003Cstrong>l’accessibilité du site est un critère majeur.\u003C/strong> Qu’il s’agisse d’une création ou d’une mise en conformité après un audit d’accessibilité.\u003C/p>\n\u003Cp>Lorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://roseprimaire.com/\">Rose Primaire\u003C/a> pour le conseil et l’accompagnement du projet ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://jedessinebien.com/\">Sylvain Plantier\u003C/a> et/ou \u003Ca href=\"http://ben-etche.com/\">Benoît Etchevery\u003C/a> pour l’illustration et la direction artistique.\u003C/li>\n\u003C/ul>\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->",{"headings":922,"imagePaths":926,"frontmatter":927},[923],{"depth":150,"slug":924,"text":925},"loffre-accessibilité-avancée","L’offre accessibilité avancée",[],{"type":893,"lang":16,"order":915,"image":914,"reference":50},"013-offre",{"id":928,"data":930,"body":933,"filePath":934,"digest":935,"rendered":936},{"type":893,"lang":16,"image":931,"order":932},"/assets/images/home/offre-1.3.svg",1.3,"## Et l'éco-conception alors ?\n\nJe ne conçois pas l'éco-conception comme une offre. C'est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l'éco-conception sans accessibilité, j'applique donc ces méthodologies quelque soit le projet !","src/data/HP/013-offre.md","03e37f364ac27cb4",{"html":937,"metadata":938},"\u003Ch2 id=\"et-léco-conception-alors\">Et l’éco-conception alors ?\u003C/h2>\n\u003Cp>Je ne conçois pas l’éco-conception comme une offre. C’est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l’éco-conception sans accessibilité, j’applique donc ces méthodologies quelque soit le projet !\u003C/p>",{"headings":939,"imagePaths":943,"frontmatter":944},[940],{"depth":150,"slug":941,"text":942},"et-léco-conception-alors","Et l’éco-conception alors ?",[],{"type":893,"lang":16,"order":932,"image":931},"020-methodo",{"id":945,"data":947,"body":952,"filePath":953,"digest":954,"rendered":955},{"type":893,"lang":16,"uid":948,"image":949,"order":150,"quickTitle":950,"quickImage":951},"methodology","/assets/images/home/methodo.svg","Ma méthodologie","/assets/images/home/icon-methodo.svg","## Méthodologie\n\n### Accessibilité par défaut\n\nEngagé pour un web plus accessible, je crée des **sites web** en m'appuyant sur le [référentiel général d'amélioration de l'accessibilité (RGAA)](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) ainsi que sur les bonnes pratiques [Opquast.](https://www.opquast.com/rendre-le-web-meilleur/)\n\n### Sobriété par choix\n\nJe privilégie le développement de **sites statiques** en adoptant une approche [d'éco-conception numérique.](https://eco-conception.designersethiques.org/guide/fr/) \nC'est-à-dire que le site est pensé pour n'embarquer que les fonctionnalités nécessaires à son utilisation.\n\nCette approche présente de **nombreux avantages :**\n\n- chargement rapide des pages ;\n- sécurité renforcée ;\n- coûts serveur réduits ;\n- maintenance facilitée.\n\nLorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l'interface. Cela permet de garantir que **le site reste en ligne** même si le CMS venait à ne plus fonctionner.","src/data/HP/020-methodo.md","75a09b4e0b1e926b",{"html":956,"metadata":957},"\u003Ch2 id=\"méthodologie\">Méthodologie\u003C/h2>\n\u003Ch3 id=\"accessibilité-par-défaut\">Accessibilité par défaut\u003C/h3>\n\u003Cp>Engagé pour un web plus accessible, je crée des \u003Cstrong>sites web\u003C/strong> en m’appuyant sur le \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité (RGAA)\u003C/a> ainsi que sur les bonnes pratiques \u003Ca href=\"https://www.opquast.com/rendre-le-web-meilleur/\">Opquast.\u003C/a>\u003C/p>\n\u003Ch3 id=\"sobriété-par-choix\">Sobriété par choix\u003C/h3>\n\u003Cp>Je privilégie le développement de \u003Cstrong>sites statiques\u003C/strong> en adoptant une approche \u003Ca href=\"https://eco-conception.designersethiques.org/guide/fr/\">d’éco-conception numérique.\u003C/a>\u003Cbr>\nC’est-à-dire que le site est pensé pour n’embarquer que les fonctionnalités nécessaires à son utilisation.\u003C/p>\n\u003Cp>Cette approche présente de \u003Cstrong>nombreux avantages :\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>chargement rapide des pages ;\u003C/li>\n\u003Cli>sécurité renforcée ;\u003C/li>\n\u003Cli>coûts serveur réduits ;\u003C/li>\n\u003Cli>maintenance facilitée.\u003C/li>\n\u003C/ul>\n\u003Cp>Lorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l’interface. Cela permet de garantir que \u003Cstrong>le site reste en ligne\u003C/strong> même si le CMS venait à ne plus fonctionner.\u003C/p>",{"headings":958,"imagePaths":968,"frontmatter":969},[959,962,965],{"depth":150,"slug":960,"text":961},"méthodologie","Méthodologie",{"depth":154,"slug":963,"text":964},"accessibilité-par-défaut","Accessibilité par défaut",{"depth":154,"slug":966,"text":967},"sobriété-par-choix","Sobriété par choix",[],{"type":893,"uid":948,"lang":16,"image":949,"order":150,"quickTitle":950,"quickImage":951},"030-about",{"id":970,"data":972,"body":977,"filePath":978,"digest":979,"rendered":980},{"type":893,"lang":16,"uid":973,"image":974,"order":154,"quickTitle":975,"quickImage":976},"about","/assets/images/home/about.svg","Moi","/assets/images/home/icon-heart.svg","## À propos\n\n### Formations personnelles\n\nAfin de solidifier mes compétences, j'ai suivi les formations et passé les certifications suivantes :\n\n- [Opquast](https://directory.opquast.com/fr/certificat/CTQSKP/) - Maîtrise de la qualité en projet web ;\n- Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\n\n### Formations des autres\n\nDepuis plusieurs années, j'interviens dans différents campus afin de dispenser des cours de développement web.\n\n### Temps libre\n\nJ’essaie de contribuer à des [projets open source](https://git.nardu.in/explore/repos) qui me tiennent à cœur et je m'engage localement avec le collectif [good-it!](https://www.good-it.org/)\n\nAh et j’écris [des articles](/articles) aussi ! Des articles sur le design, le développement web et l’informatique.","src/data/HP/030-about.md","a7abff6d744406ce",{"html":981,"metadata":982},"\u003Ch2 id=\"à-propos\">À propos\u003C/h2>\n\u003Ch3 id=\"formations-personnelles\">Formations personnelles\u003C/h3>\n\u003Cp>Afin de solidifier mes compétences, j’ai suivi les formations et passé les certifications suivantes :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://directory.opquast.com/fr/certificat/CTQSKP/\">Opquast\u003C/a> - Maîtrise de la qualité en projet web ;\u003C/li>\n\u003Cli>Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"formations-des-autres\">Formations des autres\u003C/h3>\n\u003Cp>Depuis plusieurs années, j’interviens dans différents campus afin de dispenser des cours de développement web.\u003C/p>\n\u003Ch3 id=\"temps-libre\">Temps libre\u003C/h3>\n\u003Cp>J’essaie de contribuer à des \u003Ca href=\"https://git.nardu.in/explore/repos\">projets open source\u003C/a> qui me tiennent à cœur et je m’engage localement avec le collectif \u003Ca href=\"https://www.good-it.org/\">good-it!\u003C/a>\u003C/p>\n\u003Cp>Ah et j’écris \u003Ca href=\"/articles\">des articles\u003C/a> aussi ! Des articles sur le design, le développement web et l’informatique.\u003C/p>",{"headings":983,"imagePaths":996,"frontmatter":997},[984,987,990,993],{"depth":150,"slug":985,"text":986},"à-propos","À propos",{"depth":154,"slug":988,"text":989},"formations-personnelles","Formations personnelles",{"depth":154,"slug":991,"text":992},"formations-des-autres","Formations des autres",{"depth":154,"slug":994,"text":995},"temps-libre","Temps libre",[],{"type":893,"uid":973,"lang":16,"image":974,"order":154,"quickTitle":975,"quickImage":976},"veille",["Map",269,1000],{"id":269,"data":1001,"body":1003,"filePath":1004,"digest":1005,"rendered":1006},{"lang":16,"title":269,"updatedAt":1002},["Date","2023-04-20T17:12:06.000Z"],"- [mmm.page](https://build.mmm.page/) - Éditeur de sites web très simples, en glisser-déposer, pour n'importe quoi.\n- [Color.io](https://www.color.io/) - Éditeur photo en ligne.\n- [Addy's toolkit](https://toolkit.addy.codes/) - Outils et ressources pour les designers et développeurs sites web.\n- [L’accessibilité n’est pas une variable d’ajustement](https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/) — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n > L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\n- [3D en CSS (english)](https://garden.bradwoods.io/notes/css/3d) – Explications et exemples des propriétés 3D en CSS.\n- [Climat : Comment ne pas déprimer ?](https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html) – Podcast.\n- [Fable (english)](https://fable.app) – Application de motion design.\n- [Rive (english)](https://rive.app) – Application de motion design.\n- [Cake Desk](https://cakedesk.app/) – Application de facturation.\n- [Ombre fluide en CSS](https://shadows.brumm.af/) – Générateur.\n- [Smol CSS](https://smolcss.dev/) – Collection de fragments CSS.\n- [Ajustement optique](https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/) (english) – Aligner visuellement plutôt que techniquement.\n- [Datawrapper](https://blog.datawrapper.de/category/datavis-dos-and-donts/) (english) – Conseils pour montrer de la donnée.\n- [Assistivlabs](https://assistivlabs.com/) (english) – Service de test des technologies d'assistance (browserstack mais pour l'accessibilité).\n- [Les caractères fantaisistes et l'accessibilité](https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/) – Explications et exemples de l'enfer que sont les caractères Unicode pour les technologies d'assistance.\n- [Créer un champ `time` sur le web](https://adamsilver.io/blog/designing-a-time-input-backed-by-research/) (english) – Article.\n- [La cascade](https://la-cascade.io) – Collection d'articles sur le CSS.\n- [Tabby](https://tabby.sh) (english) – An alternative terminal app.\n- [Newglyph](https://newglyph.com/) – Fonderie indépendante.\n- [\u003Cspan lang=\"en\">Headless UI\u003C/span>](https://headlessui.com/vue/dialog) (english) – Librairie de composants vue et react.\n- [Vie privée sexy](https://privacy.sexy) (english) – Outils de confidentialité pour windows et macos.\n- [33 concepts JavaScript](https://github.com/leonardomso/33-js-concepts) (english) – Articles.\n- [Formbricks](https://formbricks.com/) (english) – Alternative open source à google form/typeform.\n- [Animations de chargement SVG](https://github.com/n3r4zzurr0/svg-spinners) – Collection.\n- [a11yphant](https://a11yphant.com/) (english) – Challenges de code pour apprendre l'accessibilité.\n- [CSS moderne](https://moderncss.dev/) (english) – Fragments CSS.\n- [Conteneur moderne en CSS](https://twitter.com/KevinJPowell/status/1501555193799925761) (english) – Tweet de Kevin Powell ❤️","src/data/veille/2023.md","1135beec386f207f",{"html":1007,"metadata":1008},"\u003Cul>\n\u003Cli>\u003Ca href=\"https://build.mmm.page/\">mmm.page\u003C/a> - Éditeur de sites web très simples, en glisser-déposer, pour n’importe quoi.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.color.io/\">Color.io\u003C/a> - Éditeur photo en ligne.\u003C/li>\n\u003Cli>\u003Ca href=\"https://toolkit.addy.codes/\">Addy’s toolkit\u003C/a> - Outils et ressources pour les designers et développeurs sites web.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/\">L’accessibilité n’est pas une variable d’ajustement\u003C/a> — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n\u003Cblockquote>\n\u003Cp>L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\u003C/p>\n\u003C/blockquote>\n\u003C/li>\n\u003Cli>\u003Ca href=\"https://garden.bradwoods.io/notes/css/3d\">3D en CSS (english)\u003C/a> – Explications et exemples des propriétés 3D en CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html\">Climat : Comment ne pas déprimer ?\u003C/a> – Podcast.\u003C/li>\n\u003Cli>\u003Ca href=\"https://fable.app\">Fable (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://rive.app\">Rive (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://cakedesk.app/\">Cake Desk\u003C/a> – Application de facturation.\u003C/li>\n\u003Cli>\u003Ca href=\"https://shadows.brumm.af/\">Ombre fluide en CSS\u003C/a> – Générateur.\u003C/li>\n\u003Cli>\u003Ca href=\"https://smolcss.dev/\">Smol CSS\u003C/a> – Collection de fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/\">Ajustement optique\u003C/a> (english) – Aligner visuellement plutôt que techniquement.\u003C/li>\n\u003Cli>\u003Ca href=\"https://blog.datawrapper.de/category/datavis-dos-and-donts/\">Datawrapper\u003C/a> (english) – Conseils pour montrer de la donnée.\u003C/li>\n\u003Cli>\u003Ca href=\"https://assistivlabs.com/\">Assistivlabs\u003C/a> (english) – Service de test des technologies d’assistance (browserstack mais pour l’accessibilité).\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/\">Les caractères fantaisistes et l’accessibilité\u003C/a> – Explications et exemples de l’enfer que sont les caractères Unicode pour les technologies d’assistance.\u003C/li>\n\u003Cli>\u003Ca href=\"https://adamsilver.io/blog/designing-a-time-input-backed-by-research/\">Créer un champ \u003Ccode>time\u003C/code> sur le web\u003C/a> (english) – Article.\u003C/li>\n\u003Cli>\u003Ca href=\"https://la-cascade.io\">La cascade\u003C/a> – Collection d’articles sur le CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://tabby.sh\">Tabby\u003C/a> (english) – An alternative terminal app.\u003C/li>\n\u003Cli>\u003Ca href=\"https://newglyph.com/\">Newglyph\u003C/a> – Fonderie indépendante.\u003C/li>\n\u003Cli>\u003Ca href=\"https://headlessui.com/vue/dialog\">\u003Cspan lang=\"en\">Headless UI\u003C/span>\u003C/a> (english) – Librairie de composants vue et react.\u003C/li>\n\u003Cli>\u003Ca href=\"https://privacy.sexy\">Vie privée sexy\u003C/a> (english) – Outils de confidentialité pour windows et macos.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/leonardomso/33-js-concepts\">33 concepts JavaScript\u003C/a> (english) – Articles.\u003C/li>\n\u003Cli>\u003Ca href=\"https://formbricks.com/\">Formbricks\u003C/a> (english) – Alternative open source à google form/typeform.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/n3r4zzurr0/svg-spinners\">Animations de chargement SVG\u003C/a> – Collection.\u003C/li>\n\u003Cli>\u003Ca href=\"https://a11yphant.com/\">a11yphant\u003C/a> (english) – Challenges de code pour apprendre l’accessibilité.\u003C/li>\n\u003Cli>\u003Ca href=\"https://moderncss.dev/\">CSS moderne\u003C/a> (english) – Fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/KevinJPowell/status/1501555193799925761\">Conteneur moderne en CSS\u003C/a> (english) – Tweet de Kevin Powell ❤️\u003C/li>\n\u003C/ul>",{"headings":1009,"imagePaths":1010,"frontmatter":1011},[],[],{"lang":16,"title":269,"updatedAt":1012},"2023-04-20T17:12:06.000Z"] \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6691182..fb1fded 100755 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # build output dist/ +.astro/ # dependencies node_modules/ @@ -18,5 +19,5 @@ pnpm-debug.log* # macOS-specific files .DS_Store -# i18n +# astro astro_tmp_pages_* \ No newline at end of file diff --git a/src/pages/plan-du-site.astro b/src/pages/plan-du-site.astro index e6f1e81..51438da 100755 --- a/src/pages/plan-du-site.astro +++ b/src/pages/plan-du-site.astro @@ -5,12 +5,18 @@ import BaseLayout from '../layouts/BaseLayout.astro' import { getCollection } from 'astro:content' // get all articles -const allArticles = await getCollection('articles', ({ data }) => { - return !data.draft +const frArticles = await getCollection('articles', ({ data }) => { + return !data.draft && data.lang === 'fr' +}) +const enArticles = await getCollection('articles', ({ data }) => { + return !data.draft && data.lang === 'en' }) // get all snippets -const allFragments = await getCollection('fragments', ({ data }) => { - return !data.draft +const frFragments = await getCollection('fragments', ({ data }) => { + return !data.draft && data.lang === 'fr' +}) +const enFragments = await getCollection('fragments', ({ data }) => { + return !data.draft && data.lang === 'en' }) const pageTitle = 'Plan du site' @@ -29,36 +35,63 @@ const pageTitle = 'Plan du site' <h2> <a href='/articles'>Articles</a> </h2> + <h3>Articles en français</h3> <ul> { - allArticles.map((article) => ( + frArticles.map((article) => ( <li> <a href={`/articles/${article.data.slug}`}> - {article.data.title} <sup>({article.data.lang})</sup> + {article.data.title} </a> </li> )) } </ul> + <div lang='en'> + <h3>Articles in english</h3> + <ul> + { + enArticles.map((article) => ( + <li> + <a href={`/articles/${article.data.slug}`}> + {article.data.title} + </a> + </li> + )) + } + </ul> + </div> </li> <li> <h2> <a href='/fragments'>Fragments</a> </h2> + <h3>Fragments en français</h3> <ul> { - allFragments.map((fragment) => ( + frFragments.map((fragment) => ( <li> - <a - href={`/fragments/${fragment.id}`} - lang={fragment.data.lang !== 'fr' ? fragment.data.lang : null} - > - {fragment.data.title} <sup>({fragment.data.lang})</sup> + <a href={`/fragments/${fragment.data.slug}`}> + {fragment.data.title} </a> </li> )) } </ul> + <div lang='en'> + <h3>Snippets in english</h3> + <ul> + { + enFragments.map((fragment) => ( + <li> + <a href={`/fragments/${fragment.data.slug}`}> + {fragment.data.title} + </a> + </li> + )) + } + </ul> + </div> </li> <li> <h2> -- 2.45.2 From 703d1d7f08c7268b25242cb4299b09f9b8242b2b Mon Sep 17 00:00:00 2001 From: nico <contact@nardu.in> Date: Sun, 29 Dec 2024 23:54:33 +0100 Subject: [PATCH 05/16] cleanup and refactor i18n + code --- .astro/content-modules.mjs | 10 +- .astro/data-store.json | 2 +- astro.config.mjs | 43 ++++--- bun.lockb | Bin 221901 -> 222308 bytes package.json | 1 + src/components/EditorialContent.astro | 2 - src/components/MetaDate.astro | 14 +- src/content/fragments/fr/visited-links.md | 2 +- src/i18n/en.json | 68 ---------- src/i18n/fr.json | 68 ---------- src/i18n/ui.ts | 150 ---------------------- src/pages/articles/[id].astro | 39 ++---- src/pages/articles/i18n/en.json | 4 - src/pages/articles/i18n/fr.json | 4 - src/pages/articles/index.astro | 59 +++++---- src/pages/fragments/[id].astro | 39 ++---- src/pages/fragments/i18n/en.json | 4 - src/pages/fragments/i18n/fr.json | 4 - src/pages/fragments/index.astro | 59 +++++---- src/pages/i18n/en.json | 15 --- src/pages/i18n/fr.json | 15 --- src/pages/references/i18n/en.json | 4 - src/pages/references/i18n/fr.json | 4 - src/pages/references/index.astro | 40 ++---- src/pages/veille/i18n/en.json | 4 - src/pages/veille/i18n/fr.json | 4 - src/pages/veille/index.astro | 41 +++--- src/styles/global/global-styles.css | 60 ++++++--- 28 files changed, 206 insertions(+), 553 deletions(-) delete mode 100755 src/i18n/en.json delete mode 100755 src/i18n/fr.json delete mode 100644 src/i18n/ui.ts delete mode 100755 src/pages/articles/i18n/en.json delete mode 100755 src/pages/articles/i18n/fr.json delete mode 100755 src/pages/fragments/i18n/en.json delete mode 100755 src/pages/fragments/i18n/fr.json delete mode 100755 src/pages/i18n/en.json delete mode 100755 src/pages/i18n/fr.json delete mode 100755 src/pages/references/i18n/en.json delete mode 100755 src/pages/references/i18n/fr.json delete mode 100755 src/pages/veille/i18n/en.json delete mode 100755 src/pages/veille/i18n/fr.json diff --git a/.astro/content-modules.mjs b/.astro/content-modules.mjs index c4a699e..4169cc6 100644 --- a/.astro/content-modules.mjs +++ b/.astro/content-modules.mjs @@ -4,11 +4,11 @@ export default new Map([ ["src/content/articles/en/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], ["src/content/articles/en/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], ["src/content/articles/en/video-compression.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fvideo-compression.mdx&astroContentModuleFlag=true")], -["src/content/fragments/en/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fimage-full.mdx&astroContentModuleFlag=true")], -["src/content/fragments/en/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], -["src/content/articles/fr/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], ["src/content/fragments/fr/buttons.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fbuttons.mdx&astroContentModuleFlag=true")], ["src/content/fragments/fr/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fimage-full.mdx&astroContentModuleFlag=true")], -["src/content/articles/fr/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], -["src/content/fragments/fr/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fsuper-cookies.mdx&astroContentModuleFlag=true")]]); +["src/content/fragments/fr/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], +["src/content/articles/fr/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], +["src/content/fragments/en/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fimage-full.mdx&astroContentModuleFlag=true")], +["src/content/fragments/en/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], +["src/content/articles/fr/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")]]); \ No newline at end of file diff --git a/.astro/data-store.json b/.astro/data-store.json index e65e8a3..4c7de64 100644 --- a/.astro/data-store.json +++ b/.astro/data-store.json @@ -1 +1 @@ -[["Map",1,2,9,10,61,62,427,428,888,889,998,999],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.1.1","content-config-digest","8021b3469f132349","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"site\":\"https://www.nardu.in\",\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[\"assets.nardu.in\"],\"remotePatterns\":[{\"protocol\":\"https\"}]},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":\"shiki\",\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"i18n\":{\"defaultLocale\":\"fr\",\"locales\":[\"fr\",\"en\"],\"routing\":{\"prefixDefaultLocale\":false,\"redirectToDefaultLocale\":true,\"fallbackType\":\"redirect\"}},\"security\":{\"checkOrigin\":true},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"responsiveImages\":false},\"legacy\":{\"collections\":false}}","references",["Map",11,12,25,26,39,40,50,51],"3w",{"id":11,"data":13,"filePath":21,"digest":22,"rendered":23},{"title":11,"subtitle":14,"url":15,"lang":16,"slug":11,"tags":17,"createdAt":20},"J'ai fait de la doc!","https://3-w.fr","fr",[18,19],"Front-end","documentation",["Date","2022-10-19T18:02:00.000Z"],"src/content/references/3w.md","0d3d94c8af754e1b",{"html":24},"","natureo",{"id":25,"data":27,"filePath":36,"digest":37,"rendered":38},{"title":28,"subtitle":29,"url":30,"lang":16,"slug":25,"tags":31,"createdAt":35},"Nature en Occitanie","La sobriété au naturel.","https://www.natureo.org/",[18,32,33,34],"accessibilité","éco-conception","CMS",["Date","2023-04-19T18:02:00.000Z"],"src/content/references/natureo.md","6a7169b855b57024",{"html":24},"parole-expression",{"id":39,"data":41,"filePath":47,"digest":48,"rendered":49},{"title":42,"subtitle":43,"url":44,"lang":16,"slug":39,"tags":45,"createdAt":46},"Parole Expression","Un nouveau site pour l'association.","https://www.paroleexpression.fr/",[18,33,34],["Date","2022-04-19T17:11:00.000Z"],"src/content/references/parole-expression.md","ec95a408f8c3e99c",{"html":24},"rose-primaire",{"id":50,"data":52,"filePath":58,"digest":59,"rendered":60},{"title":53,"subtitle":54,"url":55,"lang":16,"slug":50,"tags":56,"createdAt":57},"Rose Primaire","Une agence comme on l'aime.","https://roseprimaire.com/",[18,32,33,34],["Date","2023-04-19T17:11:00.000Z"],"src/content/references/rose-primaire.md","a0133200cf1bee58",{"html":24},"articles",["Map",63,64,76,77,89,90,102,103,113,114,124,125,134,135,171,172,205,206,224,225,239,240,269,270,298,299,315,316,366,367,410,411],"en-after-effects-expressions",{"id":63,"data":65,"body":73,"filePath":74,"digest":75,"deferredRender":72},{"title":66,"subtitle":67,"lang":68,"tags":69,"type":61,"slug":63,"createdAt":71,"code":72},"After Effects Expressions","Animation on steroïds.","en",[70],"Design",["Date","2019-04-24T09:00:00.000Z"],true,"import AstroImage from '../../../components/AstroImage.astro'\n\n## An ever lasting battle\n\nThere is very little documentation and the existing one is hard to find or very old. Very often I just don't have the time to dive into expression learning while animating even though it could help the entire project on the long term.\nSo the last time I had to do a complex animation, **I took the damn time!**\n\n## The begining of the end (of keyframes).\n\nEveryone uses expressions whether they know it or not. Most of the time it's a rather transparent process for the animator. For example: when parenting a property to another one, After Effects creates an expression for us.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/basic_expression_d81b12f1ac.jpeg'\n\twidth='728'\n\theight='80'\n\talt='Parenting the position of the form to a null creates an expression.'\n/>\n\nOver the last updates, Adobe has made an effort to make expressions more accessible to everyone. For example, the expression box is now resembling a code editor thanks to code-coloring and auto-completion features. After Effects expression feel like JavaScript with custom functions.\n\nThose custom functions can be called through a menu once you enabled the expressions on a property. It offers organized shortcut and proper syntax to all of AE native functions and a bunch of JavaScript standard ones.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/shortcut_39cc19d383.jpeg'\n\twidth='728'\n\theight='322'\n\talt='Alt + Click the stopwatch to access the shortcuts.'\n/>\n\n## So I need to learn javascript to do motion design now?\n\n### Why bother?\n\nI know that most animators don't have any kind of development background. However, if Adobe thought it best to let us use expressions, I think we ought to, at least, try.\n\n> A lot of incredible professionals like [Mt Mograph](https://www.mtmograph.com/) and [Video Copilot](https://videocopilot.net/) use expressions.\n\nLike every optimization process, building an expressions knowledge takes time. However, like all optimization process, you will benefit from it afterwards.\n\n### Where to learn\n\nI've gathered a list of my favourite learning grounds. Plenty more exist, **go get'em!**\n\n- [Adobe official expression starter guide (FR)](https://helpx.adobe.com/fr/after-effects/using/expression-language-reference.html)\n- [Adobe official expression basic (EN)](https://helpx.adobe.com/after-effects/using/expression-basics.html)\n- [Adobe forums for expressions](https://community.adobe.com/t5/after-effects/bd-p/after-effects?page=1&sort=latest_replies&filter=all&topics=label-expressions)\n- [Creative Cow expressions forums](https://creativecow.net/forums/forum/adobe-after-effects-expressions/)\n- [Youtube channel about expressions](https://www.youtube.com/playlist?list=PLvr5U5ZSt6IzHyvSL9fo0M9NRPsTvra31)\n- [All expressions explained](http://aescript.jecool.net/reference/)\n- [All expressions explained again](http://expressions.aenhancers.com/index.html)\n- [Nice examples of basic expressions](https://www.schoolofmotion.com/tutorials/amazing-expressions-in-after-effects)\n\n## Real world example\n\n### Number counter\n\nLet's say you need to animate a rather simple counter from 0% to 100%.\n\n- Start by creating a text layer. Define your typographic choices, colours, etc.\n- On the effect menu add expression options > slider control\n- Alt + Click the Source text property\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/alt-counter.mp4' type='video/mp4' />\n\u003C/video>\n\n- Parent the source text to the slider control through the pickwhip.\n\n\u003Cvideo width='462' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/pickwhip.mp4' type='video/mp4' />\n\u003C/video>\n\nYou should get something like this in the expressions panel:\n\n```javascript\neffect(\"Slider Control\")(\"Slider\")​\n```\n\n- Set two keyframes on the slider from 0 to 100. The text should update accordingly.\n- By default, After Effects does not round numbers. In the expression panel, wrap your expression with the `Math.round()` function.\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/round.mp4' type='video/mp4' />\n\u003C/video>\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\"))​\n```\n\nGreat! We have a working counter. But we wanted a percentage counter. We could add a % glyph in another text layer but let's not.\n\nStill in the expression panel, we're going to add a string containing the % glyph, using basic JavaScript concatenation: `+ '%'`\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\")) + '%'​\n```\n\n\u003Cvideo width='538' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/percent.mp4' type='video/mp4' />\n\u003C/video>\n\n**And there we go!** A fully functioning and customizable counter using a slider controller and expressions.","src/content/articles/en/after-effects-expressions.mdx","3b6f88fbf35af1a4","en-sci-hub-unblock",{"id":76,"data":78,"body":86,"filePath":87,"digest":88,"deferredRender":72},{"title":79,"subtitle":80,"lang":68,"tags":81,"type":61,"slug":76,"createdAt":84,"updatedAt":85},"Access blocked Sci-hub","The science of sharing.",[82,83],"Internet","Science",["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nThe current sci-hub address is: \u003Ca href=\"https://sci-hub.se\" rel=\"noreferer noopener\">sci-hub.se\u003C/a>\n\n## What is this about?\n\nNot being a researcher myself, here’s an [extremely well done explanatory video](https://youtu.be/rcgxY__YXEc) on the subject of scientific publication (french audio with auto subtitle).\n\n> “This is outrageous!”​\n\nI noticed that my ISP was indeed blocking access. I have not yet been able to check for the other suppliers, but I imagine that they have all complied with the court decision.\nThe restriction in place is quite basic. This is a “DNS” block. A DNS is a server that is used to link a domain name: **www.sci-hub.tw** to an IP address: **186.2.163.90**\nIt is, in a way, the Internet phone book. Without the address, it is impossible to contact the domain. What ISPs have certainly done: block requests to the [sci-hub.se.](http://sci-hub.se/) domain name. As a result, no IP address is returned and the site is not accessible.\n\n## How to bypass this?\n\n- Either by using a VPN\n- Either by modifying the DNS servers of your computers/Internet box\n\nI would recommend the second solution because it allows you to protect yourself against future blockages/filtering/censorship from your ISP and does not require any financial compensation.\nI will focus on change from a computer because it will be effective wherever you are and not only from your home.\n\n### MacOs\n\nGo to:\n\n1. System Preferences\n1. Network\n1. (wi-fi and/or ethernet)\n1. Advanced\n1. DNS\n\nFrom there, you can add DNS servers by clicking the + icon. Click ok and apply the new settings. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS network and DNS settings'\n/>\n\n### Windows (10)\n\nGo to:\n\n1. System Settings\n1. Network & Internet\n1. Change adapter options\n1. Right click your adapter then “properties”\n1. Select “internet protocol version 4” (and/or 6)\n1. Properties\n1. Use the following DNS server addresses\n\nFrom there, you can add DNS servers. Click save. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Windows system settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows network settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows network connections settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows network adapter settings'\n/>\n\n## Which DNS?\n\nThere are many DNS servers available. The best known are Google, Cloudflare and OpenDNS. If you really want to use Google’s, I’ll let you look up their address. Here are my recommendations in order of preference.\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMy favorite since it is a [french association](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net)\n\nQuand9 is a non-profit foundation offering free public DNS servers. Their classic servers offer filtering of identified malicious domains. They do not collect data and are \u003Cabbr title=\"General Data Protection Regulation\">GDPR\u003C/abbr>-compliant.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## That's it.\n\nBy changing these settings, you are free from your ISPs and their content filtering rules.\n\nFor the moment, these restrictions are almost symbolic because if Sci-hub were to change its url, the block would no longer work. But the publishers’ victory in court shows that they have not had their last word. We are therefore not immune to a wider and stronger block in the future.\n\nIf you want to learn more about the struggle of the people who fight to ensure that research is not a paid commodity, I recommend [this documentary](https://youtu.be/y_CQATGOX2w) on Aaron Shwartz. Or [this article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) about the founder of Sci-hub.\n\nIn the meantime, good readings to all of you. We stand with you!","src/content/articles/en/sci-hub-blocage.mdx","8959506d941cdcc5","en-the-day-I-jamd",{"id":89,"data":91,"body":99,"filePath":100,"digest":101,"deferredRender":72},{"title":92,"subtitle":93,"lang":68,"tags":94,"type":61,"slug":89,"createdAt":97,"updatedAt":98},"The day I Jam’d","A story of unusual tools and fun gambles.",[95,96],"Dev","Jamstack",["Date","2020-10-08T09:00:00.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## The not so easy choice\n\nWhen I was still using Wordpress for my personal website, I thought it would be nice to try [OpenLiteSpeed](https://openlitespeed.org) webserver. Being a designer, I always like to have a graphical interface and I heard OLS had very nice caching and overall performances.\n\n## FIGHT!\n\nA few years later, I learned about Jamstack and its incredible potential. Not being impulsive at all, I chose to entirely remake my website with tools like [11ty](https://www.11ty.dev/) and [Strapi](https://strapi.io/).\n\nI remember Strapi still being in alpha/beta and colleagues telling me it was a risky gamble, especially since I was pretty new to the node.js world.\n\n> Open source and french? Sign me up!\n\nSo I started recreating my website identically with 11ty and Strapi. Same hosting on a Digital Ocean droplet, same webserver, same content. I had done a fair amout of performance optimizations on my wordpress install so I was eager to compare the results with the new static version.\n\nBoy did they exceed my expectations! With almost no optimization on the static side, I got the following results.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 53/100 on Wordpress.'\n/>\n\nDespite a lot of efforts I could not do better. I’m no expert in caching, do not use CDN and relied on plugins to achieve a lot of stuff (php not being my strongest skill 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 97/100 on jamstack.'\n/>\n\nAlmost **zero** special configuration (I was too anxious to test) and I reached an awesome score. I know lighthouse scores are not everything but hey, **53 vs 97**… I’ll take it!\n\n## Now kiss 🥰\n\nBoth of these approaches have their benefits and drawbacks. As a freelance, my clients often prefer or ask for Wordpress because of its reputation. I always present a Jamstack alternative when possible but it’s still scary to most compared to Wordpress. I feel however that it’s going to be easier to use Jamstack with time.\n\n## I did it again…\n\nHere we are now, a quarantine and a few months later and this website is running with… [Nuxt.js](https://nuxtjs.org/). I know, I’m sorry, I couldn’t resist the latest [nuxt content](https://content.nuxtjs.org/) functionnality.\n\nSo I re-did everything again… and let me just say: **wow**, what an experience!\nI **love** developing with Nuxt. Using nuxt content allowed me to focus on design and, well, content.\nNo more Apollo client and graphQL query, only markdown and a few promises.\n\nDon’t get me wrong, I really like working with Strapi and its graphQL capabilities but for the purpose of this website, nuxt content does it (extremely well).\n\nI’m still using Strapi as a way to upload, store and manage images, videos, gifs, etc. It might be too much for this use case but I like to know that I can still go back to it if I want to! Also, I spent quite a bit of time setting it up with OpenLiteSpeed and I’m still too attached to this accomplishment to let it go.\n\n## In the end\n\nWordpress, Jamstack, vanilla everything… Does it really matter? For me, the dev experience was far more enjoyable working with 11ty, nuxt.js and strapi than with Wordpress.\n\nOn the performance and accessibility side, it also seems to be the better/smarter choice. It might not be everytime! ¯\\\\\\_(ツ)\\_/¯\n\nCan’t wait to learn [astro](https://astro.build/) and start from scratch again!","src/content/articles/en/the-day-I-jamd.mdx","60b77e216e02f618","en-video-compression",{"id":102,"data":104,"body":110,"filePath":111,"digest":112,"deferredRender":72},{"title":105,"subtitle":106,"lang":68,"tags":107,"type":61,"slug":102,"createdAt":108,"updatedAt":109},"Video compression","Encode like you mean it.",[70],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Let's play.\n\nVideos are everywhere. **EVERYWHERE!** But videos can and will be huge when 4k becomes an internet standard. Currently, 1920x1080 is king and we usually have no problem hosting or playing this resolution.\n\n## Because we can doesn't mean we should.\n\nRight now, the (good) trend of web performance is on the rise. Everyone wants a blazing fast loading website, which might not be possible if we send requests to 100mb (or even more) videos.\n\nWith a good connection, users will not see the difference. But if we go down that path, nor will they with a 300mb one. So the goal is to make every asset as small as possible. It's already the case with images. But it's simpler and faster than video encoding.\n\n## Small size, best quality.\n\nLet's say we exported​ a 1920x1080 video from Premiere Pro with these basic settings:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-premiere-1.jpeg'\n\twidth='673'\n\theight='800'\n/>\n\nIt's gorgeous, it's Full HD, it's 1:30 minute of excellent editing but it's 50mb… What a shame.\n\n> We can already bring down the size from Premiere or Media Encoder by selecting CBR instead of VBR and using a low bitrate (like 2 or 3).\n\nLet's now use [Handbrake!](https://handbrake.fr/) It's free, open source and multi platform. You can also read this great article from [Ueno](https://loremipsum.ueno.co/dear-ueno-how-do-you-compress-videos-6657ebd9dd28?gi=930afecec398) on video encoding.\n\n**Please please PLEASE. Never export videos from within After Effects.**\n\n## Handbrake\n\n### Summary screen\n\nWhile it's not as nice as Premiere Pro, it has way more exporting capabilities. Follow these steps to use good standard settings:\n\n1. Open your source video\n1. Select a preset corresponding to your future usage like Fast 1080p30\n1. Check Web Optimized\n1. Keep MPEG-4 as the format\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-1.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Video screen\n\n1. Keep H.264 (x264) or use H.264 nvidia nvenc if you can (crazy fast encoding by nvidia)\n1. Choose Constant Quality and try a value between 20 and 30​ (higher = smaller size but lower quality)\n1. Choose Peak Framerate. If you don't know the framerate, keep the default setting\n1. Choose the type of video you are encoding (film, animation…)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-2.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Audio screen\n\nIf you don't have audio, be sure to set the audio channel to none.\nIf you have an audio channel, these settings are great and will not influence the size much​:\n\n1. Codec AAC\n1. Samplerate 44.1\n1. Bitrate 192 to 256 (your choice)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-3.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Export!\n\nI used a RF of 25 for this example and no audio.\n\n1. My Premiere Pro video was 50,6mb\n1. My Handbrake video is 5,5mb​\n\n> What a save!\n\n​I ended up dividing the original size by 10. Which is cool.\nI tried with a RF of 30. The video was still pretty good and only 3,3mb.\n\n## Exporting for the web\n\nNow that we know how to properly compress videos, let's go further. Say we have a website with a lot of videos on the same page. We still want to load the content as fast as possible. So our videos need to be as small as possible. We won't do better than previously seen using mp4/H.264. However, we can use **webm/VP9.**\nWebm is an html video format and VP9 is its latest codec.\n\nUsing Handbrake and webm/VP9, we can achieve really great compression without losing too much quality (or none at all depending on the settings). I was able to divide by 4 the size of a video using these presets:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-4.jpg'\n\twidth='728'\n\theight='313'\n\talt=''\n/>\n\nThe only down side is that it takes some time to encode. It will depend on the video length and your computing power.\n\nI tried various settings but I read [here](https://trac.ffmpeg.org/wiki/Encode/VP9) that VP9 is supposed to be used with two-pass encoding. You then have to find the right bitrate (here 1000) for your situation.","src/content/articles/en/video-compression.mdx","5bb9f69df6c651d1","sci-hub-blocage",{"id":113,"data":115,"body":121,"filePath":122,"digest":123,"deferredRender":72},{"title":116,"subtitle":117,"lang":16,"tags":118,"type":61,"slug":113,"createdAt":119,"updatedAt":120},"Sci-hub bloqué, comment contourner","La science du partage.",[82,83],["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nL'adresse actuelle de sci-hub est : [sci-hub.se](https://sci-hub.se)\n\n## Résumé de la situation\n\nN’étant pas moi-même directement chercheur, je vous laisse regarder [cette vidéo](https://youtu.be/rcgxY__YXEc) explicative extrêmement bien faite sur le sujet de la publication scientifique.\n\n> “ Mais c’est scandaleux ! ”​\n\nJ’ai constaté que le blocage était actif chez SFR. Je n’ai pas encore pu vérifier pour les autres fournisseurs mais j’imagine qu’ils se sont tous conformés à la décision de justice.\nLe blocage mis en place est assez basique. Il s’agit d’un blocage “ DNS ”.\n\nUn DNS est un serveur qui sert à faire le lien entre un nom de domaine : **sci-hub.tw** et une adresse IP : **186.2.163.90**.\n\nC’est en quelque sorte l’annuaire d’internet. Sans l’adresse, impossible de contacter le domaine. Ce que les FAI ont certainement fait : bloquer les requêtes au nom de domaine [sci-hub.se.](http://sci-hub.se/) Ainsi, aucune adresse IP n’est renvoyée et le site n’est pas accessible.\n\n## Comment contourner ce blocage ?\n\n- Soit en utilisant un VPN\n- Soit en modifiant les serveurs DNS de vos ordinateurs/box internet\n\nJe recommande la deuxième solution car elle permet de se prémunir contre de futurs blocages/filtrages/censures de la part de votre FAI et ne nécessite pas de contrepartie financière.\nJe vais me focaliser sur le changement depuis un ordinateur car il sera effectif où que vous soyez.\n\n### Sur MacOs\n\nOuvrez :\n\n1. Préférences système\n1. Réseau\n1. Ethernet et/ou Wi-fi\n1. Avancé\n1. DNS\n1. Serveurs DNS\n\nDe là, vous pouvez ajouter des serveurs DNS en cliquant sur l'icône +. Cliquez sur ok et appliquez les nouveaux paramètres. Vous devrez peut-être redémarrer votre ordinateur pour que les changements fonctionnent.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS réglages réseau et DNS'\n/>\n\n### Sur Windows (ici 10)\n\nOuvrez :\n\n1. Réglages\n1. Réseau et internet\n1. Modifier les options de l'adaptateur\n1. Clic droit sur les propriétés de votre interface réseau\n1. Selectionnez « protocole Internet version 4 » (et/ou 6)\n1. Propriétés\n1. Utiliser l’adresse de serveur DNS suivante\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Réglages windows'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows réglages réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows régalges connections réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows options adaptateur réseau'\n/>\n\n## Quels serveurs DNS utiliser ?\n\nIl y a de nombreux serveurs DNS accessibles. Les plus connus étant ceux de Google, Cloudflare et OpenDNS. Si vous tenez vraiment à utiliser ceux de Google, je vous laisse chercher leur adresse. Voici mes recommandations par ordre de préférence.\n\nPlusieurs fournisseurs :\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMes favoris puisqu’il s’agit d’une [association française.](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net/fr)\n\nQuand9 est une fondation à but non lucratif proposant des serveurs DNS publics et gratuits. Leurs serveur classiques offrent un filtrage de domaines malveillants identifiés. Ils ne collectent pas de données et sont conforment au \u003Cabbr title=\"Règlement général sur la protection des données\">RGPD\u003C/abbr>.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## C'est tout.\n\nEn modifiant ces réglages, vous vous affranchissez de vos fournisseurs d’accès et de leurs règles de filtrage du contenu.\n\nPour l’instant, ces blocages sont presque symboliques car si Sci-hub venait à changer d’url, le blocage ne fonctionnerait plus. Mais la victoire des éditeurs au tribunal montre qu’ils n’ont pas dit leur dernier mot. Nous ne sommes donc pas à l’abri d’un futur blocage plus large et plus dur à contrer.\n\nSi vous voulez en apprendre plus sur le combat de ces gens qui se battent pour que la recherche ne soit pas une marchandise, je vous conseille [ce documentaire](https://youtu.be/y_CQATGOX2w) sur Aaron Shwartz. Ou plus simplement [cet article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) sur la fondatrice de Sci-hub.\n\nEn attendant, bonnes lectures à tou·te·s. On est avec vous !","src/content/articles/fr/sci-hub-blocage.mdx","6438fdc02b91ec59","the-day-I-jamd",{"id":124,"data":126,"body":131,"filePath":132,"digest":133,"deferredRender":72},{"title":92,"subtitle":127,"lang":16,"tags":128,"type":61,"slug":124,"createdAt":129,"updatedAt":130},"Des paris, des outils et du fun.",[95,96],["Date","2020-10-08T07:47:36.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## La solution de non facilité\n\nLorsque j’utilisais encore Wordpress pour mon site web personnel, j’ai voulu essayer le serveur web \u003Ca href=\"https://openlitespeed.org\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">OpenLiteSpeed (en anglais)\u003C/a>. En tant que designer, j’ai toujours aimé avoir une interface graphique et j’avais entendu dire qu’OLS jouissait de bonnes performances en général et de cache en particulier.\n\n## Battez-vous!\n\nQuelques années plus tard, je découvrais l’univers Jamstack et son incroyable potentiel. N’étant pas du tout impulsif, j’ai choisi de refaire entièrement mon site web avec des outils comme \u003Ca href=\"https://www.11ty.dev/\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">11ty (en anglais)\u003C/a> et \u003Ca href=\"https://strapi.io/\" hreflang=\"en\">Strapi (en anglais)\u003C/a>.\n\nJe me souviens que Strapi était encore en alpha/beta et que certains collègues me disaient que c’était un pari risqué, surtout que je découvrais à peine le monde de node.js.\n\n> Open source et français ? Je dis banco !\n\nJ’ai donc commencé à recréer mon site web à l’identique avec 11ty et Strapi. Même hébergement chez Digital Ocean, même serveur web, même contenu. J’avais fait pas mal d’optimisations de performances sur mon installation wordpress, j’étais donc impatient de comparer les résultats avec la nouvelle version statique.\n\nJ’en suis resté pantois ! Quasiment sans optimisation du côté statique, j’ai obtenu les résultats ci-dessous.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 53/100 sur Wordpress.'\n/>\n\nMalgré beaucoup d’efforts, je n’ai pas pu faire mieux. Je ne suis pas un expert en cache, je n’utilise pas de CDN et je me suis appuyé sur des plugins pour réaliser beaucoup de choses (php n’étant pas ma spécialité 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 97/100 en Jamstack.'\n/>\n\nPresque **zéro** configuration spéciale (j’étais trop impatient de tester) et j’ai atteint un score impressionnant. Je sais que les scores lighthouse ne font pas tout mais **53 contre 97**… Ça me va !\n\n## Embrassez-vous 🥰\n\nCes deux approches ont leurs avantages et leurs inconvénients. En tant que freelance, mes clients préfèrent ou demandent souvent Wordpress en raison de sa réputation. Je présente toujours une alternative Jamstack lorsque c’est possible, mais cela reste effrayant la plupart du temps par rapport à Wordpress. Je pense cependant qu’il sera plus facile d’utiliser la Jamstack avec le temps.\n\n## Encore et encore…\n\nNous voici maintenant une quarantaine et quelques mois plus tard et ce site fonctionne avec… [Nuxt.js](https://fr.nuxtjs.org/). Je sais, je suis désolé, je n’ai pas pu résister à la dernière fonctionnalité [\u003Cspan lang=\"en\">nuxt content\u003C/span>](https://content.nuxtjs.org/fr) de Nuxt.\n\nDu coup j’ai tout refait… et laissez-moi vous dire : **wow**, quelle expérience !\nJ’adore développer avec Nuxt. L’utilisation de \u003Cspan lang=\"en\">nuxt content\u003C/span> m’a permis de me concentrer sur le design et, évidemment, sur le contenu.\nPlus de client Apollo ni de requête graphQL, seulement du \u003Cspan lang=\"en\">markdown\u003C/span> et quelques promesses.\n\nAttention, j’aime beaucoup travailler avec Strapi et son interface graphQL mais pour les besoins de ce site, \u003Cspan lang=\"en\">nuxt content\u003C/span> fait le \u003Cspan lang=\"en\">job\u003C/span> (extrêmement bien).\n\nJ’utilise toujours Strapi pour téléverser, stocker et gérer les images, vidéos, gifs, etc. C’est peut-être trop pour ce que j’en fait mais j’aime savoir que je peux toujours y revenir si j’ai envie ! De plus, j’ai passé pas mal de temps à le mettre en place avec \u003Cspan lang=\"en\">OpenLiteSpeed\u003C/span> et je suis encore trop attaché à cette réussite pour la laisser tomber.\n\n## Et en fait à la fin\n\nWordpress, Jamstack, fait main… Est-ce vraiment important ? Pour moi, l’expérience de développement a été bien plus agréable en travaillant avec 11ty, nuxt.js et strapi qu’avec Wordpress.\n\nDu point de vue de la performance et de l’accessibilité, il semble également que ce soit le choix le plus judicieux. Ce n’est peut-être pas le cas à chaque fois ! ¯\\\\\\_(ツ)\\_/¯\n\nJ’ai hâte d’apprendre \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> et de tout recommencer à zéro !","src/content/articles/fr/the-day-I-jamd.mdx","57bd292bda8b6632","en-2022",{"id":134,"data":136,"body":142,"filePath":143,"digest":144,"rendered":145},{"title":137,"subtitle":138,"lang":68,"tags":139,"type":61,"slug":134,"createdAt":141},"Nico v2.0","2022 update of many things.",[140],"Freelance",["Date","2022-06-08T14:24:06.000Z"],"After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\n\n## Services\n\n### No more print\n\nEven though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for \"classic\" graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\n\n### Internet all the way\n\nOn the other hand, I spend my time **doing web stuff.** A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer **more specific web offerings,** in which I have specialised.\n\nThus, **accessibility** and **eco-design** become integrated expertises in my practice. They are no longer options on a quote but **my core business.**\n\n## The website\n\nI have reworked my website, especially the homepage and its content, to better reflect these decisions.\n\nI have also made several behavioural changes:\n\n- external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven't found a good reason to continue using this behaviour;\n- I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu);\n- \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\n- I only trigger animations if the user has not asked the system to reduce the amount motion [(reference)](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).\n\nI am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello [astro](https://astro.build/) 👀).\n\n## Le Nico\n\nOn a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\n\nI have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.","src/content/articles/en/2022.md","7b98592763cb0929",{"html":146,"metadata":147},"\u003Cp>After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\u003C/p>\n\u003Ch2 id=\"services\">Services\u003C/h2>\n\u003Ch3 id=\"no-more-print\">No more print\u003C/h3>\n\u003Cp>Even though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for “classic” graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\u003C/p>\n\u003Ch3 id=\"internet-all-the-way\">Internet all the way\u003C/h3>\n\u003Cp>On the other hand, I spend my time \u003Cstrong>doing web stuff.\u003C/strong> A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer \u003Cstrong>more specific web offerings,\u003C/strong> in which I have specialised.\u003C/p>\n\u003Cp>Thus, \u003Cstrong>accessibility\u003C/strong> and \u003Cstrong>eco-design\u003C/strong> become integrated expertises in my practice. They are no longer options on a quote but \u003Cstrong>my core business.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Cp>I have reworked my website, especially the homepage and its content, to better reflect these decisions.\u003C/p>\n\u003Cp>I have also made several behavioural changes:\u003C/p>\n\u003Cul>\n\u003Cli>external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven’t found a good reason to continue using this behaviour;\u003C/li>\n\u003Cli>I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a>;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\u003C/li>\n\u003Cli>I only trigger animations if the user has not asked the system to reduce the amount motion \u003Ca href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion\">(reference)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>I am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello \u003Ca href=\"https://astro.build/\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>On a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\u003C/p>\n\u003Cp>I have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.\u003C/p>",{"headings":148,"imagePaths":166,"frontmatter":167},[149,153,157,160,163],{"depth":150,"slug":151,"text":152},2,"services","Services",{"depth":154,"slug":155,"text":156},3,"no-more-print","No more print",{"depth":154,"slug":158,"text":159},"internet-all-the-way","Internet all the way",{"depth":150,"slug":161,"text":162},"the-website","The website",{"depth":150,"slug":164,"text":165},"le-nico","Le Nico",[],{"title":137,"subtitle":138,"lang":68,"slug":134,"excerpt":168,"tags":169,"type":61,"createdAt":170},"Changes in my services, the website and myself.",[140],"2022-06-08T14:24:06.000Z","en-2023",{"id":171,"data":173,"body":179,"filePath":180,"digest":181,"rendered":182},{"title":174,"subtitle":175,"lang":68,"tags":176,"type":61,"slug":171,"createdAt":177,"updatedAt":178},"Nico v2.5","Update 2023.",[140],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"This article will be updated when I have something new to share during the year 2023.\n\n## The website\n\n### Technologies\n\nOops... I (re)did it again.\n\nI have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself [in 2022 !](/en/articles/2022/#the-website)\n\nI will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\n\nMy \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I'm back to a solid **95/100** without any particular optimization. With some small efforts, I've reached the good old 100/100.\n\nI then did a work of modernization of the codebase. Hello CSS variables and goodbye `media queries`. In no particular order, here are some of the improvements I made:\n\n- `flexbox` and `grid` to adapt the layout to different screen sizes;\n- CSS variables for colors, font sizes and margins;\n- some `container queries`, just to try;\n- logical CSS properties (`inline` and `block` instead of `width` and `height` for example).\n\nI took this opportunity to publish [the source code](https://git.nardu.in/nardu.in/website-astro) on my git repository.\n\n**Update #1:** I've added [an RSS feed](/en/rss.xml) as I find myself using it more and more on other websites.\n\n### Analytics\n\nI removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\n\nIt's nice to see that your site is consulted, but if there is no other purpose behind it, it's an extra resource loaded for nothing by visitors. Maybe I'll reactivate the tracking when I have a use for it (other than flattering my ego).\n\nPrevious visit reports can be found at [this link.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Content\n\n- I've added a [work](/en/work/) page to list some of my projects.\n- I've also added [a page](/en/veille/) where I list some interesting things from around the web.\n\n## Additional projects\n\nI'm still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at [3-w.fr](https://3-w.fr/) (an address I am very proud of).\n\nI have to update it more regularly but I hope that the platform will help students progress!\n\n**More to come soon!**","src/content/articles/en/2023.md","489c650e66cced63",{"html":183,"metadata":184},"\u003Cp>This article will be updated when I have something new to share during the year 2023.\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oops… I (re)did it again.\u003C/p>\n\u003Cp>I have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself \u003Ca href=\"/en/articles/2022/#the-website\">in 2022 !\u003C/a>\u003C/p>\n\u003Cp>I will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\u003C/p>\n\u003Cp>My \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I’m back to a solid \u003Cstrong>95/100\u003C/strong> without any particular optimization. With some small efforts, I’ve reached the good old 100/100.\u003C/p>\n\u003Cp>I then did a work of modernization of the codebase. Hello CSS variables and goodbye \u003Ccode>media queries\u003C/code>. In no particular order, here are some of the improvements I made:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> and \u003Ccode>grid\u003C/code> to adapt the layout to different screen sizes;\u003C/li>\n\u003Cli>CSS variables for colors, font sizes and margins;\u003C/li>\n\u003Cli>some \u003Ccode>container queries\u003C/code>, just to try;\u003C/li>\n\u003Cli>logical CSS properties (\u003Ccode>inline\u003C/code> and \u003Ccode>block\u003C/code> instead of \u003Ccode>width\u003C/code> and \u003Ccode>height\u003C/code> for example).\u003C/li>\n\u003C/ul>\n\u003Cp>I took this opportunity to publish \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">the source code\u003C/a> on my git repository.\u003C/p>\n\u003Cp>\u003Cstrong>Update #1:\u003C/strong> I’ve added \u003Ca href=\"/en/rss.xml\">an RSS feed\u003C/a> as I find myself using it more and more on other websites.\u003C/p>\n\u003Ch3 id=\"analytics\">Analytics\u003C/h3>\n\u003Cp>I removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\u003C/p>\n\u003Cp>It’s nice to see that your site is consulted, but if there is no other purpose behind it, it’s an extra resource loaded for nothing by visitors. Maybe I’ll reactivate the tracking when I have a use for it (other than flattering my ego).\u003C/p>\n\u003Cp>Previous visit reports can be found at \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">this link.\u003C/a>\u003C/p>\n\u003Ch3 id=\"content\">Content\u003C/h3>\n\u003Cul>\n\u003Cli>I’ve added a \u003Ca href=\"/en/work/\">work\u003C/a> page to list some of my projects.\u003C/li>\n\u003Cli>I’ve also added \u003Ca href=\"/en/veille/\">a page\u003C/a> where I list some interesting things from around the web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"additional-projects\">Additional projects\u003C/h2>\n\u003Cp>I’m still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (an address I am very proud of).\u003C/p>\n\u003Cp>I have to update it more regularly but I hope that the platform will help students progress!\u003C/p>\n\u003Cp>\u003Cstrong>More to come soon!\u003C/strong>\u003C/p>",{"headings":185,"imagePaths":199,"frontmatter":200},[186,187,190,193,196],{"depth":150,"slug":161,"text":162},{"depth":154,"slug":188,"text":189},"technologies","Technologies",{"depth":154,"slug":191,"text":192},"analytics","Analytics",{"depth":154,"slug":194,"text":195},"content","Content",{"depth":150,"slug":197,"text":198},"additional-projects","Additional projects",[],{"title":174,"subtitle":175,"lang":68,"slug":171,"excerpt":201,"tags":202,"type":61,"createdAt":203,"updatedAt":204},"New changes.",[140],"2023-02-03T17:41:00.000Z","2023-05-17T17:41:00.000Z","en-faq",{"id":205,"data":207,"body":212,"filePath":213,"digest":214,"rendered":215},{"title":208,"subtitle":209,"lang":68,"tags":210,"type":61,"slug":205,"createdAt":211,"draft":72},"Accessibility and sobriety","Translation in progress, stay tuned ;)",[140],["Date","2022-06-22T15:34:45.000Z"],"[Go back to available articles](/en/articles)","src/content/articles/en/faq.md","82d516449896f6ca",{"html":216,"metadata":217},"\u003Cp>\u003Ca href=\"/en/articles\">Go back to available articles\u003C/a>\u003C/p>",{"headings":218,"imagePaths":219,"frontmatter":220},[],[],{"title":208,"subtitle":209,"lang":68,"slug":205,"draft":72,"excerpt":221,"tags":222,"type":61,"createdAt":223},"Why, how et and especially what.",[140],"2022-06-22T15:34:45.000Z","en-gratuiste",{"id":224,"data":226,"body":212,"filePath":230,"digest":231,"rendered":232},{"title":227,"subtitle":209,"lang":68,"tags":228,"type":61,"slug":224,"createdAt":229,"draft":72},"Gratuiste",[70,140],["Date","2017-05-27T07:47:36.000Z"],"src/content/articles/en/gratuiste.md","ebec75d19f0ff741",{"html":216,"metadata":233},{"headings":234,"imagePaths":235,"frontmatter":236},[],[],{"title":227,"subtitle":209,"lang":68,"slug":224,"draft":72,"excerpt":209,"tags":237,"type":61,"createdAt":238},[70,140],"2017-05-27T07:47:36.000Z","2022",{"id":239,"data":241,"body":245,"filePath":246,"digest":247,"rendered":248},{"title":137,"subtitle":242,"lang":16,"tags":243,"type":61,"slug":239,"createdAt":244},"Mise à jour 2022 de plein de trucs.",[140],["Date","2022-06-08T14:24:06.000Z"],"Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\n\n## Les services\n\n### J’arrête le print\n\nMême si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\n\n### J’internet à fond\n\nÀ l’inverse, je passe mon temps à **faire du web.** Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer **des offres web plus précises,** dans lesquelles je me suis spécialisé.\n\nAinsi, **l’accessibilité numérique** et **l’éco-conception** deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien **mon cœur de métier.**\n\n## Le site\n\nJ’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\n\nJ’ai également fait plusieurs changements de comportements :\n\n- les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\n- j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec [cette analyse](https://twitter.com/HTeuMeuLeu/status/1370310316496728065) de [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu) ;\n- [idem pour la favicon](https://twitter.com/HTeuMeuLeu/status/1370310312214339586) ;\n- je ne déclenche les animations que si l'utilisateur n'a pas demandé au système de minimiser la quantité d'animation ou de mouvement [(référence de l'option)](https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion).\n\nJe suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> 👀).\n\n## Le Nico\n\nD’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif [Good-it!](https://www.good-it.org/) et en participant activement à son développement.\n\nJ’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.","src/content/articles/fr/2022.md","2589166172138721",{"html":249,"metadata":250},"\u003Cp>Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\u003C/p>\n\u003Ch2 id=\"les-services\">Les services\u003C/h2>\n\u003Ch3 id=\"jarrête-le-print\">J’arrête le print\u003C/h3>\n\u003Cp>Même si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\u003C/p>\n\u003Ch3 id=\"jinternet-à-fond\">J’internet à fond\u003C/h3>\n\u003Cp>À l’inverse, je passe mon temps à \u003Cstrong>faire du web.\u003C/strong> Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer \u003Cstrong>des offres web plus précises,\u003C/strong> dans lesquelles je me suis spécialisé.\u003C/p>\n\u003Cp>Ainsi, \u003Cstrong>l’accessibilité numérique\u003C/strong> et \u003Cstrong>l’éco-conception\u003C/strong> deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien \u003Cstrong>mon cœur de métier.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Cp>J’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\u003C/p>\n\u003Cp>J’ai également fait plusieurs changements de comportements :\u003C/p>\n\u003Cul>\n\u003Cli>les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\u003C/li>\n\u003Cli>j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\">cette analyse\u003C/a> de \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a> ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\">idem pour la favicon\u003C/a> ;\u003C/li>\n\u003Cli>je ne déclenche les animations que si l’utilisateur n’a pas demandé au système de minimiser la quantité d’animation ou de mouvement \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion\">(référence de l’option)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>Je suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>D’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif \u003Ca href=\"https://www.good-it.org/\">Good-it!\u003C/a> et en participant activement à son développement.\u003C/p>\n\u003Cp>J’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.\u003C/p>",{"headings":251,"imagePaths":265,"frontmatter":266},[252,255,258,261,264],{"depth":150,"slug":253,"text":254},"les-services","Les services",{"depth":154,"slug":256,"text":257},"jarrête-le-print","J’arrête le print",{"depth":154,"slug":259,"text":260},"jinternet-à-fond","J’internet à fond",{"depth":150,"slug":262,"text":263},"le-site","Le site",{"depth":150,"slug":164,"text":165},[],{"title":137,"subtitle":242,"lang":16,"slug":239,"excerpt":267,"tags":268,"type":61,"createdAt":170},"Évolution des services, du site et de moi-même.",[140],"2023",{"id":269,"data":271,"body":276,"filePath":277,"digest":278,"rendered":279},{"title":174,"subtitle":272,"lang":16,"tags":273,"type":61,"slug":269,"createdAt":274,"updatedAt":275},"Mise à jour 2023.",[140],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"Cet article sera mis à jour lorsque j'aurai des nouveautés à partager au cours de l'année 2023.\n\n## Le site\n\n### Technologies\n\nOups… je l'ai encore (re)fait.\n\nJ'ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même [en 2022 !](/articles/2022/#le-site)\n\nJe ferai certainement un ou deux articles/fragments sur Astro et les extensions que j'ai utilisées. En tout cas c'était super comme expérience. Nuxt v2 n'étant plus vraiment à jour, les performances n'étaient plus au rendez-vous. Astro a complètement corrigé ça.\n\nMon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide **95/100** sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\n\nJ'ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les `media queries`. En vrac, voici certaines améliorations que j'ai mises en place :\n\n- `flexbox` et `grid` pour adapter la mise en page aux différentes tailles d'écran ;\n- variables CSS pour les couleurs, les tailles de polices et les marges ;\n- quelques \u003Cspan lang=\"en\">`container queries`\u003C/span> pour essayer ;\n- propriétés logiques CSS (\u003Cspan lang=\"en\">`inline`\u003C/span> et \u003Cspan lang=\"en\">`block`\u003C/span> à la place de \u003Cspan lang=\"en\">`width`\u003C/span> et \u003Cspan lang=\"en\">`height`\u003C/span> par exemple).\n\nJ'en ai profité pour publier [le code source](https://git.nardu.in/nardu.in/website-astro) sur mon dépôt git.\n\n**Mise à jour #1 :** J'ai ajouté [un flux RSS](/rss.xml) car j'utilise de plus en plus le RSS sur d'autres sites web.\n\n### Suivi des visites\n\nJ’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n'était collectée et je consultais rarement les rapports.\n\nC'est sympa de voir que son site est visité, mais s'il n'y a aucun autre but derrière, c'est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j'en aurai l'utilité (autre que flatter mon égo).\n\nLes rapports de visites précédents sont consultables sur [ce lien.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Contenu\n\n- J'ai ajouté une page [références](/references/) pour lister certains de mes projets.\n- J'ai également ajouté [une page](/veille/) où je répertorie des choses intéressantes trouvées sur le web.\n\n## Projets annexes\n\nJe continue d'enseigner le développement web cette année. Afin d'étoffer mes supports de cours, j'ai mis en place un mini site de documentation disponible à l'adresse [3-w.fr](https://3-w.fr/) (adresse dont je suis très fier).\n\nIl faut que j'arrive à être plus régulier dans sa mise à jour mais j'ai bon espoir que la plateforme aide les élèves à progresser !\n\n**Plus de trucs bientôt!**","src/content/articles/fr/2023.md","d97f4a5af975333f",{"html":280,"metadata":281},"\u003Cp>Cet article sera mis à jour lorsque j’aurai des nouveautés à partager au cours de l’année 2023.\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oups… je l’ai encore (re)fait.\u003C/p>\n\u003Cp>J’ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même \u003Ca href=\"/articles/2022/#le-site\">en 2022 !\u003C/a>\u003C/p>\n\u003Cp>Je ferai certainement un ou deux articles/fragments sur Astro et les extensions que j’ai utilisées. En tout cas c’était super comme expérience. Nuxt v2 n’étant plus vraiment à jour, les performances n’étaient plus au rendez-vous. Astro a complètement corrigé ça.\u003C/p>\n\u003Cp>Mon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide \u003Cstrong>95/100\u003C/strong> sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\u003C/p>\n\u003Cp>J’ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les \u003Ccode>media queries\u003C/code>. En vrac, voici certaines améliorations que j’ai mises en place :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> et \u003Ccode>grid\u003C/code> pour adapter la mise en page aux différentes tailles d’écran ;\u003C/li>\n\u003Cli>variables CSS pour les couleurs, les tailles de polices et les marges ;\u003C/li>\n\u003Cli>quelques \u003Cspan lang=\"en\">\u003Ccode>container queries\u003C/code>\u003C/span> pour essayer ;\u003C/li>\n\u003Cli>propriétés logiques CSS (\u003Cspan lang=\"en\">\u003Ccode>inline\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>block\u003C/code>\u003C/span> à la place de \u003Cspan lang=\"en\">\u003Ccode>width\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>height\u003C/code>\u003C/span> par exemple).\u003C/li>\n\u003C/ul>\n\u003Cp>J’en ai profité pour publier \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">le code source\u003C/a> sur mon dépôt git.\u003C/p>\n\u003Cp>\u003Cstrong>Mise à jour #1 :\u003C/strong> J’ai ajouté \u003Ca href=\"/rss.xml\">un flux RSS\u003C/a> car j’utilise de plus en plus le RSS sur d’autres sites web.\u003C/p>\n\u003Ch3 id=\"suivi-des-visites\">Suivi des visites\u003C/h3>\n\u003Cp>J’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n’était collectée et je consultais rarement les rapports.\u003C/p>\n\u003Cp>C’est sympa de voir que son site est visité, mais s’il n’y a aucun autre but derrière, c’est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j’en aurai l’utilité (autre que flatter mon égo).\u003C/p>\n\u003Cp>Les rapports de visites précédents sont consultables sur \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">ce lien.\u003C/a>\u003C/p>\n\u003Ch3 id=\"contenu\">Contenu\u003C/h3>\n\u003Cul>\n\u003Cli>J’ai ajouté une page \u003Ca href=\"/references/\">références\u003C/a> pour lister certains de mes projets.\u003C/li>\n\u003Cli>J’ai également ajouté \u003Ca href=\"/veille/\">une page\u003C/a> où je répertorie des choses intéressantes trouvées sur le web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"projets-annexes\">Projets annexes\u003C/h2>\n\u003Cp>Je continue d’enseigner le développement web cette année. Afin d’étoffer mes supports de cours, j’ai mis en place un mini site de documentation disponible à l’adresse \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (adresse dont je suis très fier).\u003C/p>\n\u003Cp>Il faut que j’arrive à être plus régulier dans sa mise à jour mais j’ai bon espoir que la plateforme aide les élèves à progresser !\u003C/p>\n\u003Cp>\u003Cstrong>Plus de trucs bientôt!\u003C/strong>\u003C/p>",{"headings":282,"imagePaths":294,"frontmatter":295},[283,284,285,288,291],{"depth":150,"slug":262,"text":263},{"depth":154,"slug":188,"text":189},{"depth":154,"slug":286,"text":287},"suivi-des-visites","Suivi des visites",{"depth":154,"slug":289,"text":290},"contenu","Contenu",{"depth":150,"slug":292,"text":293},"projets-annexes","Projets annexes",[],{"title":174,"subtitle":272,"lang":16,"slug":269,"excerpt":296,"tags":297,"type":61,"createdAt":203,"updatedAt":204},"Suite des évolutions.",[140],"after-effects-expressions",{"id":298,"data":300,"body":304,"filePath":305,"digest":306,"rendered":307},{"title":66,"subtitle":301,"lang":16,"tags":302,"type":61,"slug":298,"createdAt":303,"draft":72},"En cours de traduction, revenez bientôt ;)",[70],["Date","2019-04-24T09:00:00.000Z"],"[Retour aux articles](/articles)","src/content/articles/fr/after-effects-expressions.md","884d725859a7bab5",{"html":308,"metadata":309},"\u003Cp>\u003Ca href=\"/articles\">Retour aux articles\u003C/a>\u003C/p>",{"headings":310,"imagePaths":311,"frontmatter":312},[],[],{"title":66,"subtitle":301,"lang":16,"draft":72,"slug":298,"excerpt":301,"tags":313,"type":61,"createdAt":314},[70],"2019-04-24T09:00:00.000Z","faq",{"id":315,"data":317,"body":322,"filePath":323,"digest":324,"rendered":325},{"title":318,"subtitle":319,"lang":16,"tags":320,"type":61,"slug":315,"createdAt":321},"Accessibilité, sobriété et F.A.Q.","Explications sur ma vision et mon fonctionnement.",[140],["Date","2022-06-22T15:34:45.000Z"],"## l'Accessibilité\n\n### Quèsaco ?\n\nD'après [access42 :](https://access42.net)\n\n> L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\n\nAinsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que **n'importe quel visiteur** puisse l'utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais **ce n'est pas le cas !**\n\nLorsqu'un site est pensé et conçu avec l'accessibilité en tête, il ne prend **pas plus de temps** qu'un projet qui ne le fait pas. En revanche, **corriger** un site existant qui n'a pas bénéficié de cette réflexion en amont **demande beaucoup plus d'efforts.**\n\n### Pourquoi c'est important ?\n\nAprès avoir été sensibilisé à l'accessibilité et aux [situations frustrantes voire bloquantes](https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles) que rencontrent les personnes handicapées sur le web, j'ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m'a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\n\n## l'Éco-conception\n\n### Quèsaco ?\n\nD'après le collectif [\u003Cspan lang=\"en\">green it\u003C/span> :](https://www.greenit.fr)\n\n> L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\n\nIl s'agit ici pour moi de créer des produits les plus sobres possibles. C'est-à-dire de développer ou d'utiliser une fonctionnalité uniquement si elle est indispensable.\n\nPar exemple, mettre en place **un formulaire de contact** sur un site web implique plusieurs choses :\n\n- développer un formulaire\n- envoyer les données au serveur\n- vérifier les données envoyées\n- envoyer les données par mail\n- confirmer l'envoi du mail (en fournissant une copie)\n- gérer les erreurs à chaque étape\n\nUn site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d'effectuer ces opérations (ou un prestataire qui s'en charge). C'est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu'un formulaire. Dans le cas d'un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\n\n### Pourquoi c'est important ?\n\nL'éco-conception fait beaucoup de bien à la qualité globale d'un site et à l'expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\n\n## F.A.Q.\n\n### Cette démarche est-elle opportuniste ?\n\n**Non.** Il est vrai que l'accessibilité et, surtout, l'éco-conception, commencent à être « tendance ». On pourrait donc croire que j'en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c'est ma responsabilité de créer des sites web accessibles et éco-conçus **par défaut.**\n\n### Un site accessible est-il plus cher ?\n\n**Oui et non.** Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l'accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j'augmente mes tarifs suite à l'obtention de certifications relatives à mon activité.\n\n### Mon site sera-t-il 100 % accessible ?\n\n**Non,** je ne suis pas en mesure de garantir ou de certifier la conformité totale d'un site au [référentiel général d'amélioration de l'accessibilité.](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d'un site. Cependant, je peux vous accompagner avant et après l'audit afin d'anticiper puis de corriger les critères d'accessibilité requis. [Access42](https://access42.net/) et [Tanaguru](https://www.tanaguru.com/) font parties de ces entreprises spécialisées.\n\n### Pourquoi ne pas utiliser un outil automatique ?\n\nCar ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom [sous peine de procès](https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/)), ne sont pas des solutions micracles. Lisez [cet article](https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/) d'une experte en accessibilité et/ou [ce test](https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/) de différents outils pour en savoir plus.\n\n### Un site éco-conçu et accessible peut-il être beau ?\n\n**Oui, évidemment.** Je vous laisse juger par vous-même avec [cette liste](https://lowww.directory/) de sites éco-conçus. En ce qui concerne l'accessibilité, elle n'impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d'un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l'utilisation d'un produit.","src/content/articles/fr/faq.md","65e9e60bcd00806c",{"html":326,"metadata":327},"\u003Ch2 id=\"laccessibilité\">l’Accessibilité\u003C/h2>\n\u003Ch3 id=\"quèsaco\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après \u003Ca href=\"https://access42.net\">access42 :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Ainsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que \u003Cstrong>n’importe quel visiteur\u003C/strong> puisse l’utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais \u003Cstrong>ce n’est pas le cas !\u003C/strong>\u003C/p>\n\u003Cp>Lorsqu’un site est pensé et conçu avec l’accessibilité en tête, il ne prend \u003Cstrong>pas plus de temps\u003C/strong> qu’un projet qui ne le fait pas. En revanche, \u003Cstrong>corriger\u003C/strong> un site existant qui n’a pas bénéficié de cette réflexion en amont \u003Cstrong>demande beaucoup plus d’efforts.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>Après avoir été sensibilisé à l’accessibilité et aux \u003Ca href=\"https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles\">situations frustrantes voire bloquantes\u003C/a> que rencontrent les personnes handicapées sur le web, j’ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m’a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\u003C/p>\n\u003Ch2 id=\"léco-conception\">l’Éco-conception\u003C/h2>\n\u003Ch3 id=\"quèsaco-1\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après le collectif \u003Ca href=\"https://www.greenit.fr\">\u003Cspan lang=\"en\">green it\u003C/span> :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Il s’agit ici pour moi de créer des produits les plus sobres possibles. C’est-à-dire de développer ou d’utiliser une fonctionnalité uniquement si elle est indispensable.\u003C/p>\n\u003Cp>Par exemple, mettre en place \u003Cstrong>un formulaire de contact\u003C/strong> sur un site web implique plusieurs choses :\u003C/p>\n\u003Cul>\n\u003Cli>développer un formulaire\u003C/li>\n\u003Cli>envoyer les données au serveur\u003C/li>\n\u003Cli>vérifier les données envoyées\u003C/li>\n\u003Cli>envoyer les données par mail\u003C/li>\n\u003Cli>confirmer l’envoi du mail (en fournissant une copie)\u003C/li>\n\u003Cli>gérer les erreurs à chaque étape\u003C/li>\n\u003C/ul>\n\u003Cp>Un site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d’effectuer ces opérations (ou un prestataire qui s’en charge). C’est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu’un formulaire. Dans le cas d’un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important-1\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>L’éco-conception fait beaucoup de bien à la qualité globale d’un site et à l’expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\u003C/p>\n\u003Ch2 id=\"faq\">F.A.Q.\u003C/h2>\n\u003Ch3 id=\"cette-démarche-est-elle-opportuniste\">Cette démarche est-elle opportuniste ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non.\u003C/strong> Il est vrai que l’accessibilité et, surtout, l’éco-conception, commencent à être « tendance ». On pourrait donc croire que j’en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c’est ma responsabilité de créer des sites web accessibles et éco-conçus \u003Cstrong>par défaut.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"un-site-accessible-est-il-plus-cher\">Un site accessible est-il plus cher ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui et non.\u003C/strong> Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l’accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j’augmente mes tarifs suite à l’obtention de certifications relatives à mon activité.\u003C/p>\n\u003Ch3 id=\"mon-site-sera-t-il-100-accessible\">Mon site sera-t-il 100 % accessible ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non,\u003C/strong> je ne suis pas en mesure de garantir ou de certifier la conformité totale d’un site au \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité.\u003C/a> Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d’un site. Cependant, je peux vous accompagner avant et après l’audit afin d’anticiper puis de corriger les critères d’accessibilité requis. \u003Ca href=\"https://access42.net/\">Access42\u003C/a> et \u003Ca href=\"https://www.tanaguru.com/\">Tanaguru\u003C/a> font parties de ces entreprises spécialisées.\u003C/p>\n\u003Ch3 id=\"pourquoi-ne-pas-utiliser-un-outil-automatique\">Pourquoi ne pas utiliser un outil automatique ?\u003C/h3>\n\u003Cp>Car ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom \u003Ca href=\"https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/\">sous peine de procès\u003C/a>), ne sont pas des solutions micracles. Lisez \u003Ca href=\"https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/\">cet article\u003C/a> d’une experte en accessibilité et/ou \u003Ca href=\"https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/\">ce test\u003C/a> de différents outils pour en savoir plus.\u003C/p>\n\u003Ch3 id=\"un-site-éco-conçu-et-accessible-peut-il-être-beau\">Un site éco-conçu et accessible peut-il être beau ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui, évidemment.\u003C/strong> Je vous laisse juger par vous-même avec \u003Ca href=\"https://lowww.directory/\">cette liste\u003C/a> de sites éco-conçus. En ce qui concerne l’accessibilité, elle n’impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d’un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l’utilisation d’un produit.\u003C/p>",{"headings":328,"imagePaths":362,"frontmatter":363},[329,332,335,338,341,343,345,347,350,353,356,359],{"depth":150,"slug":330,"text":331},"laccessibilité","l’Accessibilité",{"depth":154,"slug":333,"text":334},"quèsaco","Quèsaco ?",{"depth":154,"slug":336,"text":337},"pourquoi-cest-important","Pourquoi c’est important ?",{"depth":150,"slug":339,"text":340},"léco-conception","l’Éco-conception",{"depth":154,"slug":342,"text":334},"quèsaco-1",{"depth":154,"slug":344,"text":337},"pourquoi-cest-important-1",{"depth":150,"slug":315,"text":346},"F.A.Q.",{"depth":154,"slug":348,"text":349},"cette-démarche-est-elle-opportuniste","Cette démarche est-elle opportuniste ?",{"depth":154,"slug":351,"text":352},"un-site-accessible-est-il-plus-cher","Un site accessible est-il plus cher ?",{"depth":154,"slug":354,"text":355},"mon-site-sera-t-il-100-accessible","Mon site sera-t-il 100 % accessible ?",{"depth":154,"slug":357,"text":358},"pourquoi-ne-pas-utiliser-un-outil-automatique","Pourquoi ne pas utiliser un outil automatique ?",{"depth":154,"slug":360,"text":361},"un-site-éco-conçu-et-accessible-peut-il-être-beau","Un site éco-conçu et accessible peut-il être beau ?",[],{"title":318,"subtitle":319,"lang":16,"slug":315,"excerpt":364,"tags":365,"type":61,"createdAt":223},"Pourquoi, comment et surtout quèsaco.",[140],"gratuiste",{"id":366,"data":368,"body":374,"filePath":375,"digest":376,"rendered":377},{"title":227,"subtitle":369,"lang":16,"tags":370,"type":61,"slug":366,"createdAt":372,"updatedAt":373},"Ou le travail gratuit.",[371,140],"Graphisme",["Date","2017-05-27T07:47:36.000Z"],["Date","2022-12-27T15:36:06.000Z"],"## Gratuiste, qu’est-ce que c’est ?\n\nDans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc. \nDe plus en plus, la communauté s’élève contre ces pratiques et les [dénonce.](https://twitter.com/PayeTonAffiche)\n\n> “ On n’est pas des gratuistes ! ”\n\nComprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez [cette vidéo](https://youtu.be/essNmNOrQto) qui transpose ces pratiques à des métiers “ standards ” et [celle-ci](https://youtu.be/DsstOs-K7gk) qui explique en détails le processus actuel.\n\n## T’es débile du coup ?\n\nJ’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\n\nÉtant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre. \nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\n\n## Le concept\n\nJe compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux. \nCe type de prestation porte le nom de “ **pro bono publico** ” – “ **pour le bien public** ”.\n\nCette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\n\n> Graphiste pro bono, pourquoi pas ?\n\n## Quels genres de services ?\n\nEn toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\n\n### En résumé :\n\n- maquette de site web\n- intégration front-end (en dur ou via wordpress) du site\n- gestion de la mise en ligne du site\n- newsletter (design et/ou intégration)\n- flyers\n- autres petites demandes\n\nVous pouvez avoir un aperçu de mon travail [sur ce même site.](/) J’ai déjà eu l’occasion de travailler pour :\n\n- [Cygnal](/projets/cygnal)\n- [OpenMole](https://openmole.org/)\n- [Good-it](https://good-it.org)\n\n## Dans quelles conditions ?\n\n- l’association doit être active\n- elle doit porter des valeurs que je partage\n- elle doit pouvoir me montrer ses actions\n- elle ne doit pas avoir les moyens de se payer un graphiste\n\n## C’est un peu trop beau pour être vrai ton truc…\n\nIl faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\n\nSi vous êtes intéressés, [envoyez-moi un mail !](mailto:contac@nardu.in)\n\n## Qu’est-ce que t’y gagnes toi ?\n\nSimplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.","src/content/articles/fr/gratuiste.md","80c20493583a842c",{"html":378,"metadata":379},"\u003Ch2 id=\"gratuiste-quest-ce-que-cest\">Gratuiste, qu’est-ce que c’est ?\u003C/h2>\n\u003Cp>Dans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc.\u003Cbr>\nDe plus en plus, la communauté s’élève contre ces pratiques et les \u003Ca href=\"https://twitter.com/PayeTonAffiche\">dénonce.\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“ On n’est pas des gratuistes ! ”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Comprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez \u003Ca href=\"https://youtu.be/essNmNOrQto\">cette vidéo\u003C/a> qui transpose ces pratiques à des métiers “ standards ” et \u003Ca href=\"https://youtu.be/DsstOs-K7gk\">celle-ci\u003C/a> qui explique en détails le processus actuel.\u003C/p>\n\u003Ch2 id=\"tes-débile-du-coup\">T’es débile du coup ?\u003C/h2>\n\u003Cp>J’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\u003C/p>\n\u003Cp>Étant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre.\u003Cbr>\nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\u003C/p>\n\u003Ch2 id=\"le-concept\">Le concept\u003C/h2>\n\u003Cp>Je compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux.\u003Cbr>\nCe type de prestation porte le nom de “ \u003Cstrong>pro bono publico\u003C/strong> ” – “ \u003Cstrong>pour le bien public\u003C/strong> ”.\u003C/p>\n\u003Cp>Cette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Graphiste pro bono, pourquoi pas ?\u003C/p>\n\u003C/blockquote>\n\u003Ch2 id=\"quels-genres-de-services\">Quels genres de services ?\u003C/h2>\n\u003Cp>En toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\u003C/p>\n\u003Ch3 id=\"en-résumé\">En résumé :\u003C/h3>\n\u003Cul>\n\u003Cli>maquette de site web\u003C/li>\n\u003Cli>intégration front-end (en dur ou via wordpress) du site\u003C/li>\n\u003Cli>gestion de la mise en ligne du site\u003C/li>\n\u003Cli>newsletter (design et/ou intégration)\u003C/li>\n\u003Cli>flyers\u003C/li>\n\u003Cli>autres petites demandes\u003C/li>\n\u003C/ul>\n\u003Cp>Vous pouvez avoir un aperçu de mon travail \u003Ca href=\"/\">sur ce même site.\u003C/a> J’ai déjà eu l’occasion de travailler pour :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"/projets/cygnal\">Cygnal\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://openmole.org/\">OpenMole\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://good-it.org\">Good-it\u003C/a>\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"dans-quelles-conditions\">Dans quelles conditions ?\u003C/h2>\n\u003Cul>\n\u003Cli>l’association doit être active\u003C/li>\n\u003Cli>elle doit porter des valeurs que je partage\u003C/li>\n\u003Cli>elle doit pouvoir me montrer ses actions\u003C/li>\n\u003Cli>elle ne doit pas avoir les moyens de se payer un graphiste\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"cest-un-peu-trop-beau-pour-être-vrai-ton-truc\">C’est un peu trop beau pour être vrai ton truc…\u003C/h2>\n\u003Cp>Il faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\u003C/p>\n\u003Cp>Si vous êtes intéressés, \u003Ca href=\"mailto:contac@nardu.in\">envoyez-moi un mail !\u003C/a>\u003C/p>\n\u003Ch2 id=\"quest-ce-que-ty-gagnes-toi\">Qu’est-ce que t’y gagnes toi ?\u003C/h2>\n\u003Cp>Simplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.\u003C/p>",{"headings":380,"imagePaths":405,"frontmatter":406},[381,384,387,390,393,396,399,402],{"depth":150,"slug":382,"text":383},"gratuiste-quest-ce-que-cest","Gratuiste, qu’est-ce que c’est ?",{"depth":150,"slug":385,"text":386},"tes-débile-du-coup","T’es débile du coup ?",{"depth":150,"slug":388,"text":389},"le-concept","Le concept",{"depth":150,"slug":391,"text":392},"quels-genres-de-services","Quels genres de services ?",{"depth":154,"slug":394,"text":395},"en-résumé","En résumé :",{"depth":150,"slug":397,"text":398},"dans-quelles-conditions","Dans quelles conditions ?",{"depth":150,"slug":400,"text":401},"cest-un-peu-trop-beau-pour-être-vrai-ton-truc","C’est un peu trop beau pour être vrai ton truc…",{"depth":150,"slug":403,"text":404},"quest-ce-que-ty-gagnes-toi","Qu’est-ce que t’y gagnes toi ?",[],{"title":227,"subtitle":369,"lang":16,"slug":366,"excerpt":407,"tags":408,"type":61,"createdAt":238,"updatedAt":409},"J’ai cherché un moyen de mettre mes compétences au service d’autrui et je pense avoir trouvé: je vais travailler gratuitement pour des associations.",[371,140],"2022-12-27T15:36:06.000Z","video-compression",{"id":410,"data":412,"body":304,"filePath":417,"digest":418,"rendered":419},{"title":413,"subtitle":301,"lang":16,"tags":414,"type":61,"slug":410,"createdAt":415,"updatedAt":416,"draft":72},"Compression vidéo",[70],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"src/content/articles/fr/video-compression.md","2296c41874b23b3d",{"html":308,"metadata":420},{"headings":421,"imagePaths":422,"frontmatter":423},[],[],{"title":413,"subtitle":301,"lang":16,"draft":72,"slug":410,"excerpt":424,"tags":425,"type":61,"createdAt":426,"updatedAt":170},"Pas encore traduit",[70],"2021-05-05T09:00:00.000Z","fragments",["Map",429,430,441,442,452,453,462,463,473,474,484,485,539,540,556,557,574,575,587,588,651,652,713,714,748,749,782,783,806,807,848,849],"en-image-full",{"id":429,"data":431,"body":438,"filePath":439,"digest":440,"deferredRender":72},{"title":432,"subtitle":209,"lang":68,"tags":433,"type":435,"slug":429,"createdAt":436,"updatedAt":437,"draft":72},"Full width image",[434],"CSS","snippets",["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"[Go back to available snippets](/en/snippets)","src/content/fragments/en/image-full.mdx","2e3dddf593f6d72f","en-super-cookies",{"id":441,"data":443,"body":449,"filePath":450,"digest":451,"deferredRender":72},{"title":444,"subtitle":445,"lang":68,"tags":446,"type":435,"slug":441,"createdAt":448},"The best cookies","Consentless biscuits.",[447],"food",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 tablespoon of baking powder\n- 3/4 of aquafaba from 400g of chickpea (chickpea water)\n- 125 grams of coconut oil\n- 2 teaspoons of maple syrup\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- if necessary, melt the coconut oil over low heat\n- meanwhile, mix all the dry ingredients\n- add all liquid ingredients (oil, aquafaba, maple syrup)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Non vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 table spoon of baking powder\n- 1 egg\n- 125 grams of melted butter\n- 2 teaspoons of honey\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- melt butter over low heat\n- meanwhile, mix all dry ingredients\n- add all liquid ingredients (melted butter, egg, honey)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Notes\n\nChocolate can be replaced by anything like nuts, raisins, legos... (don't eat legos be reasonable).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='All ingredients mixed together to form a brown paste.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='The cookies are round and soft after baking.'\n/>","src/content/fragments/en/super-cookies.mdx","b0c67adad40c177c","buttons",{"id":452,"data":454,"body":459,"filePath":460,"digest":461,"deferredRender":72},{"title":455,"subtitle":456,"lang":16,"tags":457,"type":427,"slug":452,"createdAt":458,"code":72,"draft":72},"Effets de survol de boutons","Simples mais efficaces.",[434],["Date","2020-10-08T09:00:00.000Z"],"## Styles généraux\n\nTous les boutons présents utilisent ces styles comme base en guise de « reset » :\n\n> N'oubliez pas de préfixer si besoin !\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Ajout d'icône\n\n\u003Cbutton role='none' class='btn btn-icon'>\n\t\u003Cspan>Icône\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('./assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double volet\n\n\u003Cbutton role='none' class='btn btn-rideau'>\n\t\u003Cspan>Volet\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Dégradé animé\n\n\u003Cbutton role='none' class='btn btn-gradient'>\n\t\u003Cspan>Dégradé\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Échelle non desctructrice\n\n\u003Cbutton role='none' class='btn btn-scale'>\n\t\u003Cspan>Échelle\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/fr/buttons.mdx","f5d7b03520f96b04","image-full",{"id":462,"data":464,"body":470,"filePath":471,"digest":472,"deferredRender":72},{"title":465,"subtitle":466,"lang":16,"tags":467,"type":427,"slug":462,"createdAt":468,"updatedAt":469},"Image pleine largeur","Casser le conteneur.",[434],["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Image inline\n\nOn est parfois obligé d'utiliser des images dans des balises `img` plutôt que dans un `background` en css. Comment faire alors pour que l'image sorte de son conteneur pour en faire une bannière ? Exemple pratique à partir de ce même site.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_container_9e3939b3ae.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Contexte\n\nConsidérons le html suivant :\n\n```html\n\u003Csection class=\"container\">\n\t\u003Cdiv class=\"hero\">\n\t\t\u003Cimg class=\"hero__image\" src=\"hero.img\" />\n\t\u003C/div>\n\u003C/section>\n```\n\nEt le style suivant :\n\n```css\n.container {\n\tpadding: 0 14px;\n\tmargin-left: auto;\n\tmargin-right: auto;\n\tmax-width: 1040px;\n}\nimg {\n\tmax-width: 100%;\n\theight: auto;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_original_d49f0d11bf.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Déborder du conteneur\n\nAfin de faire prendre à l'image toute la largeur, on agit sur son conteneur :\n\n```css\n.hero {\n\tmargin-left: calc(50% - 50vw);\n\tposition: relative;\n\twidth: 100vw;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_full_2a902f9539.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Faire une bannière\n\nOn peut alors réduire la hauteur du conteneur pour obtenir une bannière plutôt que l'image entière et faire correspondre la hauteur de l'image à la hauteur du conteneur :\n\n```css\n.hero {\n\theight: 200px;\n}\n.hero__image {\n\theight: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_height_81b4ce969a.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nIl faut ensuite forcer l'image à prendre toute la largeur du conteneur :\n\n```css\n.hero__image {\n\twidth: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_deformed_479046d2cb.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nPas top…\n\n### J'ai cassé l'image…\n\n**ENFIN** le code magique pour redonner son ratio à l'image sans la déformer :\n\n```css\n.hero__image {\n\tobject-fit: cover;\n\tobject-position: center; /* à positionner comme on veut */\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_6c164e82b3.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nCette technique s'apparente à l'utilisation d'une image de background mais en dur 😁\n\n## TL;DR\n\nLe code complet :\n\n```css\n.hero {\n\tmargin-left: calc(50% - 50vw);\n\tposition: relative;\n\twidth: 100vw;\n\theight: 200px;\n}\n.hero__image {\n\twidth: 100%;\n\theight: 100%;\n\t-o-object-fit: cover;\n\tobject-fit: cover;\n\t-o-object-position: center;\n\tobject-position: center;\n}\n```","src/content/fragments/fr/image-full.mdx","91ebd97eef5cb8a4","super-cookies",{"id":473,"data":475,"body":481,"filePath":482,"digest":483,"deferredRender":72},{"title":476,"subtitle":477,"lang":16,"tags":478,"type":427,"slug":473,"createdAt":480},"Les meilleurs cookies","Des gâteaux sans consentement.",[479],"cuisine",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Version végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 3/4 de l'aquafaba de 400g de pois chiche (l'eau des pois chiche)\n- 125 grammes d'huile de noix de coco\n- 2 cuillères à café de sirop d'érable\n- 1 plaquette de chocolat (noir) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre si besoin l'huile de noix de coco à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (huile, aquafaba, sirop d'érable)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Version non végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 1 œuf\n- 125 grammes de beurre fondu\n- 2 cuillères à café de miel\n- 1 plaquette de chocolat (noir/blanc/les deux) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre le beurre à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (beurre fondu, œuf, miel)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Notes\n\nLe chocolat peut-être remplacé par n'importe quoi comme des noix, des raisins secs, des légos… (mangez pas des légos soyez sérieux).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Tous les ingrédients mélangés forment une pâte marron.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Les cookies cuits sont bombés et très moelleux.'\n/>","src/content/fragments/fr/super-cookies.mdx","f7a802e0b68cb04a","en-toulouse-fun",{"id":484,"data":486,"body":492,"filePath":493,"digest":494,"rendered":495},{"title":487,"subtitle":488,"lang":68,"tags":489,"type":435,"slug":484,"createdAt":491},"Toulouse yourself","Only the bestest",[490],"lifestyle",["Date","2022-06-22T15:34:45.000Z"],"Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite. \n**It's always a good idea to make a reservation!**\n\n## Restaurants\n\n### French cuisine\n\n- [Solides](https://www.solides.fr/) — semi-gastronomic\n- [Les impulsifs](https://les-impulsifs-toulouse.eatbu.com/?lang=en) — semi-gastronomic\n- [Sixta](https://sixta-toulouse.fr/) — vege/vegan/gluten friendly\n- [Attila](https://attila.site-solocal.com/) — great **fish restaurant,** just above the Victor Hugo market\n- [Chez Emile](https://www.restaurant-emile.com/) - best [cassoulet](https://en.wikipedia.org/wiki/Cassoulet) in town (or so I'm told)\n\n### Korean\n\n- [Le ptit Louis](https://leptitlouis.fr/) — best of its kind, **only for lunch**\n- [Kongbap](https://kong-bap.com/) — street-food like\n\n### Japanese\n\n- [Iori](https://www.iori.fr/) — best ramen\n- [Japoyaki](https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402) — best sushi/sashimis\n\n## Drinks and snacks\n\n### Bars\n\n- [Le Bièrographe](https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327) — all time favourite, **check out the typical toulouse basement**\n- [A Taula](https://www.facebook.com/ataulatolosa/) — all time favourite in summer, **amazing terrace,** also: great tapas\n- [The Hopscotch Pub](https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385) — good beers, good whiskies, good cocktials, good food\n\n### Cafés & tea rooms\n\n- [Bapz](https://www.bapz.fr/contact) — Excellent pastries / hot beverages\n- [Ô thé divin](https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/) — nice lunch options\n- [Les Rêveries d’Hercule](https://www.lesreveriesdhercule.com/) — Pottery Café, relaxing activity (ceramics need to be baked, there'll be a delay to get them back)\n- Bonus: the best bakeries in [Carmes](https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872) and [Saint-Aubin](https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694) — croissants, baguettes **traditions**, chocolatines and more\n\n### Wine shops\n\n- [l'envie du sud](https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930) — amazing selection of wines and other spirits, excellent advice from the staff\n- [enoteca](https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952) — smaller selection but more beers and great advice from the staff as well\n\n## Other delights\n\n### Ice creams\n\n- [Forno gusto](https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450) — only in the summer\n- [Moustache](https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540) — lots of flavours\n\n### Cheese shop\n\n- [Xavier](https://xavier.fr/) — one of the **best of the country**, two shops in Toulouse, including one at Victor Hugo market\n- [Massembea](https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490) — a serious contender in Toulouse (weird hours)\n\n### Delicatessen\n\n- [Café Bacquié](http://cafe-bacquie.com/) — stock up on fine foods, coffees, teas and other great quality products","src/content/fragments/en/toulouse-fun.md","370491cc68079e8c",{"html":496,"metadata":497},"\u003Cp>Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite.\u003Cbr>\n\u003Cstrong>It’s always a good idea to make a reservation!\u003C/strong>\u003C/p>\n\u003Ch2 id=\"restaurants\">Restaurants\u003C/h2>\n\u003Ch3 id=\"french-cuisine\">French cuisine\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.solides.fr/\">Solides\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://les-impulsifs-toulouse.eatbu.com/?lang=en\">Les impulsifs\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://sixta-toulouse.fr/\">Sixta\u003C/a> — vege/vegan/gluten friendly\u003C/li>\n\u003Cli>\u003Ca href=\"https://attila.site-solocal.com/\">Attila\u003C/a> — great \u003Cstrong>fish restaurant,\u003C/strong> just above the Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.restaurant-emile.com/\">Chez Emile\u003C/a> - best \u003Ca href=\"https://en.wikipedia.org/wiki/Cassoulet\">cassoulet\u003C/a> in town (or so I’m told)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"korean\">Korean\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://leptitlouis.fr/\">Le ptit Louis\u003C/a> — best of its kind, \u003Cstrong>only for lunch\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://kong-bap.com/\">Kongbap\u003C/a> — street-food like\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"japanese\">Japanese\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.iori.fr/\">Iori\u003C/a> — best ramen\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402\">Japoyaki\u003C/a> — best sushi/sashimis\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"drinks-and-snacks\">Drinks and snacks\u003C/h2>\n\u003Ch3 id=\"bars\">Bars\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327\">Le Bièrographe\u003C/a> — all time favourite, \u003Cstrong>check out the typical toulouse basement\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.facebook.com/ataulatolosa/\">A Taula\u003C/a> — all time favourite in summer, \u003Cstrong>amazing terrace,\u003C/strong> also: great tapas\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385\">The Hopscotch Pub\u003C/a> — good beers, good whiskies, good cocktials, good food\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cafés--tea-rooms\">Cafés & tea rooms\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.bapz.fr/contact\">Bapz\u003C/a> — Excellent pastries / hot beverages\u003C/li>\n\u003Cli>\u003Ca href=\"https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/\">Ô thé divin\u003C/a> — nice lunch options\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lesreveriesdhercule.com/\">Les Rêveries d’Hercule\u003C/a> — Pottery Café, relaxing activity (ceramics need to be baked, there’ll be a delay to get them back)\u003C/li>\n\u003Cli>Bonus: the best bakeries in \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872\">Carmes\u003C/a> and \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694\">Saint-Aubin\u003C/a> — croissants, baguettes \u003Cstrong>traditions\u003C/strong>, chocolatines and more\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"wine-shops\">Wine shops\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930\">l’envie du sud\u003C/a> — amazing selection of wines and other spirits, excellent advice from the staff\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952\">enoteca\u003C/a> — smaller selection but more beers and great advice from the staff as well\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"other-delights\">Other delights\u003C/h2>\n\u003Ch3 id=\"ice-creams\">Ice creams\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450\">Forno gusto\u003C/a> — only in the summer\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540\">Moustache\u003C/a> — lots of flavours\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cheese-shop\">Cheese shop\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://xavier.fr/\">Xavier\u003C/a> — one of the \u003Cstrong>best of the country\u003C/strong>, two shops in Toulouse, including one at Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490\">Massembea\u003C/a> — a serious contender in Toulouse (weird hours)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"delicatessen\">Delicatessen\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"http://cafe-bacquie.com/\">Café Bacquié\u003C/a> — stock up on fine foods, coffees, teas and other great quality products\u003C/li>\n\u003C/ul>",{"headings":498,"imagePaths":535,"frontmatter":536},[499,502,505,508,511,514,517,520,523,526,529,532],{"depth":150,"slug":500,"text":501},"restaurants","Restaurants",{"depth":154,"slug":503,"text":504},"french-cuisine","French cuisine",{"depth":154,"slug":506,"text":507},"korean","Korean",{"depth":154,"slug":509,"text":510},"japanese","Japanese",{"depth":150,"slug":512,"text":513},"drinks-and-snacks","Drinks and snacks",{"depth":154,"slug":515,"text":516},"bars","Bars",{"depth":154,"slug":518,"text":519},"cafés--tea-rooms","Cafés & tea rooms",{"depth":154,"slug":521,"text":522},"wine-shops","Wine shops",{"depth":150,"slug":524,"text":525},"other-delights","Other delights",{"depth":154,"slug":527,"text":528},"ice-creams","Ice creams",{"depth":154,"slug":530,"text":531},"cheese-shop","Cheese shop",{"depth":154,"slug":533,"text":534},"delicatessen","Delicatessen",[],{"title":487,"subtitle":488,"lang":68,"slug":484,"excerpt":537,"tags":538,"type":435,"createdAt":223},"Gonna have to trust me on this ¯\\_(ツ)_/¯",[490],"en-visited-links",{"id":539,"data":541,"body":438,"filePath":545,"digest":546,"rendered":547},{"title":542,"subtitle":209,"lang":68,"tags":543,"type":435,"slug":539,"createdAt":544,"draft":72},"Visited links and visuel aid",[18],["Date","2023-06-06T18:34:00.000Z"],"src/content/fragments/en/visited-links.md","cb7c11c12c25067e",{"html":548,"metadata":549},"\u003Cp>\u003Ca href=\"/en/snippets\">Go back to available snippets\u003C/a>\u003C/p>",{"headings":550,"imagePaths":551,"frontmatter":552},[],[],{"title":542,"subtitle":209,"lang":68,"draft":72,"slug":539,"excerpt":553,"tags":554,"type":435,"createdAt":555},"Petit hack CSS",[18],"2023-06-06T18:34:00.000Z","array-vs-array",{"id":556,"data":558,"body":564,"filePath":565,"digest":566,"rendered":567},{"title":559,"subtitle":560,"lang":16,"tags":561,"type":427,"slug":556,"createdAt":563,"draft":72},"Filtrer un array avec un autre array","En cours de traduction.",[562],"nuxt.js",["Date","2022-06-08T14:24:06.000Z"],"[Voir les fragments disponibles](/fragments)","src/content/fragments/fr/array-vs-array.md","7321d444177c3841",{"html":568,"metadata":569},"\u003Cp>\u003Ca href=\"/fragments\">Voir les fragments disponibles\u003C/a>\u003C/p>",{"headings":570,"imagePaths":571,"frontmatter":572},[],[],{"title":559,"subtitle":560,"lang":16,"draft":72,"slug":556,"createdAt":170,"excerpt":560,"tags":573,"type":427},[562],"toulouse-fun",{"id":574,"data":576,"body":564,"filePath":579,"digest":580,"rendered":581},{"title":487,"subtitle":560,"lang":16,"tags":577,"type":427,"slug":574,"createdAt":578,"draft":72},[490],["Date","2022-06-22T15:34:45.000Z"],"src/content/fragments/fr/toulouse-fun.md","a0c25b438b34c05e",{"html":568,"metadata":582},{"headings":583,"imagePaths":584,"frontmatter":585},[],[],{"title":487,"subtitle":560,"lang":16,"draft":72,"slug":574,"createdAt":223,"excerpt":560,"tags":586,"type":427},[490],"en-acme-sh-tls-cert",{"id":587,"data":589,"body":595,"filePath":596,"digest":597,"rendered":598},{"title":590,"subtitle":591,"lang":68,"tags":592,"type":435,"slug":587,"createdAt":594},"Strong TLS certificates with acme.sh","384-bit of https",[593],"security",["Date","2022-06-08T14:24:06.000Z"],"## Disclaimer\n\nI'm, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs. \nThis is why I've switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nYou can learn (far) more by reading [this topic](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) and its linked resources.\n\n## Requirements\n\n### Installing acme.sh\n\nFor automation and ease of use purposes, I'm using [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# for using standalone mode, you might have to install as sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changing default authority\n\nBy default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let's Encrypt because according to acme.sh, they're the only ones offering ECC capabilities.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Using your DNS api\n\nIf available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports [a lot](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) of DNS providers.\n\n### Define an api key\n\nFollow the [docs](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) for your DNS provider, usually:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Issue the cert\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Using standalone mode\n\nIf you don't have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\n\nPort `80` must be free.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Examples\n\n### Multi domains standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domain DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Next steps\n\nThe ECC certificate alone will not grant you a high/perfect score.\n\n### TLS version\n\nLimit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a [5% compatibility gap](https://caniuse.com/?search=tls%201.) with 1.2).\n\n### HSTS\n\nUse the [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/) header.\n\n```\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Cipher suite\n\nUse recent and strong ciphers. This is where my knowledge hits its limit… I'm having a really hard time understanding what to use and why.\n\nI've based my initial choices of ciphers on [this list](https://tls.imirhil.fr/ciphers), cross referencing it with (older?) [browser compatibility](https://tls.imirhil.fr/suite).\n\nI then asked [Aeris](https://twitter.com/aeris22), the creator of [tls.imirhil.fr](https://tls.imirhil.fr), about it and he advised me to use the following:\n\n```\nECDHE+AES:ECDHE+CHACHA20\n```\n\nIn order to achieve a perfect score, we can be a little more restrictive with:\n\n```\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/en/acme-sh-tls-cert.md","41577e8aee884f85",{"html":599,"metadata":600},"\u003Ch2 id=\"disclaimer\">Disclaimer\u003C/h2>\n\u003Cp>I’m, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs.\u003Cbr>\nThis is why I’ve switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>You can learn (far) more by reading \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">this topic\u003C/a> and its linked resources.\u003C/p>\n\u003Ch2 id=\"requirements\">Requirements\u003C/h2>\n\u003Ch3 id=\"installing-acmesh\">Installing acme.sh\u003C/h3>\n\u003Cp>For automation and ease of use purposes, I’m using \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># for using standalone mode, you might have to install as sudo\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">curl\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> https://get.acme.sh\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#B392F0\"> sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -s\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> email=mail@domain.tld\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"changing-default-authority\">Changing default authority\u003C/h3>\n\u003Cp>By default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let’s Encrypt because according to acme.sh, they’re the only ones offering ECC capabilities.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --set-default-ca\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --server\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> letsencrypt\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"using-your-dns-api\">Using your DNS api\u003C/h2>\n\u003Cp>If available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">a lot\u003C/a> of DNS providers.\u003C/p>\n\u003Ch3 id=\"define-an-api-key\">Define an api key\u003C/h3>\n\u003Cp>Follow the \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">docs\u003C/a> for your DNS provider, usually:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">export\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> PROVIDER_Key\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"YOUR_API_KEY\"\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"issue-the-cert\">Issue the cert\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"using-standalone-mode\">Using standalone mode\u003C/h2>\n\u003Cp>If you don’t have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\u003C/p>\n\u003Cp>Port \u003Ccode>80\u003C/code> must be free.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"examples\">Examples\u003C/h2>\n\u003Ch3 id=\"multi-domains-standalone\">Multi domains standalone\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> www.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> subdomain.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"wildcard-domain-dns\">Wildcard domain DNS\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '*.domain.tld'\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"next-steps\">Next steps\u003C/h2>\n\u003Cp>The ECC certificate alone will not grant you a high/perfect score.\u003C/p>\n\u003Ch3 id=\"tls-version\">TLS version\u003C/h3>\n\u003Cp>Limit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a \u003Ca href=\"https://caniuse.com/?search=tls%201.\">5% compatibility gap\u003C/a> with 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Use the \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a> header.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>Strict-Transport-Security: max-age=31536000; includeSubDomains\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"cipher-suite\">Cipher suite\u003C/h3>\n\u003Cp>Use recent and strong ciphers. This is where my knowledge hits its limit… I’m having a really hard time understanding what to use and why.\u003C/p>\n\u003Cp>I’ve based my initial choices of ciphers on \u003Ca href=\"https://tls.imirhil.fr/ciphers\">this list\u003C/a>, cross referencing it with (older?) \u003Ca href=\"https://tls.imirhil.fr/suite\">browser compatibility\u003C/a>.\u003C/p>\n\u003Cp>I then asked \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, the creator of \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, about it and he advised me to use the following:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>In order to achieve a perfect score, we can be a little more restrictive with:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES256:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":601,"imagePaths":647,"frontmatter":648},[602,605,608,611,614,617,620,623,626,629,632,635,638,641,644],{"depth":150,"slug":603,"text":604},"disclaimer","Disclaimer",{"depth":150,"slug":606,"text":607},"requirements","Requirements",{"depth":154,"slug":609,"text":610},"installing-acmesh","Installing acme.sh",{"depth":154,"slug":612,"text":613},"changing-default-authority","Changing default authority",{"depth":150,"slug":615,"text":616},"using-your-dns-api","Using your DNS api",{"depth":154,"slug":618,"text":619},"define-an-api-key","Define an api key",{"depth":154,"slug":621,"text":622},"issue-the-cert","Issue the cert",{"depth":150,"slug":624,"text":625},"using-standalone-mode","Using standalone mode",{"depth":150,"slug":627,"text":628},"examples","Examples",{"depth":154,"slug":630,"text":631},"multi-domains-standalone","Multi domains standalone",{"depth":154,"slug":633,"text":634},"wildcard-domain-dns","Wildcard domain DNS",{"depth":150,"slug":636,"text":637},"next-steps","Next steps",{"depth":154,"slug":639,"text":640},"tls-version","TLS version",{"depth":154,"slug":642,"text":643},"hsts","HSTS",{"depth":154,"slug":645,"text":646},"cipher-suite","Cipher suite",[],{"title":590,"subtitle":591,"lang":68,"slug":587,"createdAt":170,"excerpt":649,"tags":650,"type":435},"Real cert have curves.",[593],"acme-sh-tls-cert",{"id":651,"data":653,"body":659,"filePath":660,"digest":661,"rendered":662},{"title":654,"subtitle":655,"lang":16,"tags":656,"type":427,"slug":651,"createdAt":658},"Certificates TLS robustes avec acme.sh","384-bit de https",[657],"sécurité",["Date","2022-06-08T14:24:06.000Z"],"## Attention\n\nJe ne suis pas du tout un expert en sécurité. J'aime juste les trucs nouveaux et stylés des internets. \nC'est pourquoi j'ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J'ai maintenant un joli 100/100 sur [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nVous pouvez en apprendre (beaucoup) plus [ici](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) et sur les liens cités (en anglais).\n\n## Prérequis\n\n### Installer acme.sh\n\nPour des raisons de simplicité et d'automatisation, j'utilise [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changer l'authorité par défaut\n\nPar défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let's Encrypt car, d'après acme.sh, ils sont les seuls à proposer des certificats ECC.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Utiliser l'api DNS\n\nSi vous en avez la possibilité, la façon la plus simple de générer un certificat est via l'api de votre fournisseur DNS. acme.sh supporte [énormément](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) de fournisseurs DNS.\n\n### Definir la clé api\n\nSuivez la [documentation](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) pour votre fournisseur DNS, généralement:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Émettre le certificat\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Utiliser le mode standalone\n\nSi vous n'avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s'occupe de toutes les vérifications.\n\nLe port `80` doit être disponible.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Exemples\n\n### Multi domaines standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domaine DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Étapes supplémentaires\n\nLe certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\n\n### Version TLS\n\nLimiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu [la différence de compatibilité de 5%](https://caniuse.com/?search=tls%201.) avec 1.2).\n\n### HSTS\n\nUtiliser le header [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/).\n\n```\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Suite cryptographique\n\nUtiliser une suite cryptographique récente et robuste. C'est ici que mes connaissances deviennent limitées… J'ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\n\nJ'avais basé ma première suite sur [cette liste](https://tls.imirhil.fr/ciphers), en la comparant avec celle de la compatibilité (d'anciens ?) [navigateurs](https://tls.imirhil.fr/suite).\n\nJ'ai ensuite demandé à [Aeris](https://twitter.com/aeris22), le créateur de [tls.imirhil.fr](https://tls.imirhil.fr), ses conseils sur cette suite. Il m'a recommandé d'utiliser :\n\n```\nECDHE+AES:ECDHE+CHACHA20\n```\n\nAfin d'atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\n\n```\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/fr/acme-sh-tls-cert.md","82e6d91747c28ea5",{"html":663,"metadata":664},"\u003Ch2 id=\"attention\">Attention\u003C/h2>\n\u003Cp>Je ne suis pas du tout un expert en sécurité. J’aime juste les trucs nouveaux et stylés des internets.\u003Cbr>\nC’est pourquoi j’ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J’ai maintenant un joli 100/100 sur \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>Vous pouvez en apprendre (beaucoup) plus \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">ici\u003C/a> et sur les liens cités (en anglais).\u003C/p>\n\u003Ch2 id=\"prérequis\">Prérequis\u003C/h2>\n\u003Ch3 id=\"installer-acmesh\">Installer acme.sh\u003C/h3>\n\u003Cp>Pour des raisons de simplicité et d’automatisation, j’utilise \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">curl\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> https://get.acme.sh\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#B392F0\"> sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -s\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> email=mail@domain.tld\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"changer-lauthorité-par-défaut\">Changer l’authorité par défaut\u003C/h3>\n\u003Cp>Par défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let’s Encrypt car, d’après acme.sh, ils sont les seuls à proposer des certificats ECC.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --set-default-ca\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --server\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> letsencrypt\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"utiliser-lapi-dns\">Utiliser l’api DNS\u003C/h2>\n\u003Cp>Si vous en avez la possibilité, la façon la plus simple de générer un certificat est via l’api de votre fournisseur DNS. acme.sh supporte \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">énormément\u003C/a> de fournisseurs DNS.\u003C/p>\n\u003Ch3 id=\"definir-la-clé-api\">Definir la clé api\u003C/h3>\n\u003Cp>Suivez la \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">documentation\u003C/a> pour votre fournisseur DNS, généralement:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">export\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> PROVIDER_Key\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"YOUR_API_KEY\"\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"émettre-le-certificat\">Émettre le certificat\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"utiliser-le-mode-standalone\">Utiliser le mode standalone\u003C/h2>\n\u003Cp>Si vous n’avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s’occupe de toutes les vérifications.\u003C/p>\n\u003Cp>Le port \u003Ccode>80\u003C/code> doit être disponible.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"exemples\">Exemples\u003C/h2>\n\u003Ch3 id=\"multi-domaines-standalone\">Multi domaines standalone\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --standalone\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> www.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> subdomain.domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"wildcard-domaine-dns\">Wildcard domaine DNS\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">acme.sh\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --issue\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> domain.tld\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '*.domain.tld'\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --dns\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> dns_provider\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --keylength\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"étapes-supplémentaires\">Étapes supplémentaires\u003C/h2>\n\u003Cp>Le certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\u003C/p>\n\u003Ch3 id=\"version-tls\">Version TLS\u003C/h3>\n\u003Cp>Limiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu \u003Ca href=\"https://caniuse.com/?search=tls%201.\">la différence de compatibilité de 5%\u003C/a> avec 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Utiliser le header \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a>.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>Strict-Transport-Security: max-age=31536000; includeSubDomains\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"suite-cryptographique\">Suite cryptographique\u003C/h3>\n\u003Cp>Utiliser une suite cryptographique récente et robuste. C’est ici que mes connaissances deviennent limitées… J’ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\u003C/p>\n\u003Cp>J’avais basé ma première suite sur \u003Ca href=\"https://tls.imirhil.fr/ciphers\">cette liste\u003C/a>, en la comparant avec celle de la compatibilité (d’anciens ?) \u003Ca href=\"https://tls.imirhil.fr/suite\">navigateurs\u003C/a>.\u003C/p>\n\u003Cp>J’ai ensuite demandé à \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, le créateur de \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, ses conseils sur cette suite. Il m’a recommandé d’utiliser :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Afin d’atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES256:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":665,"imagePaths":709,"frontmatter":710},[666,669,672,675,678,681,684,687,690,693,696,699,702,705,706],{"depth":150,"slug":667,"text":668},"attention","Attention",{"depth":150,"slug":670,"text":671},"prérequis","Prérequis",{"depth":154,"slug":673,"text":674},"installer-acmesh","Installer acme.sh",{"depth":154,"slug":676,"text":677},"changer-lauthorité-par-défaut","Changer l’authorité par défaut",{"depth":150,"slug":679,"text":680},"utiliser-lapi-dns","Utiliser l’api DNS",{"depth":154,"slug":682,"text":683},"definir-la-clé-api","Definir la clé api",{"depth":154,"slug":685,"text":686},"émettre-le-certificat","Émettre le certificat",{"depth":150,"slug":688,"text":689},"utiliser-le-mode-standalone","Utiliser le mode standalone",{"depth":150,"slug":691,"text":692},"exemples","Exemples",{"depth":154,"slug":694,"text":695},"multi-domaines-standalone","Multi domaines standalone",{"depth":154,"slug":697,"text":698},"wildcard-domaine-dns","Wildcard domaine DNS",{"depth":150,"slug":700,"text":701},"étapes-supplémentaires","Étapes supplémentaires",{"depth":154,"slug":703,"text":704},"version-tls","Version TLS",{"depth":154,"slug":642,"text":643},{"depth":154,"slug":707,"text":708},"suite-cryptographique","Suite cryptographique",[],{"title":654,"subtitle":655,"lang":16,"slug":651,"createdAt":170,"excerpt":711,"tags":712,"type":427},"La sécurité avec des courbes.",[657],"visited-links",{"id":713,"data":715,"body":721,"filePath":722,"digest":723,"rendered":724},{"title":716,"subtitle":717,"lang":16,"tags":718,"type":435,"slug":713,"createdAt":719,"draft":720},"Liens visités et indication visuelle","Comment différencier les liens déjà cliqués",[18],["Date","2023-06-06T18:34:00.000Z"],false,"## La théorie\n\nIl est possible sur le web d'appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu'un lien visité est violet.\n\nGénéralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L'information qu'un lien a déjà été visité ne semble pas indispensable à la navigation. C'est sûrement vrai, mais personnellement, je suis assez content d'avoir un rappel des pages que j'ai déjà consultées lorsque je navigue.\n\nUne information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J'ai alors cherché un moyen d'ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n'est certainement pas idéale, elle se rapproche plus d'une expérience, à priori inoffensive pour l'internaute.\n\n## La spécification\n\nQuand je me suis intéressé à ce qu'il était possible de faire avec les liens déjà visités, j'ai découvert qu'extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu'il était possible de récupérer l'historique de navigation d'un utilisateur grâce aux styles des liens visités. Le sélecteur `:visited` a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. [Plus d'informations dans cet article.](https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector)\n\n## La pratique\n\nQue faire alors, en terme de style, quand on ne peut changer que des couleurs ?\n\nD'après MDN, les propriétés suivantes sont modifiables :\n\n- `color`\n- `background-color`\n- `border-color` (et les propriétés détaillées associées),\n- `column-rule-color`\n- `outline-color`\n- `text-decoration-color`\n- `text-emphasis-color`\n- Les composantes de couleur liées aux attributs SVG `fill` et `stroke`.\n\nChanger la couleur d'un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\n\nEn revanche, il est possible de \" masquer \" un élément en modifiant sa couleur pour qu'elle corresponde à la couleur du fond de la page ou de l'élément parent. On pourrait ainsi imaginer masquer une `border` ou un `outline`.\n\nJ'ai personnellement choisi de faire différemment. J'ai décidé d'utiliser un pseudo-élément `::before` sur l'état non visité du lien puis de le masquer quand celui-ci devient visité.\n\n### Le code\n\n```css\na {\n\tposition: relative;\n\ttext-decoration: none;\n}\na::before {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 0;\n\tinline-size: 2px;\n\tblock-size: 2px;\n\tborder-radius: 4px;\n\ttransform: translate(-6px, 0);\n\tbackground-color: grey;\n}\na:visited::before {\n\tbackground-color: white;\n}\n```\n\nCes règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\n\n### Accessibilité\n\nOn pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété `content` mais les lecteurs d'écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d'écrans annoncent déjà si un lien est visité avant de lire son intitulé.\n\n## Aller plus loin\n\nAfin de pousser l'expérience un peu plus loin, j'ai tenté d'utiliser des éléments plus explicites pour signifier l'état visité du lien. Bien qu'encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\n\nL'idée est d'avoir un `::before` et un `::after`, chacun contenant une icône en base 64 blanche en tant qu'image de fond. Quand le lien est non visité, le `::before` contient un fond coloré qui fait apparaître l'icône. Quand le lien passe en visité, le fond du `::before` devient blanc et celui du `::after` devient coloré, ce qui masque la première icône et affiche la deuxième.\n\nIl est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l'une sur l'autre.\n\n[Voir la démo sur codepen.](https://codepen.io/narduin/pen/VwVwmrO)","src/content/fragments/fr/visited-links.md","52385f4f8bc864b2",{"html":725,"metadata":726},"\u003Ch2 id=\"la-théorie\">La théorie\u003C/h2>\n\u003Cp>Il est possible sur le web d’appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu’un lien visité est violet.\u003C/p>\n\u003Cp>Généralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L’information qu’un lien a déjà été visité ne semble pas indispensable à la navigation. C’est sûrement vrai, mais personnellement, je suis assez content d’avoir un rappel des pages que j’ai déjà consultées lorsque je navigue.\u003C/p>\n\u003Cp>Une information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J’ai alors cherché un moyen d’ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n’est certainement pas idéale, elle se rapproche plus d’une expérience, à priori inoffensive pour l’internaute.\u003C/p>\n\u003Ch2 id=\"la-spécification\">La spécification\u003C/h2>\n\u003Cp>Quand je me suis intéressé à ce qu’il était possible de faire avec les liens déjà visités, j’ai découvert qu’extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu’il était possible de récupérer l’historique de navigation d’un utilisateur grâce aux styles des liens visités. Le sélecteur \u003Ccode>:visited\u003C/code> a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector\">Plus d’informations dans cet article.\u003C/a>\u003C/p>\n\u003Ch2 id=\"la-pratique\">La pratique\u003C/h2>\n\u003Cp>Que faire alors, en terme de style, quand on ne peut changer que des couleurs ?\u003C/p>\n\u003Cp>D’après MDN, les propriétés suivantes sont modifiables :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>background-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>border-color\u003C/code> (et les propriétés détaillées associées),\u003C/li>\n\u003Cli>\u003Ccode>column-rule-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>outline-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-decoration-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-emphasis-color\u003C/code>\u003C/li>\n\u003Cli>Les composantes de couleur liées aux attributs SVG \u003Ccode>fill\u003C/code> et \u003Ccode>stroke\u003C/code>.\u003C/li>\n\u003C/ul>\n\u003Cp>Changer la couleur d’un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\u003C/p>\n\u003Cp>En revanche, il est possible de ” masquer ” un élément en modifiant sa couleur pour qu’elle corresponde à la couleur du fond de la page ou de l’élément parent. On pourrait ainsi imaginer masquer une \u003Ccode>border\u003C/code> ou un \u003Ccode>outline\u003C/code>.\u003C/p>\n\u003Cp>J’ai personnellement choisi de faire différemment. J’ai décidé d’utiliser un pseudo-élément \u003Ccode>::before\u003C/code> sur l’état non visité du lien puis de le masquer quand celui-ci devient visité.\u003C/p>\n\u003Ch3 id=\"le-code\">Le code\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">a\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">relative\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttext-decoration\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">a\u003C/span>\u003Cspan style=\"color:#B392F0\">::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttop\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tleft\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tinline-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tblock-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder-radius\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">4\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translate\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-6\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">grey\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">a\u003C/span>\u003Cspan style=\"color:#B392F0\">:visited::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">white\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Ces règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\u003C/p>\n\u003Ch3 id=\"accessibilité\">Accessibilité\u003C/h3>\n\u003Cp>On pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété \u003Ccode>content\u003C/code> mais les lecteurs d’écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d’écrans annoncent déjà si un lien est visité avant de lire son intitulé.\u003C/p>\n\u003Ch2 id=\"aller-plus-loin\">Aller plus loin\u003C/h2>\n\u003Cp>Afin de pousser l’expérience un peu plus loin, j’ai tenté d’utiliser des éléments plus explicites pour signifier l’état visité du lien. Bien qu’encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\u003C/p>\n\u003Cp>L’idée est d’avoir un \u003Ccode>::before\u003C/code> et un \u003Ccode>::after\u003C/code>, chacun contenant une icône en base 64 blanche en tant qu’image de fond. Quand le lien est non visité, le \u003Ccode>::before\u003C/code> contient un fond coloré qui fait apparaître l’icône. Quand le lien passe en visité, le fond du \u003Ccode>::before\u003C/code> devient blanc et celui du \u003Ccode>::after\u003C/code> devient coloré, ce qui masque la première icône et affiche la deuxième.\u003C/p>\n\u003Cp>Il est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l’une sur l’autre.\u003C/p>\n\u003Cp>\u003Ca href=\"https://codepen.io/narduin/pen/VwVwmrO\">Voir la démo sur codepen.\u003C/a>\u003C/p>",{"headings":727,"imagePaths":745,"frontmatter":746},[728,731,734,737,740,742],{"depth":150,"slug":729,"text":730},"la-théorie","La théorie",{"depth":150,"slug":732,"text":733},"la-spécification","La spécification",{"depth":150,"slug":735,"text":736},"la-pratique","La pratique",{"depth":154,"slug":738,"text":739},"le-code","Le code",{"depth":154,"slug":32,"text":741},"Accessibilité",{"depth":150,"slug":743,"text":744},"aller-plus-loin","Aller plus loin",[],{"title":716,"subtitle":717,"lang":16,"draft":720,"slug":713,"excerpt":553,"tags":747,"type":435,"createdAt":555},[18],"en-buttons",{"id":748,"data":750,"body":755,"filePath":756,"digest":757,"rendered":758},{"title":751,"subtitle":752,"lang":68,"tags":753,"type":435,"slug":748,"createdAt":754,"code":72,"draft":72},"Buttons hover","Simple, but nice.",[434],["Date","2020-10-08T09:00:00.000Z"],"## General rules\n\nAll the buttons use these styles as a “reset”:\n\n> Don't forget to prefix if necessary!\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Add an icon\n\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('~assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double shutter down\n\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Animated gradient\n\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Non destructive scale\n\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/en/buttons.md","ea9a5513a5a4cef4",{"html":759,"metadata":760},"\u003Ch2 id=\"general-rules\">General rules\u003C/h2>\n\u003Cp>All the buttons use these styles as a “reset”:\u003C/p>\n\u003Cblockquote>\n\u003Cp>Don’t forget to prefix if necessary!\u003C/p>\n\u003C/blockquote>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tmargin\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">20\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tpadding\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">12\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 26\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">relative\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tdisplay\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">inline-block\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\toverflow\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hidden\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tfont-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">20\u003C/span>\u003Cspan style=\"color:#F97583\">rem\u003C/span>\u003Cspan style=\"color:#E1E4E8\">; \u003C/span>\u003Cspan style=\"color:#6A737D\">/* 20px */\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tline-height\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">1.6\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttext-align\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">center\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttext-decoration\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tfont-weight\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">bold\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcursor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">pointer\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder-radius\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t-moz-appearance\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t-webkit-appearance\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">none\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">white\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hotpink\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: background-color \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"add-an-icon\">Add an icon\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hotpink\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">url\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'~assets/svg/arrow-right-white.svg'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">20\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttop\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tright\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translate\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">40\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">-50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">ease\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:hover\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:focus\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">darkorchid\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:hover::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:focus::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translate\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-10\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">-50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon\u003C/span>\u003Cspan style=\"color:#F97583\"> >\u003C/span>\u003Cspan style=\"color:#85E89D\"> span\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tdisplay\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">inline-block\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\theight\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:hover\u003C/span>\u003Cspan style=\"color:#F97583\"> >\u003C/span>\u003Cspan style=\"color:#85E89D\"> span\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-icon:focus\u003C/span>\u003Cspan style=\"color:#F97583\"> >\u003C/span>\u003Cspan style=\"color:#85E89D\"> span\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translateX\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-10\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"double-shutter-down\">Double shutter down\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> solid\u003C/span>\u003Cspan style=\"color:#79B8FF\"> #10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">#10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">transparent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">color\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">white\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">hotpink\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">darkorchid\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\theight\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbottom\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tleft\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tz-index\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">-1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition-timing-function\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition-timing-function\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">cubic-bezier\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">0.75\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.125\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:focus::before\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:focus::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">translateY\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:hover::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-rideau:focus::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition-delay\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.175\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"animated-gradient\">Animated gradient\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-gradient\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">linear-gradient\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">-45\u003C/span>\u003Cspan style=\"color:#F97583\">deg\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#ee7752\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#e73c7e\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#23a6d5\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">#23d5ab\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-size\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">400\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 400\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tanimation\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: GradientReverse \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.5\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:#79B8FF\"> normal\u003C/span>\u003Cspan style=\"color:#79B8FF\"> forwards\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-gradient:hover\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-gradient:focus\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tanimation\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: Gradient \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.5\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:#79B8FF\"> normal\u003C/span>\u003Cspan style=\"color:#79B8FF\"> forwards\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">@keyframes\u003C/span>\u003Cspan style=\"color:#FFAB70\"> Gradient\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t0%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t100%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">@keyframes\u003C/span>\u003Cspan style=\"color:#FFAB70\"> GradientReverse\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t0%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">\t100%\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\t\tbackground-position\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"non-destructive-scale\">Non destructive scale\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\toverflow\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">visible\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcolor\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">#10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbackground-color\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">transparent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tcontent\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tposition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">absolute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttop\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tleft\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tbottom\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\twidth\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#F97583\">%\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#79B8FF\"> solid\u003C/span>\u003Cspan style=\"color:#79B8FF\"> #10113a\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\tborder-radius\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#F97583\">px\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransition\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: transform \u003C/span>\u003Cspan style=\"color:#79B8FF\">0.3\u003C/span>\u003Cspan style=\"color:#F97583\">s\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ease\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale:hover::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">.btn-scale:focus::after\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">\ttransform\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">scale\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">1.1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":761,"imagePaths":777,"frontmatter":778},[762,765,768,771,774],{"depth":150,"slug":763,"text":764},"general-rules","General rules",{"depth":150,"slug":766,"text":767},"add-an-icon","Add an icon",{"depth":150,"slug":769,"text":770},"double-shutter-down","Double shutter down",{"depth":150,"slug":772,"text":773},"animated-gradient","Animated gradient",{"depth":150,"slug":775,"text":776},"non-destructive-scale","Non destructive scale",[],{"title":751,"subtitle":752,"lang":68,"slug":748,"draft":72,"excerpt":779,"tags":780,"code":72,"type":435,"createdAt":781},"Easy to grab and use hover effects.",[434],"2020-10-08T09:00:00.000Z","en-array-vs-array",{"id":782,"data":784,"body":789,"filePath":790,"digest":791,"rendered":792},{"title":785,"subtitle":786,"lang":68,"tags":787,"type":435,"slug":782,"createdAt":788},"Filter an array against another array","Array vs Array.",[562],["Date","2022-06-08T14:24:06.000Z"],"## Context\n\nFor a project, I had to come up with a way to filter an array of objects based on another array of strings.\n\nIn other words, I needed to include every object which `user` property was found in the second array.\n\nHere is an example:\n\n```javascript\nconst skills = [\n\t{\n\t\tname: 'Be awesome',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Great jokes',\n\t\tuser: 'Jacques'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Beatriz'\n\t}\n]\n\nconst selectedUsers = ['Jean', 'Beatriz']\n```\n\nI thought it would be pretty easy but I guess I'm not familiar enough with javascript 😬\n\n## My solution\n\nAfter a bit of thinking, I came up with the following statement:\n\n> I need to filter the skills based on which users are selected. So I need to loop over the `selectedUsers` array and filter the skills according to their `user` value.\n\nAfter a bit more trials and errors, this is the code I ended up using in a `computed property`:\n\n```javascript\n// index.vue\nconst filteredSkills = selectedUsers.map((user) => {\n\treturn skills.filter((skill) => {\n\t\treturn skill.user === user\n\t})\n})\n```\n\nI used `map()` in order to loop on the second array and used its string value to only include the corresponding skills with `filter()`.\n\nI'm pretty sure there is a better way to do it though…","src/content/fragments/en/array-vs-array.md","c63ba57b1049cf4c",{"html":793,"metadata":794},"\u003Ch2 id=\"context\">Context\u003C/h2>\n\u003Cp>For a project, I had to come up with a way to filter an array of objects based on another array of strings.\u003C/p>\n\u003Cp>In other words, I needed to include every object which \u003Ccode>user\u003C/code> property was found in the second array.\u003C/p>\n\u003Cp>Here is an example:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> skills\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Be awesome'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jean'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Great jokes'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jacques'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jean'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tname: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\tuser: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Beatriz'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> selectedUsers\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Jean'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Beatriz'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>I thought it would be pretty easy but I guess I’m not familiar enough with javascript 😬\u003C/p>\n\u003Ch2 id=\"my-solution\">My solution\u003C/h2>\n\u003Cp>After a bit of thinking, I came up with the following statement:\u003C/p>\n\u003Cblockquote>\n\u003Cp>I need to filter the skills based on which users are selected. So I need to loop over the \u003Ccode>selectedUsers\u003C/code> array and filter the skills according to their \u003Ccode>user\u003C/code> value.\u003C/p>\n\u003C/blockquote>\n\u003Cp>After a bit more trials and errors, this is the code I ended up using in a \u003Ccode>computed property\u003C/code>:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> filteredSkills\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> selectedUsers.\u003C/span>\u003Cspan style=\"color:#B392F0\">map\u003C/span>\u003Cspan style=\"color:#E1E4E8\">((\u003C/span>\u003Cspan style=\"color:#FFAB70\">user\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">=>\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">\treturn\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> skills.\u003C/span>\u003Cspan style=\"color:#B392F0\">filter\u003C/span>\u003Cspan style=\"color:#E1E4E8\">((\u003C/span>\u003Cspan style=\"color:#FFAB70\">skill\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">=>\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">\t\treturn\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> skill.user \u003C/span>\u003Cspan style=\"color:#F97583\">===\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> user\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t})\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">})\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>I used \u003Ccode>map()\u003C/code> in order to loop on the second array and used its string value to only include the corresponding skills with \u003Ccode>filter()\u003C/code>.\u003C/p>\n\u003Cp>I’m pretty sure there is a better way to do it though…\u003C/p>",{"headings":795,"imagePaths":802,"frontmatter":803},[796,799],{"depth":150,"slug":797,"text":798},"context","Context",{"depth":150,"slug":800,"text":801},"my-solution","My solution",[],{"title":785,"subtitle":786,"lang":68,"slug":782,"createdAt":170,"excerpt":804,"tags":805,"type":435},"My peak javascript",[562],"en-nuxt-graphql-static",{"id":806,"data":808,"body":814,"filePath":815,"digest":816,"rendered":817},{"title":809,"subtitle":810,"lang":68,"tags":811,"type":435,"slug":806,"createdAt":812,"updatedAt":813},"Static website and GraphQL queries with Nuxt.js","Graphql client is king.",[562],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## The problem\n\nI encountered a nasty bug while using static generation with Nuxt and [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (new tab)') client.\nI found [the issue](https://github.com/nuxt-community/apollo-module/issues/339 'Github issue on nuxt/apollo repository (new tab)') already reported on github.\n\nIt seems the module doesn't handle static generation correctly with `nuxt generate`.\n\nI could find request to my local API url after the static generation. Moreover, it also seemed like `\u003Cnuxt-link>` navigation was broken.\n\n## The solution 🙌\n\nFortunately, there is another Nuxt module that handles GraphQL requests!\n\n[Nuxt graphql request to the rescue!](https://github.com/gomah/nuxt-graphql-request)\n\n### The conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### The request\n\nThe best approach so far is to use `asyncData` in pages and `fetch` in components. Using `fetch` in pages does not work well at all with `nuxt generate`.\n\nI also install the `graphql-tag` package (only in `devDependencies`) to be able to import directly `.gql` files.\n\nQuery example:\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Inside a page\n\n```javascript\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n async asyncData({ $graphql }) {\n const data = await $graphql.default.request(homepageQuery)\n return { data }\n },\n}\n\u003C/script>\n```\n\n#### Inside a component\n\nIt is safer to wait until `fetch` has received a response before displaying anything. You can use `$fetchState` to be sure ([documentation](https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation on the fetch hook (new tab)')).\n\n```javascript\n// Header.vue\n\u003Ctemplate>\n \u003Cheader v-if=\"!$fetchState.pending\">\n …\n \u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n data() {\n return {\n data: {},\n }\n },\n async fetch() {\n try {\n const data = await this.$graphql.default.request(headerQuery)\n this.data = data\n } catch (error) {\n console.error(JSON.stringify(error, undefined, 2))\n }\n },\n}\n\u003C/script>\n```\n\n### Options\n\nTo pass options to the request, for example for a multilingual version with [nuxt/i18n](https://i18n.nuxtjs.org/) and/or a url parameter in a dynamic page:\n\n```javascript\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n async asyncData({ $graphql, app, params }) {\n const locale = app.i18n.localeProperties.iso\n const data = await $graphql.default.request(articleQuery, {\n code: locale,\n slug: params.slug,\n })\n return { data }\n },\n}\n\u003C/script>\n```","src/content/fragments/en/nuxt-graphql-static.md","181e8091294eb858",{"html":818,"metadata":819},"\u003Ch2 id=\"the-problem\">The problem\u003C/h2>\n\u003Cp>I encountered a nasty bug while using static generation with Nuxt and \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (new tab)\">nuxt apollo\u003C/a> client.\nI found \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Github issue on nuxt/apollo repository (new tab)\">the issue\u003C/a> already reported on github.\u003C/p>\n\u003Cp>It seems the module doesn’t handle static generation correctly with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I could find request to my local API url after the static generation. Moreover, it also seemed like \u003Ccode><nuxt-link>\u003C/code> navigation was broken.\u003C/p>\n\u003Ch2 id=\"the-solution\">The solution 🙌\u003C/h2>\n\u003Cp>Fortunately, there is another Nuxt module that handles GraphQL requests!\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\">Nuxt graphql request to the rescue!\u003C/a>\u003C/p>\n\u003Ch3 id=\"the-conf\">The conf\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// nuxt.config.js\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">buildModules\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\"> 'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">graphql\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> clients\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> default\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> endpoint: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> options: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> headers: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> authorization: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">},\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"the-request\">The request\u003C/h3>\n\u003Cp>The best approach so far is to use \u003Ccode>asyncData\u003C/code> in pages and \u003Ccode>fetch\u003C/code> in components. Using \u003Ccode>fetch\u003C/code> in pages does not work well at all with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I also install the \u003Ccode>graphql-tag\u003C/code> package (only in \u003Ccode>devDependencies\u003C/code>) to be able to import directly \u003Ccode>.gql\u003C/code> files.\u003C/p>\n\u003Cp>Query example:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"graphql\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># homepage.gql\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">query\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\thomepage\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\ttitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\tsubtitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\thero\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\tid\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\talt\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"inside-a-page\">Inside a page\u003C/h4>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import homepageQuery from '~/graphql/queries/singles/homepage'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(homepageQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"inside-a-component\">Inside a component\u003C/h4>\n\u003Cp>It is safer to wait until \u003Ccode>fetch\u003C/code> has received a response before displaying anything. You can use \u003Ccode>$fetchState\u003C/code> to be sure (\u003Ca href=\"https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation on the fetch hook (new tab)\">documentation\u003C/a>).\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// Header.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> <\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#B392F0\"> v-if\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"!$fetchState.pending\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> …\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> </\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import headerQuery from '~/graphql/queries/singles/header'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">fetch\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> try {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> data\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.$graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(headerQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> data\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> } catch (error) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> console.\u003C/span>\u003Cspan style=\"color:#B392F0\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(JSON.stringify(\u003C/span>\u003Cspan style=\"color:#FFAB70\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">undefined\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, 2))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"options\">Options\u003C/h3>\n\u003Cp>To pass options to the request, for example for a multilingual version with \u003Ca href=\"https://i18n.nuxtjs.org/\">nuxt/i18n\u003C/a> and/or a url parameter in a dynamic page:\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// _slug.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import articleQuery from '~/graphql/queries/articles'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql, app, params }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const locale \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> app.i18n.localeProperties.iso\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(articleQuery, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> code: locale,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> slug: params.slug,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> })\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":820,"imagePaths":843,"frontmatter":844},[821,824,827,830,833,837,840],{"depth":150,"slug":822,"text":823},"the-problem","The problem",{"depth":150,"slug":825,"text":826},"the-solution","The solution 🙌",{"depth":154,"slug":828,"text":829},"the-conf","The conf",{"depth":154,"slug":831,"text":832},"the-request","The request",{"depth":834,"slug":835,"text":836},4,"inside-a-page","Inside a page",{"depth":834,"slug":838,"text":839},"inside-a-component","Inside a component",{"depth":154,"slug":841,"text":842},"options","Options",[],{"title":809,"subtitle":810,"lang":68,"slug":806,"createdAt":170,"updatedAt":845,"excerpt":846,"tags":847,"type":435},"2022-09-08T13:43:33.000Z","When the most used gql module doesn't work…",[562],"nuxt-graphql-static",{"id":848,"data":850,"body":856,"filePath":857,"digest":858,"rendered":859},{"title":851,"subtitle":852,"lang":16,"tags":853,"type":427,"slug":848,"createdAt":854,"updatedAt":855},"Site statique et requêtes GraphQL avec Nuxt.js","Le client graphql est roi.",[562],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## Le problème\n\nJe me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (nouvel onglet)').\nAprès quelques recherches, voici [le bug constaté par quelqu'un d'autre](https://github.com/nuxt-community/apollo-module/issues/339 'Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)') sur github.\n\nIl semblerait que le module en l'état ne gère pas correctement la génération statique avec `nuxt generate`.\n\nJe trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les `\u003Cnuxt-link>` ne fonctionnait pas.\n\n## La solution 🙌\n\nHeureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\n\n[Nuxt graphql request à la rescousse !](https://github.com/gomah/nuxt-graphql-request 'Dépôt github du module (nouvel onglet)')\n\n### La conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### La requête\n\nLa meilleure méthode à ce jour est d'utiliser `asyncData` dans les pages et `fetch` dans les composants. Utiliser `fetch` dans les pages ne fonctionne pas bien du tout avec `nuxt generate`.\n\nJ'installe également le paquet `graphql-tag` (uniquement en `devDependencies`) afin de pouvoir importer directement des fichiers `.gql`\n\nExemple de fichier :\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Dans une page\n\n```javascript\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n async asyncData({ $graphql }) {\n const data = await $graphql.default.request(homepageQuery)\n return { data }\n },\n}\n\u003C/script>\n```\n\n#### Dans un composant\n\nIl est plus prudent d'attendre que `fetch` ait reçu une réponse avant d'afficher quoi que ce soit. On peut utiliser `$fetchState` afin d'être tranquille ([documentation](https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation sur la méthode fetch (nouvel onglet)')).\n\n```javascript\n// Header.vue\n\u003Ctemplate>\n \u003Cheader v-if=\"!$fetchState.pending\">\n …\n \u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n data() {\n return {\n data: {},\n }\n },\n async fetch() {\n try {\n const data = await this.$graphql.default.request(headerQuery)\n this.data = data\n } catch (error) {\n console.error(JSON.stringify(error, undefined, 2))\n }\n },\n}\n\u003C/script>\n```\n\n### Les options\n\nPour passer des options à la requête, par exemple pour une version multilingue avec [nuxt/i18n](https://i18n.nuxtjs.org/ 'Documentation de nuxt i18n (nouvel onglet)') et/ou un paramètre d'url dans le cadre d'une page dynamique :\n\n```javascript\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n async asyncData({ $graphql, app, params }) {\n const locale = app.i18n.localeProperties.iso\n const data = await $graphql.default.request(articleQuery, {\n code: locale,\n slug: params.slug,\n })\n return { data }\n },\n}\n\u003C/script>\n```","src/content/fragments/fr/nuxt-graphql-static.md","73b6cc6b4fed04f5",{"html":860,"metadata":861},"\u003Ch2 id=\"le-problème\">Le problème\u003C/h2>\n\u003Cp>Je me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (nouvel onglet)\">nuxt apollo\u003C/a>.\nAprès quelques recherches, voici \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)\">le bug constaté par quelqu’un d’autre\u003C/a> sur github.\u003C/p>\n\u003Cp>Il semblerait que le module en l’état ne gère pas correctement la génération statique avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>Je trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les \u003Ccode><nuxt-link>\u003C/code> ne fonctionnait pas.\u003C/p>\n\u003Ch2 id=\"la-solution\">La solution 🙌\u003C/h2>\n\u003Cp>Heureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\" title=\"Dépôt github du module (nouvel onglet)\">Nuxt graphql request à la rescousse !\u003C/a>\u003C/p>\n\u003Ch3 id=\"la-conf\">La conf\u003C/h3>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// nuxt.config.js\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">buildModules\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\"> 'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">graphql\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> clients\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> default\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> endpoint: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> options: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> headers: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> authorization: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">},\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"la-requête\">La requête\u003C/h3>\n\u003Cp>La meilleure méthode à ce jour est d’utiliser \u003Ccode>asyncData\u003C/code> dans les pages et \u003Ccode>fetch\u003C/code> dans les composants. Utiliser \u003Ccode>fetch\u003C/code> dans les pages ne fonctionne pas bien du tout avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>J’installe également le paquet \u003Ccode>graphql-tag\u003C/code> (uniquement en \u003Ccode>devDependencies\u003C/code>) afin de pouvoir importer directement des fichiers \u003Ccode>.gql\u003C/code>\u003C/p>\n\u003Cp>Exemple de fichier :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"graphql\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># homepage.gql\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">query\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\thomepage\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\ttitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\tsubtitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\thero\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\tid\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">\t\t\talt\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"dans-une-page\">Dans une page\u003C/h4>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import homepageQuery from '~/graphql/queries/singles/homepage'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(homepageQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"dans-un-composant\">Dans un composant\u003C/h4>\n\u003Cp>Il est plus prudent d’attendre que \u003Ccode>fetch\u003C/code> ait reçu une réponse avant d’afficher quoi que ce soit. On peut utiliser \u003Ccode>$fetchState\u003C/code> afin d’être tranquille (\u003Ca href=\"https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation sur la méthode fetch (nouvel onglet)\">documentation\u003C/a>).\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// Header.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> <\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#B392F0\"> v-if\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"!$fetchState.pending\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> …\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> </\u003C/span>\u003Cspan style=\"color:#85E89D\">header\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import headerQuery from '~/graphql/queries/singles/header'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\"> data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: {},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">fetch\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> try {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\"> const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> data\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.$graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(headerQuery)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\"> this\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> data\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> } catch (error) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> console.\u003C/span>\u003Cspan style=\"color:#B392F0\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(JSON.stringify(\u003C/span>\u003Cspan style=\"color:#FFAB70\">error\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">undefined\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, 2))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"les-options\">Les options\u003C/h3>\n\u003Cp>Pour passer des options à la requête, par exemple pour une version multilingue avec \u003Ca href=\"https://i18n.nuxtjs.org/\" title=\"Documentation de nuxt i18n (nouvel onglet)\">nuxt/i18n\u003C/a> et/ou un paramètre d’url dans le cadre d’une page dynamique :\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// _slug.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"><\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">import articleQuery from '~/graphql/queries/articles'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">export default {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> async \u003C/span>\u003Cspan style=\"color:#B392F0\">asyncData\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ $graphql, app, params }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const locale \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> app.i18n.localeProperties.iso\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> const data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $graphql.default.\u003C/span>\u003Cspan style=\"color:#B392F0\">request\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(articleQuery, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> code: locale,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> slug: params.slug,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> })\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> return { data }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\"></\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":862,"imagePaths":884,"frontmatter":885},[863,866,869,872,875,878,881],{"depth":150,"slug":864,"text":865},"le-problème","Le problème",{"depth":150,"slug":867,"text":868},"la-solution","La solution 🙌",{"depth":154,"slug":870,"text":871},"la-conf","La conf",{"depth":154,"slug":873,"text":874},"la-requête","La requête",{"depth":834,"slug":876,"text":877},"dans-une-page","Dans une page",{"depth":834,"slug":879,"text":880},"dans-un-composant","Dans un composant",{"depth":154,"slug":882,"text":883},"les-options","Les options",[],{"title":851,"subtitle":852,"lang":16,"slug":848,"createdAt":170,"updatedAt":845,"excerpt":886,"tags":887,"type":427},"Quand le module gql le plus utilisé ne fonctionne pas…",[562],"HPsections",["Map",890,891,911,912,928,929,945,946,970,971],"011-offre",{"id":890,"data":892,"body":899,"filePath":900,"digest":901,"rendered":902},{"type":893,"lang":16,"uid":894,"image":895,"order":896,"quickTitle":897,"quickImage":898,"reference":39},"section","offre","/assets/images/home/offre-1.1.svg",1.1,"Mes offres en freelance","/assets/images/home/icon-desktop.svg","## L'offre site web classique\n\nCette offre est destinée à un public souhaitant **se doter d'un site web**, sans forcément intégrer l'accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du [référentiel général d'amélioration de l'accessibilité](https://accessibilite.numerique.gouv.fr/) (\u003Cabbr>RGAA\u003C/abbr>).\n\nL'objectif principal de cette offre étant d'**établir une présence en ligne** pour le client. Que cette dernière ait un but informatif et/ou éditorial.\n\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->","src/data/HP/011-offre.md","290ecd1ed94a1087",{"html":903,"metadata":904},"\u003Ch2 id=\"loffre-site-web-classique\">L’offre site web classique\u003C/h2>\n\u003Cp>Cette offre est destinée à un public souhaitant \u003Cstrong>se doter d’un site web\u003C/strong>, sans forcément intégrer l’accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du \u003Ca href=\"https://accessibilite.numerique.gouv.fr/\">référentiel général d’amélioration de l’accessibilité\u003C/a> (\u003Cabbr>RGAA\u003C/abbr>).\u003C/p>\n\u003Cp>L’objectif principal de cette offre étant d’\u003Cstrong>établir une présence en ligne\u003C/strong> pour le client. Que cette dernière ait un but informatif et/ou éditorial.\u003C/p>\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->",{"headings":905,"imagePaths":909,"frontmatter":910},[906],{"depth":150,"slug":907,"text":908},"loffre-site-web-classique","L’offre site web classique",[],{"type":893,"uid":894,"lang":16,"image":895,"order":896,"quickTitle":897,"quickImage":898,"reference":39},"012-offre",{"id":911,"data":913,"body":916,"filePath":917,"digest":918,"rendered":919},{"type":893,"lang":16,"image":914,"order":915,"reference":50},"/assets/images/home/offre-1.2.svg",1.2,"## L'offre accessibilité avancée\n\nCette offre s'adresse plus spécifiquement aux entités pour lesquelles **l'accessibilité du site est un critère majeur.** Qu'il s'agisse d'une création ou d'une mise en conformité après un audit d'accessibilité.\n\nLorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\n\n- [Rose Primaire](https://roseprimaire.com/) pour le conseil et l'accompagnement du projet ;\n- [Sylvain Plantier](https://jedessinebien.com/) et/ou [Benoît Etchevery](http://ben-etche.com/) pour l'illustration et la direction artistique.\n\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->","src/data/HP/012-offre.md","2a3bf3411b3c171b",{"html":920,"metadata":921},"\u003Ch2 id=\"loffre-accessibilité-avancée\">L’offre accessibilité avancée\u003C/h2>\n\u003Cp>Cette offre s’adresse plus spécifiquement aux entités pour lesquelles \u003Cstrong>l’accessibilité du site est un critère majeur.\u003C/strong> Qu’il s’agisse d’une création ou d’une mise en conformité après un audit d’accessibilité.\u003C/p>\n\u003Cp>Lorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://roseprimaire.com/\">Rose Primaire\u003C/a> pour le conseil et l’accompagnement du projet ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://jedessinebien.com/\">Sylvain Plantier\u003C/a> et/ou \u003Ca href=\"http://ben-etche.com/\">Benoît Etchevery\u003C/a> pour l’illustration et la direction artistique.\u003C/li>\n\u003C/ul>\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->",{"headings":922,"imagePaths":926,"frontmatter":927},[923],{"depth":150,"slug":924,"text":925},"loffre-accessibilité-avancée","L’offre accessibilité avancée",[],{"type":893,"lang":16,"order":915,"image":914,"reference":50},"013-offre",{"id":928,"data":930,"body":933,"filePath":934,"digest":935,"rendered":936},{"type":893,"lang":16,"image":931,"order":932},"/assets/images/home/offre-1.3.svg",1.3,"## Et l'éco-conception alors ?\n\nJe ne conçois pas l'éco-conception comme une offre. C'est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l'éco-conception sans accessibilité, j'applique donc ces méthodologies quelque soit le projet !","src/data/HP/013-offre.md","03e37f364ac27cb4",{"html":937,"metadata":938},"\u003Ch2 id=\"et-léco-conception-alors\">Et l’éco-conception alors ?\u003C/h2>\n\u003Cp>Je ne conçois pas l’éco-conception comme une offre. C’est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l’éco-conception sans accessibilité, j’applique donc ces méthodologies quelque soit le projet !\u003C/p>",{"headings":939,"imagePaths":943,"frontmatter":944},[940],{"depth":150,"slug":941,"text":942},"et-léco-conception-alors","Et l’éco-conception alors ?",[],{"type":893,"lang":16,"order":932,"image":931},"020-methodo",{"id":945,"data":947,"body":952,"filePath":953,"digest":954,"rendered":955},{"type":893,"lang":16,"uid":948,"image":949,"order":150,"quickTitle":950,"quickImage":951},"methodology","/assets/images/home/methodo.svg","Ma méthodologie","/assets/images/home/icon-methodo.svg","## Méthodologie\n\n### Accessibilité par défaut\n\nEngagé pour un web plus accessible, je crée des **sites web** en m'appuyant sur le [référentiel général d'amélioration de l'accessibilité (RGAA)](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) ainsi que sur les bonnes pratiques [Opquast.](https://www.opquast.com/rendre-le-web-meilleur/)\n\n### Sobriété par choix\n\nJe privilégie le développement de **sites statiques** en adoptant une approche [d'éco-conception numérique.](https://eco-conception.designersethiques.org/guide/fr/) \nC'est-à-dire que le site est pensé pour n'embarquer que les fonctionnalités nécessaires à son utilisation.\n\nCette approche présente de **nombreux avantages :**\n\n- chargement rapide des pages ;\n- sécurité renforcée ;\n- coûts serveur réduits ;\n- maintenance facilitée.\n\nLorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l'interface. Cela permet de garantir que **le site reste en ligne** même si le CMS venait à ne plus fonctionner.","src/data/HP/020-methodo.md","75a09b4e0b1e926b",{"html":956,"metadata":957},"\u003Ch2 id=\"méthodologie\">Méthodologie\u003C/h2>\n\u003Ch3 id=\"accessibilité-par-défaut\">Accessibilité par défaut\u003C/h3>\n\u003Cp>Engagé pour un web plus accessible, je crée des \u003Cstrong>sites web\u003C/strong> en m’appuyant sur le \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité (RGAA)\u003C/a> ainsi que sur les bonnes pratiques \u003Ca href=\"https://www.opquast.com/rendre-le-web-meilleur/\">Opquast.\u003C/a>\u003C/p>\n\u003Ch3 id=\"sobriété-par-choix\">Sobriété par choix\u003C/h3>\n\u003Cp>Je privilégie le développement de \u003Cstrong>sites statiques\u003C/strong> en adoptant une approche \u003Ca href=\"https://eco-conception.designersethiques.org/guide/fr/\">d’éco-conception numérique.\u003C/a>\u003Cbr>\nC’est-à-dire que le site est pensé pour n’embarquer que les fonctionnalités nécessaires à son utilisation.\u003C/p>\n\u003Cp>Cette approche présente de \u003Cstrong>nombreux avantages :\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>chargement rapide des pages ;\u003C/li>\n\u003Cli>sécurité renforcée ;\u003C/li>\n\u003Cli>coûts serveur réduits ;\u003C/li>\n\u003Cli>maintenance facilitée.\u003C/li>\n\u003C/ul>\n\u003Cp>Lorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l’interface. Cela permet de garantir que \u003Cstrong>le site reste en ligne\u003C/strong> même si le CMS venait à ne plus fonctionner.\u003C/p>",{"headings":958,"imagePaths":968,"frontmatter":969},[959,962,965],{"depth":150,"slug":960,"text":961},"méthodologie","Méthodologie",{"depth":154,"slug":963,"text":964},"accessibilité-par-défaut","Accessibilité par défaut",{"depth":154,"slug":966,"text":967},"sobriété-par-choix","Sobriété par choix",[],{"type":893,"uid":948,"lang":16,"image":949,"order":150,"quickTitle":950,"quickImage":951},"030-about",{"id":970,"data":972,"body":977,"filePath":978,"digest":979,"rendered":980},{"type":893,"lang":16,"uid":973,"image":974,"order":154,"quickTitle":975,"quickImage":976},"about","/assets/images/home/about.svg","Moi","/assets/images/home/icon-heart.svg","## À propos\n\n### Formations personnelles\n\nAfin de solidifier mes compétences, j'ai suivi les formations et passé les certifications suivantes :\n\n- [Opquast](https://directory.opquast.com/fr/certificat/CTQSKP/) - Maîtrise de la qualité en projet web ;\n- Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\n\n### Formations des autres\n\nDepuis plusieurs années, j'interviens dans différents campus afin de dispenser des cours de développement web.\n\n### Temps libre\n\nJ’essaie de contribuer à des [projets open source](https://git.nardu.in/explore/repos) qui me tiennent à cœur et je m'engage localement avec le collectif [good-it!](https://www.good-it.org/)\n\nAh et j’écris [des articles](/articles) aussi ! Des articles sur le design, le développement web et l’informatique.","src/data/HP/030-about.md","a7abff6d744406ce",{"html":981,"metadata":982},"\u003Ch2 id=\"à-propos\">À propos\u003C/h2>\n\u003Ch3 id=\"formations-personnelles\">Formations personnelles\u003C/h3>\n\u003Cp>Afin de solidifier mes compétences, j’ai suivi les formations et passé les certifications suivantes :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://directory.opquast.com/fr/certificat/CTQSKP/\">Opquast\u003C/a> - Maîtrise de la qualité en projet web ;\u003C/li>\n\u003Cli>Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"formations-des-autres\">Formations des autres\u003C/h3>\n\u003Cp>Depuis plusieurs années, j’interviens dans différents campus afin de dispenser des cours de développement web.\u003C/p>\n\u003Ch3 id=\"temps-libre\">Temps libre\u003C/h3>\n\u003Cp>J’essaie de contribuer à des \u003Ca href=\"https://git.nardu.in/explore/repos\">projets open source\u003C/a> qui me tiennent à cœur et je m’engage localement avec le collectif \u003Ca href=\"https://www.good-it.org/\">good-it!\u003C/a>\u003C/p>\n\u003Cp>Ah et j’écris \u003Ca href=\"/articles\">des articles\u003C/a> aussi ! Des articles sur le design, le développement web et l’informatique.\u003C/p>",{"headings":983,"imagePaths":996,"frontmatter":997},[984,987,990,993],{"depth":150,"slug":985,"text":986},"à-propos","À propos",{"depth":154,"slug":988,"text":989},"formations-personnelles","Formations personnelles",{"depth":154,"slug":991,"text":992},"formations-des-autres","Formations des autres",{"depth":154,"slug":994,"text":995},"temps-libre","Temps libre",[],{"type":893,"uid":973,"lang":16,"image":974,"order":154,"quickTitle":975,"quickImage":976},"veille",["Map",269,1000],{"id":269,"data":1001,"body":1003,"filePath":1004,"digest":1005,"rendered":1006},{"lang":16,"title":269,"updatedAt":1002},["Date","2023-04-20T17:12:06.000Z"],"- [mmm.page](https://build.mmm.page/) - Éditeur de sites web très simples, en glisser-déposer, pour n'importe quoi.\n- [Color.io](https://www.color.io/) - Éditeur photo en ligne.\n- [Addy's toolkit](https://toolkit.addy.codes/) - Outils et ressources pour les designers et développeurs sites web.\n- [L’accessibilité n’est pas une variable d’ajustement](https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/) — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n > L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\n- [3D en CSS (english)](https://garden.bradwoods.io/notes/css/3d) – Explications et exemples des propriétés 3D en CSS.\n- [Climat : Comment ne pas déprimer ?](https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html) – Podcast.\n- [Fable (english)](https://fable.app) – Application de motion design.\n- [Rive (english)](https://rive.app) – Application de motion design.\n- [Cake Desk](https://cakedesk.app/) – Application de facturation.\n- [Ombre fluide en CSS](https://shadows.brumm.af/) – Générateur.\n- [Smol CSS](https://smolcss.dev/) – Collection de fragments CSS.\n- [Ajustement optique](https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/) (english) – Aligner visuellement plutôt que techniquement.\n- [Datawrapper](https://blog.datawrapper.de/category/datavis-dos-and-donts/) (english) – Conseils pour montrer de la donnée.\n- [Assistivlabs](https://assistivlabs.com/) (english) – Service de test des technologies d'assistance (browserstack mais pour l'accessibilité).\n- [Les caractères fantaisistes et l'accessibilité](https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/) – Explications et exemples de l'enfer que sont les caractères Unicode pour les technologies d'assistance.\n- [Créer un champ `time` sur le web](https://adamsilver.io/blog/designing-a-time-input-backed-by-research/) (english) – Article.\n- [La cascade](https://la-cascade.io) – Collection d'articles sur le CSS.\n- [Tabby](https://tabby.sh) (english) – An alternative terminal app.\n- [Newglyph](https://newglyph.com/) – Fonderie indépendante.\n- [\u003Cspan lang=\"en\">Headless UI\u003C/span>](https://headlessui.com/vue/dialog) (english) – Librairie de composants vue et react.\n- [Vie privée sexy](https://privacy.sexy) (english) – Outils de confidentialité pour windows et macos.\n- [33 concepts JavaScript](https://github.com/leonardomso/33-js-concepts) (english) – Articles.\n- [Formbricks](https://formbricks.com/) (english) – Alternative open source à google form/typeform.\n- [Animations de chargement SVG](https://github.com/n3r4zzurr0/svg-spinners) – Collection.\n- [a11yphant](https://a11yphant.com/) (english) – Challenges de code pour apprendre l'accessibilité.\n- [CSS moderne](https://moderncss.dev/) (english) – Fragments CSS.\n- [Conteneur moderne en CSS](https://twitter.com/KevinJPowell/status/1501555193799925761) (english) – Tweet de Kevin Powell ❤️","src/data/veille/2023.md","1135beec386f207f",{"html":1007,"metadata":1008},"\u003Cul>\n\u003Cli>\u003Ca href=\"https://build.mmm.page/\">mmm.page\u003C/a> - Éditeur de sites web très simples, en glisser-déposer, pour n’importe quoi.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.color.io/\">Color.io\u003C/a> - Éditeur photo en ligne.\u003C/li>\n\u003Cli>\u003Ca href=\"https://toolkit.addy.codes/\">Addy’s toolkit\u003C/a> - Outils et ressources pour les designers et développeurs sites web.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/\">L’accessibilité n’est pas une variable d’ajustement\u003C/a> — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n\u003Cblockquote>\n\u003Cp>L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\u003C/p>\n\u003C/blockquote>\n\u003C/li>\n\u003Cli>\u003Ca href=\"https://garden.bradwoods.io/notes/css/3d\">3D en CSS (english)\u003C/a> – Explications et exemples des propriétés 3D en CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html\">Climat : Comment ne pas déprimer ?\u003C/a> – Podcast.\u003C/li>\n\u003Cli>\u003Ca href=\"https://fable.app\">Fable (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://rive.app\">Rive (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://cakedesk.app/\">Cake Desk\u003C/a> – Application de facturation.\u003C/li>\n\u003Cli>\u003Ca href=\"https://shadows.brumm.af/\">Ombre fluide en CSS\u003C/a> – Générateur.\u003C/li>\n\u003Cli>\u003Ca href=\"https://smolcss.dev/\">Smol CSS\u003C/a> – Collection de fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/\">Ajustement optique\u003C/a> (english) – Aligner visuellement plutôt que techniquement.\u003C/li>\n\u003Cli>\u003Ca href=\"https://blog.datawrapper.de/category/datavis-dos-and-donts/\">Datawrapper\u003C/a> (english) – Conseils pour montrer de la donnée.\u003C/li>\n\u003Cli>\u003Ca href=\"https://assistivlabs.com/\">Assistivlabs\u003C/a> (english) – Service de test des technologies d’assistance (browserstack mais pour l’accessibilité).\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/\">Les caractères fantaisistes et l’accessibilité\u003C/a> – Explications et exemples de l’enfer que sont les caractères Unicode pour les technologies d’assistance.\u003C/li>\n\u003Cli>\u003Ca href=\"https://adamsilver.io/blog/designing-a-time-input-backed-by-research/\">Créer un champ \u003Ccode>time\u003C/code> sur le web\u003C/a> (english) – Article.\u003C/li>\n\u003Cli>\u003Ca href=\"https://la-cascade.io\">La cascade\u003C/a> – Collection d’articles sur le CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://tabby.sh\">Tabby\u003C/a> (english) – An alternative terminal app.\u003C/li>\n\u003Cli>\u003Ca href=\"https://newglyph.com/\">Newglyph\u003C/a> – Fonderie indépendante.\u003C/li>\n\u003Cli>\u003Ca href=\"https://headlessui.com/vue/dialog\">\u003Cspan lang=\"en\">Headless UI\u003C/span>\u003C/a> (english) – Librairie de composants vue et react.\u003C/li>\n\u003Cli>\u003Ca href=\"https://privacy.sexy\">Vie privée sexy\u003C/a> (english) – Outils de confidentialité pour windows et macos.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/leonardomso/33-js-concepts\">33 concepts JavaScript\u003C/a> (english) – Articles.\u003C/li>\n\u003Cli>\u003Ca href=\"https://formbricks.com/\">Formbricks\u003C/a> (english) – Alternative open source à google form/typeform.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/n3r4zzurr0/svg-spinners\">Animations de chargement SVG\u003C/a> – Collection.\u003C/li>\n\u003Cli>\u003Ca href=\"https://a11yphant.com/\">a11yphant\u003C/a> (english) – Challenges de code pour apprendre l’accessibilité.\u003C/li>\n\u003Cli>\u003Ca href=\"https://moderncss.dev/\">CSS moderne\u003C/a> (english) – Fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/KevinJPowell/status/1501555193799925761\">Conteneur moderne en CSS\u003C/a> (english) – Tweet de Kevin Powell ❤️\u003C/li>\n\u003C/ul>",{"headings":1009,"imagePaths":1010,"frontmatter":1011},[],[],{"lang":16,"title":269,"updatedAt":1012},"2023-04-20T17:12:06.000Z"] \ No newline at end of file +[["Map",1,2,9,10,61,62,427,428,888,889,903,904],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.1.1","content-config-digest","8021b3469f132349","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"site\":\"https://www.nardu.in\",\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[\"assets.nardu.in\"],\"remotePatterns\":[{\"protocol\":\"https\"}]},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":\"shiki\",\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"one-dark-pro\",\"themes\":{},\"wrap\":false,\"transformers\":[{\"name\":\"@shikijs/transformers:meta-highlight\"}]},\"remarkPlugins\":[],\"rehypePlugins\":[],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"i18n\":{\"defaultLocale\":\"fr\",\"locales\":[\"fr\",\"en\"],\"routing\":{\"prefixDefaultLocale\":false,\"redirectToDefaultLocale\":true,\"fallbackType\":\"redirect\"}},\"security\":{\"checkOrigin\":true},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"responsiveImages\":false},\"legacy\":{\"collections\":false}}","references",["Map",11,12,25,26,39,40,50,51],"3w",{"id":11,"data":13,"filePath":21,"digest":22,"rendered":23},{"title":11,"subtitle":14,"url":15,"lang":16,"slug":11,"tags":17,"createdAt":20},"J'ai fait de la doc!","https://3-w.fr","fr",[18,19],"Front-end","documentation",["Date","2022-10-19T18:02:00.000Z"],"src/content/references/3w.md","0d3d94c8af754e1b",{"html":24},"","natureo",{"id":25,"data":27,"filePath":36,"digest":37,"rendered":38},{"title":28,"subtitle":29,"url":30,"lang":16,"slug":25,"tags":31,"createdAt":35},"Nature en Occitanie","La sobriété au naturel.","https://www.natureo.org/",[18,32,33,34],"accessibilité","éco-conception","CMS",["Date","2023-04-19T18:02:00.000Z"],"src/content/references/natureo.md","6a7169b855b57024",{"html":24},"parole-expression",{"id":39,"data":41,"filePath":47,"digest":48,"rendered":49},{"title":42,"subtitle":43,"url":44,"lang":16,"slug":39,"tags":45,"createdAt":46},"Parole Expression","Un nouveau site pour l'association.","https://www.paroleexpression.fr/",[18,33,34],["Date","2022-04-19T17:11:00.000Z"],"src/content/references/parole-expression.md","ec95a408f8c3e99c",{"html":24},"rose-primaire",{"id":50,"data":52,"filePath":58,"digest":59,"rendered":60},{"title":53,"subtitle":54,"url":55,"lang":16,"slug":50,"tags":56,"createdAt":57},"Rose Primaire","Une agence comme on l'aime.","https://roseprimaire.com/",[18,32,33,34],["Date","2023-04-19T17:11:00.000Z"],"src/content/references/rose-primaire.md","a0133200cf1bee58",{"html":24},"articles",["Map",63,64,76,77,89,90,102,103,113,114,124,125,134,135,171,172,205,206,224,225,239,240,269,270,298,299,315,316,366,367,410,411],"en-after-effects-expressions",{"id":63,"data":65,"body":73,"filePath":74,"digest":75,"deferredRender":72},{"title":66,"subtitle":67,"lang":68,"tags":69,"type":61,"slug":63,"createdAt":71,"code":72},"After Effects Expressions","Animation on steroïds.","en",[70],"Design",["Date","2019-04-24T09:00:00.000Z"],true,"import AstroImage from '../../../components/AstroImage.astro'\n\n## An ever lasting battle\n\nThere is very little documentation and the existing one is hard to find or very old. Very often I just don't have the time to dive into expression learning while animating even though it could help the entire project on the long term.\nSo the last time I had to do a complex animation, **I took the damn time!**\n\n## The begining of the end (of keyframes).\n\nEveryone uses expressions whether they know it or not. Most of the time it's a rather transparent process for the animator. For example: when parenting a property to another one, After Effects creates an expression for us.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/basic_expression_d81b12f1ac.jpeg'\n\twidth='728'\n\theight='80'\n\talt='Parenting the position of the form to a null creates an expression.'\n/>\n\nOver the last updates, Adobe has made an effort to make expressions more accessible to everyone. For example, the expression box is now resembling a code editor thanks to code-coloring and auto-completion features. After Effects expression feel like JavaScript with custom functions.\n\nThose custom functions can be called through a menu once you enabled the expressions on a property. It offers organized shortcut and proper syntax to all of AE native functions and a bunch of JavaScript standard ones.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/shortcut_39cc19d383.jpeg'\n\twidth='728'\n\theight='322'\n\talt='Alt + Click the stopwatch to access the shortcuts.'\n/>\n\n## So I need to learn javascript to do motion design now?\n\n### Why bother?\n\nI know that most animators don't have any kind of development background. However, if Adobe thought it best to let us use expressions, I think we ought to, at least, try.\n\n> A lot of incredible professionals like [Mt Mograph](https://www.mtmograph.com/) and [Video Copilot](https://videocopilot.net/) use expressions.\n\nLike every optimization process, building an expressions knowledge takes time. However, like all optimization process, you will benefit from it afterwards.\n\n### Where to learn\n\nI've gathered a list of my favourite learning grounds. Plenty more exist, **go get'em!**\n\n- [Adobe official expression starter guide (FR)](https://helpx.adobe.com/fr/after-effects/using/expression-language-reference.html)\n- [Adobe official expression basic (EN)](https://helpx.adobe.com/after-effects/using/expression-basics.html)\n- [Adobe forums for expressions](https://community.adobe.com/t5/after-effects/bd-p/after-effects?page=1&sort=latest_replies&filter=all&topics=label-expressions)\n- [Creative Cow expressions forums](https://creativecow.net/forums/forum/adobe-after-effects-expressions/)\n- [Youtube channel about expressions](https://www.youtube.com/playlist?list=PLvr5U5ZSt6IzHyvSL9fo0M9NRPsTvra31)\n- [All expressions explained](http://aescript.jecool.net/reference/)\n- [All expressions explained again](http://expressions.aenhancers.com/index.html)\n- [Nice examples of basic expressions](https://www.schoolofmotion.com/tutorials/amazing-expressions-in-after-effects)\n\n## Real world example\n\n### Number counter\n\nLet's say you need to animate a rather simple counter from 0% to 100%.\n\n- Start by creating a text layer. Define your typographic choices, colours, etc.\n- On the effect menu add expression options > slider control\n- Alt + Click the Source text property\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/alt-counter.mp4' type='video/mp4' />\n\u003C/video>\n\n- Parent the source text to the slider control through the pickwhip.\n\n\u003Cvideo width='462' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/pickwhip.mp4' type='video/mp4' />\n\u003C/video>\n\nYou should get something like this in the expressions panel:\n\n```javascript\neffect(\"Slider Control\")(\"Slider\")​\n```\n\n- Set two keyframes on the slider from 0 to 100. The text should update accordingly.\n- By default, After Effects does not round numbers. In the expression panel, wrap your expression with the `Math.round()` function.\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/round.mp4' type='video/mp4' />\n\u003C/video>\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\"))​\n```\n\nGreat! We have a working counter. But we wanted a percentage counter. We could add a % glyph in another text layer but let's not.\n\nStill in the expression panel, we're going to add a string containing the % glyph, using basic JavaScript concatenation: `+ '%'`\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\")) + '%'​\n```\n\n\u003Cvideo width='538' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/percent.mp4' type='video/mp4' />\n\u003C/video>\n\n**And there we go!** A fully functioning and customizable counter using a slider controller and expressions.","src/content/articles/en/after-effects-expressions.mdx","3b6f88fbf35af1a4","en-sci-hub-unblock",{"id":76,"data":78,"body":86,"filePath":87,"digest":88,"deferredRender":72},{"title":79,"subtitle":80,"lang":68,"tags":81,"type":61,"slug":76,"createdAt":84,"updatedAt":85},"Access blocked Sci-hub","The science of sharing.",[82,83],"Internet","Science",["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nThe current sci-hub address is: \u003Ca href=\"https://sci-hub.se\" rel=\"noreferer noopener\">sci-hub.se\u003C/a>\n\n## What is this about?\n\nNot being a researcher myself, here’s an [extremely well done explanatory video](https://youtu.be/rcgxY__YXEc) on the subject of scientific publication (french audio with auto subtitle).\n\n> “This is outrageous!”​\n\nI noticed that my ISP was indeed blocking access. I have not yet been able to check for the other suppliers, but I imagine that they have all complied with the court decision.\nThe restriction in place is quite basic. This is a “DNS” block. A DNS is a server that is used to link a domain name: **www.sci-hub.tw** to an IP address: **186.2.163.90**\nIt is, in a way, the Internet phone book. Without the address, it is impossible to contact the domain. What ISPs have certainly done: block requests to the [sci-hub.se.](http://sci-hub.se/) domain name. As a result, no IP address is returned and the site is not accessible.\n\n## How to bypass this?\n\n- Either by using a VPN\n- Either by modifying the DNS servers of your computers/Internet box\n\nI would recommend the second solution because it allows you to protect yourself against future blockages/filtering/censorship from your ISP and does not require any financial compensation.\nI will focus on change from a computer because it will be effective wherever you are and not only from your home.\n\n### MacOs\n\nGo to:\n\n1. System Preferences\n1. Network\n1. (wi-fi and/or ethernet)\n1. Advanced\n1. DNS\n\nFrom there, you can add DNS servers by clicking the + icon. Click ok and apply the new settings. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS network and DNS settings'\n/>\n\n### Windows (10)\n\nGo to:\n\n1. System Settings\n1. Network & Internet\n1. Change adapter options\n1. Right click your adapter then “properties”\n1. Select “internet protocol version 4” (and/or 6)\n1. Properties\n1. Use the following DNS server addresses\n\nFrom there, you can add DNS servers. Click save. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Windows system settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows network settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows network connections settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows network adapter settings'\n/>\n\n## Which DNS?\n\nThere are many DNS servers available. The best known are Google, Cloudflare and OpenDNS. If you really want to use Google’s, I’ll let you look up their address. Here are my recommendations in order of preference.\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMy favorite since it is a [french association](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net)\n\nQuand9 is a non-profit foundation offering free public DNS servers. Their classic servers offer filtering of identified malicious domains. They do not collect data and are \u003Cabbr title=\"General Data Protection Regulation\">GDPR\u003C/abbr>-compliant.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## That's it.\n\nBy changing these settings, you are free from your ISPs and their content filtering rules.\n\nFor the moment, these restrictions are almost symbolic because if Sci-hub were to change its url, the block would no longer work. But the publishers’ victory in court shows that they have not had their last word. We are therefore not immune to a wider and stronger block in the future.\n\nIf you want to learn more about the struggle of the people who fight to ensure that research is not a paid commodity, I recommend [this documentary](https://youtu.be/y_CQATGOX2w) on Aaron Shwartz. Or [this article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) about the founder of Sci-hub.\n\nIn the meantime, good readings to all of you. We stand with you!","src/content/articles/en/sci-hub-blocage.mdx","8959506d941cdcc5","en-the-day-I-jamd",{"id":89,"data":91,"body":99,"filePath":100,"digest":101,"deferredRender":72},{"title":92,"subtitle":93,"lang":68,"tags":94,"type":61,"slug":89,"createdAt":97,"updatedAt":98},"The day I Jam’d","A story of unusual tools and fun gambles.",[95,96],"Dev","Jamstack",["Date","2020-10-08T09:00:00.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## The not so easy choice\n\nWhen I was still using Wordpress for my personal website, I thought it would be nice to try [OpenLiteSpeed](https://openlitespeed.org) webserver. Being a designer, I always like to have a graphical interface and I heard OLS had very nice caching and overall performances.\n\n## FIGHT!\n\nA few years later, I learned about Jamstack and its incredible potential. Not being impulsive at all, I chose to entirely remake my website with tools like [11ty](https://www.11ty.dev/) and [Strapi](https://strapi.io/).\n\nI remember Strapi still being in alpha/beta and colleagues telling me it was a risky gamble, especially since I was pretty new to the node.js world.\n\n> Open source and french? Sign me up!\n\nSo I started recreating my website identically with 11ty and Strapi. Same hosting on a Digital Ocean droplet, same webserver, same content. I had done a fair amout of performance optimizations on my wordpress install so I was eager to compare the results with the new static version.\n\nBoy did they exceed my expectations! With almost no optimization on the static side, I got the following results.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 53/100 on Wordpress.'\n/>\n\nDespite a lot of efforts I could not do better. I’m no expert in caching, do not use CDN and relied on plugins to achieve a lot of stuff (php not being my strongest skill 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 97/100 on jamstack.'\n/>\n\nAlmost **zero** special configuration (I was too anxious to test) and I reached an awesome score. I know lighthouse scores are not everything but hey, **53 vs 97**… I’ll take it!\n\n## Now kiss 🥰\n\nBoth of these approaches have their benefits and drawbacks. As a freelance, my clients often prefer or ask for Wordpress because of its reputation. I always present a Jamstack alternative when possible but it’s still scary to most compared to Wordpress. I feel however that it’s going to be easier to use Jamstack with time.\n\n## I did it again…\n\nHere we are now, a quarantine and a few months later and this website is running with… [Nuxt.js](https://nuxtjs.org/). I know, I’m sorry, I couldn’t resist the latest [nuxt content](https://content.nuxtjs.org/) functionnality.\n\nSo I re-did everything again… and let me just say: **wow**, what an experience!\nI **love** developing with Nuxt. Using nuxt content allowed me to focus on design and, well, content.\nNo more Apollo client and graphQL query, only markdown and a few promises.\n\nDon’t get me wrong, I really like working with Strapi and its graphQL capabilities but for the purpose of this website, nuxt content does it (extremely well).\n\nI’m still using Strapi as a way to upload, store and manage images, videos, gifs, etc. It might be too much for this use case but I like to know that I can still go back to it if I want to! Also, I spent quite a bit of time setting it up with OpenLiteSpeed and I’m still too attached to this accomplishment to let it go.\n\n## In the end\n\nWordpress, Jamstack, vanilla everything… Does it really matter? For me, the dev experience was far more enjoyable working with 11ty, nuxt.js and strapi than with Wordpress.\n\nOn the performance and accessibility side, it also seems to be the better/smarter choice. It might not be everytime! ¯\\\\\\_(ツ)\\_/¯\n\nCan’t wait to learn [astro](https://astro.build/) and start from scratch again!","src/content/articles/en/the-day-I-jamd.mdx","60b77e216e02f618","en-video-compression",{"id":102,"data":104,"body":110,"filePath":111,"digest":112,"deferredRender":72},{"title":105,"subtitle":106,"lang":68,"tags":107,"type":61,"slug":102,"createdAt":108,"updatedAt":109},"Video compression","Encode like you mean it.",[70],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Let's play.\n\nVideos are everywhere. **EVERYWHERE!** But videos can and will be huge when 4k becomes an internet standard. Currently, 1920x1080 is king and we usually have no problem hosting or playing this resolution.\n\n## Because we can doesn't mean we should.\n\nRight now, the (good) trend of web performance is on the rise. Everyone wants a blazing fast loading website, which might not be possible if we send requests to 100mb (or even more) videos.\n\nWith a good connection, users will not see the difference. But if we go down that path, nor will they with a 300mb one. So the goal is to make every asset as small as possible. It's already the case with images. But it's simpler and faster than video encoding.\n\n## Small size, best quality.\n\nLet's say we exported​ a 1920x1080 video from Premiere Pro with these basic settings:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-premiere-1.jpeg'\n\twidth='673'\n\theight='800'\n/>\n\nIt's gorgeous, it's Full HD, it's 1:30 minute of excellent editing but it's 50mb… What a shame.\n\n> We can already bring down the size from Premiere or Media Encoder by selecting CBR instead of VBR and using a low bitrate (like 2 or 3).\n\nLet's now use [Handbrake!](https://handbrake.fr/) It's free, open source and multi platform. You can also read this great article from [Ueno](https://loremipsum.ueno.co/dear-ueno-how-do-you-compress-videos-6657ebd9dd28?gi=930afecec398) on video encoding.\n\n**Please please PLEASE. Never export videos from within After Effects.**\n\n## Handbrake\n\n### Summary screen\n\nWhile it's not as nice as Premiere Pro, it has way more exporting capabilities. Follow these steps to use good standard settings:\n\n1. Open your source video\n1. Select a preset corresponding to your future usage like Fast 1080p30\n1. Check Web Optimized\n1. Keep MPEG-4 as the format\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-1.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Video screen\n\n1. Keep H.264 (x264) or use H.264 nvidia nvenc if you can (crazy fast encoding by nvidia)\n1. Choose Constant Quality and try a value between 20 and 30​ (higher = smaller size but lower quality)\n1. Choose Peak Framerate. If you don't know the framerate, keep the default setting\n1. Choose the type of video you are encoding (film, animation…)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-2.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Audio screen\n\nIf you don't have audio, be sure to set the audio channel to none.\nIf you have an audio channel, these settings are great and will not influence the size much​:\n\n1. Codec AAC\n1. Samplerate 44.1\n1. Bitrate 192 to 256 (your choice)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-3.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Export!\n\nI used a RF of 25 for this example and no audio.\n\n1. My Premiere Pro video was 50,6mb\n1. My Handbrake video is 5,5mb​\n\n> What a save!\n\n​I ended up dividing the original size by 10. Which is cool.\nI tried with a RF of 30. The video was still pretty good and only 3,3mb.\n\n## Exporting for the web\n\nNow that we know how to properly compress videos, let's go further. Say we have a website with a lot of videos on the same page. We still want to load the content as fast as possible. So our videos need to be as small as possible. We won't do better than previously seen using mp4/H.264. However, we can use **webm/VP9.**\nWebm is an html video format and VP9 is its latest codec.\n\nUsing Handbrake and webm/VP9, we can achieve really great compression without losing too much quality (or none at all depending on the settings). I was able to divide by 4 the size of a video using these presets:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-4.jpg'\n\twidth='728'\n\theight='313'\n\talt=''\n/>\n\nThe only down side is that it takes some time to encode. It will depend on the video length and your computing power.\n\nI tried various settings but I read [here](https://trac.ffmpeg.org/wiki/Encode/VP9) that VP9 is supposed to be used with two-pass encoding. You then have to find the right bitrate (here 1000) for your situation.","src/content/articles/en/video-compression.mdx","5bb9f69df6c651d1","sci-hub-blocage",{"id":113,"data":115,"body":121,"filePath":122,"digest":123,"deferredRender":72},{"title":116,"subtitle":117,"lang":16,"tags":118,"type":61,"slug":113,"createdAt":119,"updatedAt":120},"Sci-hub bloqué, comment contourner","La science du partage.",[82,83],["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nL'adresse actuelle de sci-hub est : [sci-hub.se](https://sci-hub.se)\n\n## Résumé de la situation\n\nN’étant pas moi-même directement chercheur, je vous laisse regarder [cette vidéo](https://youtu.be/rcgxY__YXEc) explicative extrêmement bien faite sur le sujet de la publication scientifique.\n\n> “ Mais c’est scandaleux ! ”​\n\nJ’ai constaté que le blocage était actif chez SFR. Je n’ai pas encore pu vérifier pour les autres fournisseurs mais j’imagine qu’ils se sont tous conformés à la décision de justice.\nLe blocage mis en place est assez basique. Il s’agit d’un blocage “ DNS ”.\n\nUn DNS est un serveur qui sert à faire le lien entre un nom de domaine : **sci-hub.tw** et une adresse IP : **186.2.163.90**.\n\nC’est en quelque sorte l’annuaire d’internet. Sans l’adresse, impossible de contacter le domaine. Ce que les FAI ont certainement fait : bloquer les requêtes au nom de domaine [sci-hub.se.](http://sci-hub.se/) Ainsi, aucune adresse IP n’est renvoyée et le site n’est pas accessible.\n\n## Comment contourner ce blocage ?\n\n- Soit en utilisant un VPN\n- Soit en modifiant les serveurs DNS de vos ordinateurs/box internet\n\nJe recommande la deuxième solution car elle permet de se prémunir contre de futurs blocages/filtrages/censures de la part de votre FAI et ne nécessite pas de contrepartie financière.\nJe vais me focaliser sur le changement depuis un ordinateur car il sera effectif où que vous soyez.\n\n### Sur MacOs\n\nOuvrez :\n\n1. Préférences système\n1. Réseau\n1. Ethernet et/ou Wi-fi\n1. Avancé\n1. DNS\n1. Serveurs DNS\n\nDe là, vous pouvez ajouter des serveurs DNS en cliquant sur l'icône +. Cliquez sur ok et appliquez les nouveaux paramètres. Vous devrez peut-être redémarrer votre ordinateur pour que les changements fonctionnent.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS réglages réseau et DNS'\n/>\n\n### Sur Windows (ici 10)\n\nOuvrez :\n\n1. Réglages\n1. Réseau et internet\n1. Modifier les options de l'adaptateur\n1. Clic droit sur les propriétés de votre interface réseau\n1. Selectionnez « protocole Internet version 4 » (et/ou 6)\n1. Propriétés\n1. Utiliser l’adresse de serveur DNS suivante\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Réglages windows'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows réglages réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows régalges connections réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows options adaptateur réseau'\n/>\n\n## Quels serveurs DNS utiliser ?\n\nIl y a de nombreux serveurs DNS accessibles. Les plus connus étant ceux de Google, Cloudflare et OpenDNS. Si vous tenez vraiment à utiliser ceux de Google, je vous laisse chercher leur adresse. Voici mes recommandations par ordre de préférence.\n\nPlusieurs fournisseurs :\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMes favoris puisqu’il s’agit d’une [association française.](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net/fr)\n\nQuand9 est une fondation à but non lucratif proposant des serveurs DNS publics et gratuits. Leurs serveur classiques offrent un filtrage de domaines malveillants identifiés. Ils ne collectent pas de données et sont conforment au \u003Cabbr title=\"Règlement général sur la protection des données\">RGPD\u003C/abbr>.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## C'est tout.\n\nEn modifiant ces réglages, vous vous affranchissez de vos fournisseurs d’accès et de leurs règles de filtrage du contenu.\n\nPour l’instant, ces blocages sont presque symboliques car si Sci-hub venait à changer d’url, le blocage ne fonctionnerait plus. Mais la victoire des éditeurs au tribunal montre qu’ils n’ont pas dit leur dernier mot. Nous ne sommes donc pas à l’abri d’un futur blocage plus large et plus dur à contrer.\n\nSi vous voulez en apprendre plus sur le combat de ces gens qui se battent pour que la recherche ne soit pas une marchandise, je vous conseille [ce documentaire](https://youtu.be/y_CQATGOX2w) sur Aaron Shwartz. Ou plus simplement [cet article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) sur la fondatrice de Sci-hub.\n\nEn attendant, bonnes lectures à tou·te·s. On est avec vous !","src/content/articles/fr/sci-hub-blocage.mdx","6438fdc02b91ec59","the-day-I-jamd",{"id":124,"data":126,"body":131,"filePath":132,"digest":133,"deferredRender":72},{"title":92,"subtitle":127,"lang":16,"tags":128,"type":61,"slug":124,"createdAt":129,"updatedAt":130},"Des paris, des outils et du fun.",[95,96],["Date","2020-10-08T07:47:36.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## La solution de non facilité\n\nLorsque j’utilisais encore Wordpress pour mon site web personnel, j’ai voulu essayer le serveur web \u003Ca href=\"https://openlitespeed.org\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">OpenLiteSpeed (en anglais)\u003C/a>. En tant que designer, j’ai toujours aimé avoir une interface graphique et j’avais entendu dire qu’OLS jouissait de bonnes performances en général et de cache en particulier.\n\n## Battez-vous!\n\nQuelques années plus tard, je découvrais l’univers Jamstack et son incroyable potentiel. N’étant pas du tout impulsif, j’ai choisi de refaire entièrement mon site web avec des outils comme \u003Ca href=\"https://www.11ty.dev/\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">11ty (en anglais)\u003C/a> et \u003Ca href=\"https://strapi.io/\" hreflang=\"en\">Strapi (en anglais)\u003C/a>.\n\nJe me souviens que Strapi était encore en alpha/beta et que certains collègues me disaient que c’était un pari risqué, surtout que je découvrais à peine le monde de node.js.\n\n> Open source et français ? Je dis banco !\n\nJ’ai donc commencé à recréer mon site web à l’identique avec 11ty et Strapi. Même hébergement chez Digital Ocean, même serveur web, même contenu. J’avais fait pas mal d’optimisations de performances sur mon installation wordpress, j’étais donc impatient de comparer les résultats avec la nouvelle version statique.\n\nJ’en suis resté pantois ! Quasiment sans optimisation du côté statique, j’ai obtenu les résultats ci-dessous.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 53/100 sur Wordpress.'\n/>\n\nMalgré beaucoup d’efforts, je n’ai pas pu faire mieux. Je ne suis pas un expert en cache, je n’utilise pas de CDN et je me suis appuyé sur des plugins pour réaliser beaucoup de choses (php n’étant pas ma spécialité 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 97/100 en Jamstack.'\n/>\n\nPresque **zéro** configuration spéciale (j’étais trop impatient de tester) et j’ai atteint un score impressionnant. Je sais que les scores lighthouse ne font pas tout mais **53 contre 97**… Ça me va !\n\n## Embrassez-vous 🥰\n\nCes deux approches ont leurs avantages et leurs inconvénients. En tant que freelance, mes clients préfèrent ou demandent souvent Wordpress en raison de sa réputation. Je présente toujours une alternative Jamstack lorsque c’est possible, mais cela reste effrayant la plupart du temps par rapport à Wordpress. Je pense cependant qu’il sera plus facile d’utiliser la Jamstack avec le temps.\n\n## Encore et encore…\n\nNous voici maintenant une quarantaine et quelques mois plus tard et ce site fonctionne avec… [Nuxt.js](https://fr.nuxtjs.org/). Je sais, je suis désolé, je n’ai pas pu résister à la dernière fonctionnalité [\u003Cspan lang=\"en\">nuxt content\u003C/span>](https://content.nuxtjs.org/fr) de Nuxt.\n\nDu coup j’ai tout refait… et laissez-moi vous dire : **wow**, quelle expérience !\nJ’adore développer avec Nuxt. L’utilisation de \u003Cspan lang=\"en\">nuxt content\u003C/span> m’a permis de me concentrer sur le design et, évidemment, sur le contenu.\nPlus de client Apollo ni de requête graphQL, seulement du \u003Cspan lang=\"en\">markdown\u003C/span> et quelques promesses.\n\nAttention, j’aime beaucoup travailler avec Strapi et son interface graphQL mais pour les besoins de ce site, \u003Cspan lang=\"en\">nuxt content\u003C/span> fait le \u003Cspan lang=\"en\">job\u003C/span> (extrêmement bien).\n\nJ’utilise toujours Strapi pour téléverser, stocker et gérer les images, vidéos, gifs, etc. C’est peut-être trop pour ce que j’en fait mais j’aime savoir que je peux toujours y revenir si j’ai envie ! De plus, j’ai passé pas mal de temps à le mettre en place avec \u003Cspan lang=\"en\">OpenLiteSpeed\u003C/span> et je suis encore trop attaché à cette réussite pour la laisser tomber.\n\n## Et en fait à la fin\n\nWordpress, Jamstack, fait main… Est-ce vraiment important ? Pour moi, l’expérience de développement a été bien plus agréable en travaillant avec 11ty, nuxt.js et strapi qu’avec Wordpress.\n\nDu point de vue de la performance et de l’accessibilité, il semble également que ce soit le choix le plus judicieux. Ce n’est peut-être pas le cas à chaque fois ! ¯\\\\\\_(ツ)\\_/¯\n\nJ’ai hâte d’apprendre \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> et de tout recommencer à zéro !","src/content/articles/fr/the-day-I-jamd.mdx","57bd292bda8b6632","en-2022",{"id":134,"data":136,"body":142,"filePath":143,"digest":144,"rendered":145},{"title":137,"subtitle":138,"lang":68,"tags":139,"type":61,"slug":134,"createdAt":141},"Nico v2.0","2022 update of many things.",[140],"Freelance",["Date","2022-06-08T14:24:06.000Z"],"After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\n\n## Services\n\n### No more print\n\nEven though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for \"classic\" graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\n\n### Internet all the way\n\nOn the other hand, I spend my time **doing web stuff.** A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer **more specific web offerings,** in which I have specialised.\n\nThus, **accessibility** and **eco-design** become integrated expertises in my practice. They are no longer options on a quote but **my core business.**\n\n## The website\n\nI have reworked my website, especially the homepage and its content, to better reflect these decisions.\n\nI have also made several behavioural changes:\n\n- external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven't found a good reason to continue using this behaviour;\n- I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu);\n- \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\n- I only trigger animations if the user has not asked the system to reduce the amount motion [(reference)](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).\n\nI am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello [astro](https://astro.build/) 👀).\n\n## Le Nico\n\nOn a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\n\nI have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.","src/content/articles/en/2022.md","7b98592763cb0929",{"html":146,"metadata":147},"\u003Cp>After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\u003C/p>\n\u003Ch2 id=\"services\">Services\u003C/h2>\n\u003Ch3 id=\"no-more-print\">No more print\u003C/h3>\n\u003Cp>Even though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for “classic” graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\u003C/p>\n\u003Ch3 id=\"internet-all-the-way\">Internet all the way\u003C/h3>\n\u003Cp>On the other hand, I spend my time \u003Cstrong>doing web stuff.\u003C/strong> A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer \u003Cstrong>more specific web offerings,\u003C/strong> in which I have specialised.\u003C/p>\n\u003Cp>Thus, \u003Cstrong>accessibility\u003C/strong> and \u003Cstrong>eco-design\u003C/strong> become integrated expertises in my practice. They are no longer options on a quote but \u003Cstrong>my core business.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Cp>I have reworked my website, especially the homepage and its content, to better reflect these decisions.\u003C/p>\n\u003Cp>I have also made several behavioural changes:\u003C/p>\n\u003Cul>\n\u003Cli>external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven’t found a good reason to continue using this behaviour;\u003C/li>\n\u003Cli>I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a>;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\u003C/li>\n\u003Cli>I only trigger animations if the user has not asked the system to reduce the amount motion \u003Ca href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion\">(reference)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>I am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello \u003Ca href=\"https://astro.build/\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>On a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\u003C/p>\n\u003Cp>I have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.\u003C/p>",{"headings":148,"imagePaths":166,"frontmatter":167},[149,153,157,160,163],{"depth":150,"slug":151,"text":152},2,"services","Services",{"depth":154,"slug":155,"text":156},3,"no-more-print","No more print",{"depth":154,"slug":158,"text":159},"internet-all-the-way","Internet all the way",{"depth":150,"slug":161,"text":162},"the-website","The website",{"depth":150,"slug":164,"text":165},"le-nico","Le Nico",[],{"title":137,"subtitle":138,"lang":68,"slug":134,"excerpt":168,"tags":169,"type":61,"createdAt":170},"Changes in my services, the website and myself.",[140],"2022-06-08T14:24:06.000Z","en-2023",{"id":171,"data":173,"body":179,"filePath":180,"digest":181,"rendered":182},{"title":174,"subtitle":175,"lang":68,"tags":176,"type":61,"slug":171,"createdAt":177,"updatedAt":178},"Nico v2.5","Update 2023.",[140],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"This article will be updated when I have something new to share during the year 2023.\n\n## The website\n\n### Technologies\n\nOops... I (re)did it again.\n\nI have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself [in 2022 !](/en/articles/2022/#the-website)\n\nI will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\n\nMy \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I'm back to a solid **95/100** without any particular optimization. With some small efforts, I've reached the good old 100/100.\n\nI then did a work of modernization of the codebase. Hello CSS variables and goodbye `media queries`. In no particular order, here are some of the improvements I made:\n\n- `flexbox` and `grid` to adapt the layout to different screen sizes;\n- CSS variables for colors, font sizes and margins;\n- some `container queries`, just to try;\n- logical CSS properties (`inline` and `block` instead of `width` and `height` for example).\n\nI took this opportunity to publish [the source code](https://git.nardu.in/nardu.in/website-astro) on my git repository.\n\n**Update #1:** I've added [an RSS feed](/en/rss.xml) as I find myself using it more and more on other websites.\n\n### Analytics\n\nI removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\n\nIt's nice to see that your site is consulted, but if there is no other purpose behind it, it's an extra resource loaded for nothing by visitors. Maybe I'll reactivate the tracking when I have a use for it (other than flattering my ego).\n\nPrevious visit reports can be found at [this link.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Content\n\n- I've added a [work](/en/work/) page to list some of my projects.\n- I've also added [a page](/en/veille/) where I list some interesting things from around the web.\n\n## Additional projects\n\nI'm still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at [3-w.fr](https://3-w.fr/) (an address I am very proud of).\n\nI have to update it more regularly but I hope that the platform will help students progress!\n\n**More to come soon!**","src/content/articles/en/2023.md","489c650e66cced63",{"html":183,"metadata":184},"\u003Cp>This article will be updated when I have something new to share during the year 2023.\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oops… I (re)did it again.\u003C/p>\n\u003Cp>I have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself \u003Ca href=\"/en/articles/2022/#the-website\">in 2022 !\u003C/a>\u003C/p>\n\u003Cp>I will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\u003C/p>\n\u003Cp>My \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I’m back to a solid \u003Cstrong>95/100\u003C/strong> without any particular optimization. With some small efforts, I’ve reached the good old 100/100.\u003C/p>\n\u003Cp>I then did a work of modernization of the codebase. Hello CSS variables and goodbye \u003Ccode>media queries\u003C/code>. In no particular order, here are some of the improvements I made:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> and \u003Ccode>grid\u003C/code> to adapt the layout to different screen sizes;\u003C/li>\n\u003Cli>CSS variables for colors, font sizes and margins;\u003C/li>\n\u003Cli>some \u003Ccode>container queries\u003C/code>, just to try;\u003C/li>\n\u003Cli>logical CSS properties (\u003Ccode>inline\u003C/code> and \u003Ccode>block\u003C/code> instead of \u003Ccode>width\u003C/code> and \u003Ccode>height\u003C/code> for example).\u003C/li>\n\u003C/ul>\n\u003Cp>I took this opportunity to publish \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">the source code\u003C/a> on my git repository.\u003C/p>\n\u003Cp>\u003Cstrong>Update #1:\u003C/strong> I’ve added \u003Ca href=\"/en/rss.xml\">an RSS feed\u003C/a> as I find myself using it more and more on other websites.\u003C/p>\n\u003Ch3 id=\"analytics\">Analytics\u003C/h3>\n\u003Cp>I removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\u003C/p>\n\u003Cp>It’s nice to see that your site is consulted, but if there is no other purpose behind it, it’s an extra resource loaded for nothing by visitors. Maybe I’ll reactivate the tracking when I have a use for it (other than flattering my ego).\u003C/p>\n\u003Cp>Previous visit reports can be found at \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">this link.\u003C/a>\u003C/p>\n\u003Ch3 id=\"content\">Content\u003C/h3>\n\u003Cul>\n\u003Cli>I’ve added a \u003Ca href=\"/en/work/\">work\u003C/a> page to list some of my projects.\u003C/li>\n\u003Cli>I’ve also added \u003Ca href=\"/en/veille/\">a page\u003C/a> where I list some interesting things from around the web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"additional-projects\">Additional projects\u003C/h2>\n\u003Cp>I’m still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (an address I am very proud of).\u003C/p>\n\u003Cp>I have to update it more regularly but I hope that the platform will help students progress!\u003C/p>\n\u003Cp>\u003Cstrong>More to come soon!\u003C/strong>\u003C/p>",{"headings":185,"imagePaths":199,"frontmatter":200},[186,187,190,193,196],{"depth":150,"slug":161,"text":162},{"depth":154,"slug":188,"text":189},"technologies","Technologies",{"depth":154,"slug":191,"text":192},"analytics","Analytics",{"depth":154,"slug":194,"text":195},"content","Content",{"depth":150,"slug":197,"text":198},"additional-projects","Additional projects",[],{"title":174,"subtitle":175,"lang":68,"slug":171,"excerpt":201,"tags":202,"type":61,"createdAt":203,"updatedAt":204},"New changes.",[140],"2023-02-03T17:41:00.000Z","2023-05-17T17:41:00.000Z","en-faq",{"id":205,"data":207,"body":212,"filePath":213,"digest":214,"rendered":215},{"title":208,"subtitle":209,"lang":68,"tags":210,"type":61,"slug":205,"createdAt":211,"draft":72},"Accessibility and sobriety","Translation in progress, stay tuned ;)",[140],["Date","2022-06-22T15:34:45.000Z"],"[Go back to available articles](/en/articles)","src/content/articles/en/faq.md","82d516449896f6ca",{"html":216,"metadata":217},"\u003Cp>\u003Ca href=\"/en/articles\">Go back to available articles\u003C/a>\u003C/p>",{"headings":218,"imagePaths":219,"frontmatter":220},[],[],{"title":208,"subtitle":209,"lang":68,"slug":205,"draft":72,"excerpt":221,"tags":222,"type":61,"createdAt":223},"Why, how et and especially what.",[140],"2022-06-22T15:34:45.000Z","en-gratuiste",{"id":224,"data":226,"body":212,"filePath":230,"digest":231,"rendered":232},{"title":227,"subtitle":209,"lang":68,"tags":228,"type":61,"slug":224,"createdAt":229,"draft":72},"Gratuiste",[70,140],["Date","2017-05-27T07:47:36.000Z"],"src/content/articles/en/gratuiste.md","ebec75d19f0ff741",{"html":216,"metadata":233},{"headings":234,"imagePaths":235,"frontmatter":236},[],[],{"title":227,"subtitle":209,"lang":68,"slug":224,"draft":72,"excerpt":209,"tags":237,"type":61,"createdAt":238},[70,140],"2017-05-27T07:47:36.000Z","2022",{"id":239,"data":241,"body":245,"filePath":246,"digest":247,"rendered":248},{"title":137,"subtitle":242,"lang":16,"tags":243,"type":61,"slug":239,"createdAt":244},"Mise à jour 2022 de plein de trucs.",[140],["Date","2022-06-08T14:24:06.000Z"],"Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\n\n## Les services\n\n### J’arrête le print\n\nMême si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\n\n### J’internet à fond\n\nÀ l’inverse, je passe mon temps à **faire du web.** Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer **des offres web plus précises,** dans lesquelles je me suis spécialisé.\n\nAinsi, **l’accessibilité numérique** et **l’éco-conception** deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien **mon cœur de métier.**\n\n## Le site\n\nJ’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\n\nJ’ai également fait plusieurs changements de comportements :\n\n- les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\n- j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec [cette analyse](https://twitter.com/HTeuMeuLeu/status/1370310316496728065) de [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu) ;\n- [idem pour la favicon](https://twitter.com/HTeuMeuLeu/status/1370310312214339586) ;\n- je ne déclenche les animations que si l'utilisateur n'a pas demandé au système de minimiser la quantité d'animation ou de mouvement [(référence de l'option)](https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion).\n\nJe suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> 👀).\n\n## Le Nico\n\nD’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif [Good-it!](https://www.good-it.org/) et en participant activement à son développement.\n\nJ’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.","src/content/articles/fr/2022.md","2589166172138721",{"html":249,"metadata":250},"\u003Cp>Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\u003C/p>\n\u003Ch2 id=\"les-services\">Les services\u003C/h2>\n\u003Ch3 id=\"jarrête-le-print\">J’arrête le print\u003C/h3>\n\u003Cp>Même si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\u003C/p>\n\u003Ch3 id=\"jinternet-à-fond\">J’internet à fond\u003C/h3>\n\u003Cp>À l’inverse, je passe mon temps à \u003Cstrong>faire du web.\u003C/strong> Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer \u003Cstrong>des offres web plus précises,\u003C/strong> dans lesquelles je me suis spécialisé.\u003C/p>\n\u003Cp>Ainsi, \u003Cstrong>l’accessibilité numérique\u003C/strong> et \u003Cstrong>l’éco-conception\u003C/strong> deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien \u003Cstrong>mon cœur de métier.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Cp>J’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\u003C/p>\n\u003Cp>J’ai également fait plusieurs changements de comportements :\u003C/p>\n\u003Cul>\n\u003Cli>les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\u003C/li>\n\u003Cli>j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\">cette analyse\u003C/a> de \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a> ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\">idem pour la favicon\u003C/a> ;\u003C/li>\n\u003Cli>je ne déclenche les animations que si l’utilisateur n’a pas demandé au système de minimiser la quantité d’animation ou de mouvement \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion\">(référence de l’option)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>Je suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>D’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif \u003Ca href=\"https://www.good-it.org/\">Good-it!\u003C/a> et en participant activement à son développement.\u003C/p>\n\u003Cp>J’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.\u003C/p>",{"headings":251,"imagePaths":265,"frontmatter":266},[252,255,258,261,264],{"depth":150,"slug":253,"text":254},"les-services","Les services",{"depth":154,"slug":256,"text":257},"jarrête-le-print","J’arrête le print",{"depth":154,"slug":259,"text":260},"jinternet-à-fond","J’internet à fond",{"depth":150,"slug":262,"text":263},"le-site","Le site",{"depth":150,"slug":164,"text":165},[],{"title":137,"subtitle":242,"lang":16,"slug":239,"excerpt":267,"tags":268,"type":61,"createdAt":170},"Évolution des services, du site et de moi-même.",[140],"2023",{"id":269,"data":271,"body":276,"filePath":277,"digest":278,"rendered":279},{"title":174,"subtitle":272,"lang":16,"tags":273,"type":61,"slug":269,"createdAt":274,"updatedAt":275},"Mise à jour 2023.",[140],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"Cet article sera mis à jour lorsque j'aurai des nouveautés à partager au cours de l'année 2023.\n\n## Le site\n\n### Technologies\n\nOups… je l'ai encore (re)fait.\n\nJ'ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même [en 2022 !](/articles/2022/#le-site)\n\nJe ferai certainement un ou deux articles/fragments sur Astro et les extensions que j'ai utilisées. En tout cas c'était super comme expérience. Nuxt v2 n'étant plus vraiment à jour, les performances n'étaient plus au rendez-vous. Astro a complètement corrigé ça.\n\nMon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide **95/100** sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\n\nJ'ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les `media queries`. En vrac, voici certaines améliorations que j'ai mises en place :\n\n- `flexbox` et `grid` pour adapter la mise en page aux différentes tailles d'écran ;\n- variables CSS pour les couleurs, les tailles de polices et les marges ;\n- quelques \u003Cspan lang=\"en\">`container queries`\u003C/span> pour essayer ;\n- propriétés logiques CSS (\u003Cspan lang=\"en\">`inline`\u003C/span> et \u003Cspan lang=\"en\">`block`\u003C/span> à la place de \u003Cspan lang=\"en\">`width`\u003C/span> et \u003Cspan lang=\"en\">`height`\u003C/span> par exemple).\n\nJ'en ai profité pour publier [le code source](https://git.nardu.in/nardu.in/website-astro) sur mon dépôt git.\n\n**Mise à jour #1 :** J'ai ajouté [un flux RSS](/rss.xml) car j'utilise de plus en plus le RSS sur d'autres sites web.\n\n### Suivi des visites\n\nJ’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n'était collectée et je consultais rarement les rapports.\n\nC'est sympa de voir que son site est visité, mais s'il n'y a aucun autre but derrière, c'est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j'en aurai l'utilité (autre que flatter mon égo).\n\nLes rapports de visites précédents sont consultables sur [ce lien.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Contenu\n\n- J'ai ajouté une page [références](/references/) pour lister certains de mes projets.\n- J'ai également ajouté [une page](/veille/) où je répertorie des choses intéressantes trouvées sur le web.\n\n## Projets annexes\n\nJe continue d'enseigner le développement web cette année. Afin d'étoffer mes supports de cours, j'ai mis en place un mini site de documentation disponible à l'adresse [3-w.fr](https://3-w.fr/) (adresse dont je suis très fier).\n\nIl faut que j'arrive à être plus régulier dans sa mise à jour mais j'ai bon espoir que la plateforme aide les élèves à progresser !\n\n**Plus de trucs bientôt!**","src/content/articles/fr/2023.md","d97f4a5af975333f",{"html":280,"metadata":281},"\u003Cp>Cet article sera mis à jour lorsque j’aurai des nouveautés à partager au cours de l’année 2023.\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oups… je l’ai encore (re)fait.\u003C/p>\n\u003Cp>J’ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même \u003Ca href=\"/articles/2022/#le-site\">en 2022 !\u003C/a>\u003C/p>\n\u003Cp>Je ferai certainement un ou deux articles/fragments sur Astro et les extensions que j’ai utilisées. En tout cas c’était super comme expérience. Nuxt v2 n’étant plus vraiment à jour, les performances n’étaient plus au rendez-vous. Astro a complètement corrigé ça.\u003C/p>\n\u003Cp>Mon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide \u003Cstrong>95/100\u003C/strong> sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\u003C/p>\n\u003Cp>J’ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les \u003Ccode>media queries\u003C/code>. En vrac, voici certaines améliorations que j’ai mises en place :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> et \u003Ccode>grid\u003C/code> pour adapter la mise en page aux différentes tailles d’écran ;\u003C/li>\n\u003Cli>variables CSS pour les couleurs, les tailles de polices et les marges ;\u003C/li>\n\u003Cli>quelques \u003Cspan lang=\"en\">\u003Ccode>container queries\u003C/code>\u003C/span> pour essayer ;\u003C/li>\n\u003Cli>propriétés logiques CSS (\u003Cspan lang=\"en\">\u003Ccode>inline\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>block\u003C/code>\u003C/span> à la place de \u003Cspan lang=\"en\">\u003Ccode>width\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>height\u003C/code>\u003C/span> par exemple).\u003C/li>\n\u003C/ul>\n\u003Cp>J’en ai profité pour publier \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">le code source\u003C/a> sur mon dépôt git.\u003C/p>\n\u003Cp>\u003Cstrong>Mise à jour #1 :\u003C/strong> J’ai ajouté \u003Ca href=\"/rss.xml\">un flux RSS\u003C/a> car j’utilise de plus en plus le RSS sur d’autres sites web.\u003C/p>\n\u003Ch3 id=\"suivi-des-visites\">Suivi des visites\u003C/h3>\n\u003Cp>J’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n’était collectée et je consultais rarement les rapports.\u003C/p>\n\u003Cp>C’est sympa de voir que son site est visité, mais s’il n’y a aucun autre but derrière, c’est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j’en aurai l’utilité (autre que flatter mon égo).\u003C/p>\n\u003Cp>Les rapports de visites précédents sont consultables sur \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">ce lien.\u003C/a>\u003C/p>\n\u003Ch3 id=\"contenu\">Contenu\u003C/h3>\n\u003Cul>\n\u003Cli>J’ai ajouté une page \u003Ca href=\"/references/\">références\u003C/a> pour lister certains de mes projets.\u003C/li>\n\u003Cli>J’ai également ajouté \u003Ca href=\"/veille/\">une page\u003C/a> où je répertorie des choses intéressantes trouvées sur le web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"projets-annexes\">Projets annexes\u003C/h2>\n\u003Cp>Je continue d’enseigner le développement web cette année. Afin d’étoffer mes supports de cours, j’ai mis en place un mini site de documentation disponible à l’adresse \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (adresse dont je suis très fier).\u003C/p>\n\u003Cp>Il faut que j’arrive à être plus régulier dans sa mise à jour mais j’ai bon espoir que la plateforme aide les élèves à progresser !\u003C/p>\n\u003Cp>\u003Cstrong>Plus de trucs bientôt!\u003C/strong>\u003C/p>",{"headings":282,"imagePaths":294,"frontmatter":295},[283,284,285,288,291],{"depth":150,"slug":262,"text":263},{"depth":154,"slug":188,"text":189},{"depth":154,"slug":286,"text":287},"suivi-des-visites","Suivi des visites",{"depth":154,"slug":289,"text":290},"contenu","Contenu",{"depth":150,"slug":292,"text":293},"projets-annexes","Projets annexes",[],{"title":174,"subtitle":272,"lang":16,"slug":269,"excerpt":296,"tags":297,"type":61,"createdAt":203,"updatedAt":204},"Suite des évolutions.",[140],"after-effects-expressions",{"id":298,"data":300,"body":304,"filePath":305,"digest":306,"rendered":307},{"title":66,"subtitle":301,"lang":16,"tags":302,"type":61,"slug":298,"createdAt":303,"draft":72},"En cours de traduction, revenez bientôt ;)",[70],["Date","2019-04-24T09:00:00.000Z"],"[Retour aux articles](/articles)","src/content/articles/fr/after-effects-expressions.md","884d725859a7bab5",{"html":308,"metadata":309},"\u003Cp>\u003Ca href=\"/articles\">Retour aux articles\u003C/a>\u003C/p>",{"headings":310,"imagePaths":311,"frontmatter":312},[],[],{"title":66,"subtitle":301,"lang":16,"draft":72,"slug":298,"excerpt":301,"tags":313,"type":61,"createdAt":314},[70],"2019-04-24T09:00:00.000Z","faq",{"id":315,"data":317,"body":322,"filePath":323,"digest":324,"rendered":325},{"title":318,"subtitle":319,"lang":16,"tags":320,"type":61,"slug":315,"createdAt":321},"Accessibilité, sobriété et F.A.Q.","Explications sur ma vision et mon fonctionnement.",[140],["Date","2022-06-22T15:34:45.000Z"],"## l'Accessibilité\n\n### Quèsaco ?\n\nD'après [access42 :](https://access42.net)\n\n> L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\n\nAinsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que **n'importe quel visiteur** puisse l'utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais **ce n'est pas le cas !**\n\nLorsqu'un site est pensé et conçu avec l'accessibilité en tête, il ne prend **pas plus de temps** qu'un projet qui ne le fait pas. En revanche, **corriger** un site existant qui n'a pas bénéficié de cette réflexion en amont **demande beaucoup plus d'efforts.**\n\n### Pourquoi c'est important ?\n\nAprès avoir été sensibilisé à l'accessibilité et aux [situations frustrantes voire bloquantes](https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles) que rencontrent les personnes handicapées sur le web, j'ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m'a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\n\n## l'Éco-conception\n\n### Quèsaco ?\n\nD'après le collectif [\u003Cspan lang=\"en\">green it\u003C/span> :](https://www.greenit.fr)\n\n> L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\n\nIl s'agit ici pour moi de créer des produits les plus sobres possibles. C'est-à-dire de développer ou d'utiliser une fonctionnalité uniquement si elle est indispensable.\n\nPar exemple, mettre en place **un formulaire de contact** sur un site web implique plusieurs choses :\n\n- développer un formulaire\n- envoyer les données au serveur\n- vérifier les données envoyées\n- envoyer les données par mail\n- confirmer l'envoi du mail (en fournissant une copie)\n- gérer les erreurs à chaque étape\n\nUn site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d'effectuer ces opérations (ou un prestataire qui s'en charge). C'est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu'un formulaire. Dans le cas d'un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\n\n### Pourquoi c'est important ?\n\nL'éco-conception fait beaucoup de bien à la qualité globale d'un site et à l'expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\n\n## F.A.Q.\n\n### Cette démarche est-elle opportuniste ?\n\n**Non.** Il est vrai que l'accessibilité et, surtout, l'éco-conception, commencent à être « tendance ». On pourrait donc croire que j'en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c'est ma responsabilité de créer des sites web accessibles et éco-conçus **par défaut.**\n\n### Un site accessible est-il plus cher ?\n\n**Oui et non.** Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l'accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j'augmente mes tarifs suite à l'obtention de certifications relatives à mon activité.\n\n### Mon site sera-t-il 100 % accessible ?\n\n**Non,** je ne suis pas en mesure de garantir ou de certifier la conformité totale d'un site au [référentiel général d'amélioration de l'accessibilité.](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d'un site. Cependant, je peux vous accompagner avant et après l'audit afin d'anticiper puis de corriger les critères d'accessibilité requis. [Access42](https://access42.net/) et [Tanaguru](https://www.tanaguru.com/) font parties de ces entreprises spécialisées.\n\n### Pourquoi ne pas utiliser un outil automatique ?\n\nCar ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom [sous peine de procès](https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/)), ne sont pas des solutions micracles. Lisez [cet article](https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/) d'une experte en accessibilité et/ou [ce test](https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/) de différents outils pour en savoir plus.\n\n### Un site éco-conçu et accessible peut-il être beau ?\n\n**Oui, évidemment.** Je vous laisse juger par vous-même avec [cette liste](https://lowww.directory/) de sites éco-conçus. En ce qui concerne l'accessibilité, elle n'impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d'un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l'utilisation d'un produit.","src/content/articles/fr/faq.md","65e9e60bcd00806c",{"html":326,"metadata":327},"\u003Ch2 id=\"laccessibilité\">l’Accessibilité\u003C/h2>\n\u003Ch3 id=\"quèsaco\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après \u003Ca href=\"https://access42.net\">access42 :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Ainsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que \u003Cstrong>n’importe quel visiteur\u003C/strong> puisse l’utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais \u003Cstrong>ce n’est pas le cas !\u003C/strong>\u003C/p>\n\u003Cp>Lorsqu’un site est pensé et conçu avec l’accessibilité en tête, il ne prend \u003Cstrong>pas plus de temps\u003C/strong> qu’un projet qui ne le fait pas. En revanche, \u003Cstrong>corriger\u003C/strong> un site existant qui n’a pas bénéficié de cette réflexion en amont \u003Cstrong>demande beaucoup plus d’efforts.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>Après avoir été sensibilisé à l’accessibilité et aux \u003Ca href=\"https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles\">situations frustrantes voire bloquantes\u003C/a> que rencontrent les personnes handicapées sur le web, j’ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m’a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\u003C/p>\n\u003Ch2 id=\"léco-conception\">l’Éco-conception\u003C/h2>\n\u003Ch3 id=\"quèsaco-1\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après le collectif \u003Ca href=\"https://www.greenit.fr\">\u003Cspan lang=\"en\">green it\u003C/span> :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Il s’agit ici pour moi de créer des produits les plus sobres possibles. C’est-à-dire de développer ou d’utiliser une fonctionnalité uniquement si elle est indispensable.\u003C/p>\n\u003Cp>Par exemple, mettre en place \u003Cstrong>un formulaire de contact\u003C/strong> sur un site web implique plusieurs choses :\u003C/p>\n\u003Cul>\n\u003Cli>développer un formulaire\u003C/li>\n\u003Cli>envoyer les données au serveur\u003C/li>\n\u003Cli>vérifier les données envoyées\u003C/li>\n\u003Cli>envoyer les données par mail\u003C/li>\n\u003Cli>confirmer l’envoi du mail (en fournissant une copie)\u003C/li>\n\u003Cli>gérer les erreurs à chaque étape\u003C/li>\n\u003C/ul>\n\u003Cp>Un site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d’effectuer ces opérations (ou un prestataire qui s’en charge). C’est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu’un formulaire. Dans le cas d’un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important-1\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>L’éco-conception fait beaucoup de bien à la qualité globale d’un site et à l’expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\u003C/p>\n\u003Ch2 id=\"faq\">F.A.Q.\u003C/h2>\n\u003Ch3 id=\"cette-démarche-est-elle-opportuniste\">Cette démarche est-elle opportuniste ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non.\u003C/strong> Il est vrai que l’accessibilité et, surtout, l’éco-conception, commencent à être « tendance ». On pourrait donc croire que j’en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c’est ma responsabilité de créer des sites web accessibles et éco-conçus \u003Cstrong>par défaut.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"un-site-accessible-est-il-plus-cher\">Un site accessible est-il plus cher ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui et non.\u003C/strong> Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l’accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j’augmente mes tarifs suite à l’obtention de certifications relatives à mon activité.\u003C/p>\n\u003Ch3 id=\"mon-site-sera-t-il-100-accessible\">Mon site sera-t-il 100 % accessible ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non,\u003C/strong> je ne suis pas en mesure de garantir ou de certifier la conformité totale d’un site au \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité.\u003C/a> Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d’un site. Cependant, je peux vous accompagner avant et après l’audit afin d’anticiper puis de corriger les critères d’accessibilité requis. \u003Ca href=\"https://access42.net/\">Access42\u003C/a> et \u003Ca href=\"https://www.tanaguru.com/\">Tanaguru\u003C/a> font parties de ces entreprises spécialisées.\u003C/p>\n\u003Ch3 id=\"pourquoi-ne-pas-utiliser-un-outil-automatique\">Pourquoi ne pas utiliser un outil automatique ?\u003C/h3>\n\u003Cp>Car ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom \u003Ca href=\"https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/\">sous peine de procès\u003C/a>), ne sont pas des solutions micracles. Lisez \u003Ca href=\"https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/\">cet article\u003C/a> d’une experte en accessibilité et/ou \u003Ca href=\"https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/\">ce test\u003C/a> de différents outils pour en savoir plus.\u003C/p>\n\u003Ch3 id=\"un-site-éco-conçu-et-accessible-peut-il-être-beau\">Un site éco-conçu et accessible peut-il être beau ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui, évidemment.\u003C/strong> Je vous laisse juger par vous-même avec \u003Ca href=\"https://lowww.directory/\">cette liste\u003C/a> de sites éco-conçus. En ce qui concerne l’accessibilité, elle n’impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d’un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l’utilisation d’un produit.\u003C/p>",{"headings":328,"imagePaths":362,"frontmatter":363},[329,332,335,338,341,343,345,347,350,353,356,359],{"depth":150,"slug":330,"text":331},"laccessibilité","l’Accessibilité",{"depth":154,"slug":333,"text":334},"quèsaco","Quèsaco ?",{"depth":154,"slug":336,"text":337},"pourquoi-cest-important","Pourquoi c’est important ?",{"depth":150,"slug":339,"text":340},"léco-conception","l’Éco-conception",{"depth":154,"slug":342,"text":334},"quèsaco-1",{"depth":154,"slug":344,"text":337},"pourquoi-cest-important-1",{"depth":150,"slug":315,"text":346},"F.A.Q.",{"depth":154,"slug":348,"text":349},"cette-démarche-est-elle-opportuniste","Cette démarche est-elle opportuniste ?",{"depth":154,"slug":351,"text":352},"un-site-accessible-est-il-plus-cher","Un site accessible est-il plus cher ?",{"depth":154,"slug":354,"text":355},"mon-site-sera-t-il-100-accessible","Mon site sera-t-il 100 % accessible ?",{"depth":154,"slug":357,"text":358},"pourquoi-ne-pas-utiliser-un-outil-automatique","Pourquoi ne pas utiliser un outil automatique ?",{"depth":154,"slug":360,"text":361},"un-site-éco-conçu-et-accessible-peut-il-être-beau","Un site éco-conçu et accessible peut-il être beau ?",[],{"title":318,"subtitle":319,"lang":16,"slug":315,"excerpt":364,"tags":365,"type":61,"createdAt":223},"Pourquoi, comment et surtout quèsaco.",[140],"gratuiste",{"id":366,"data":368,"body":374,"filePath":375,"digest":376,"rendered":377},{"title":227,"subtitle":369,"lang":16,"tags":370,"type":61,"slug":366,"createdAt":372,"updatedAt":373},"Ou le travail gratuit.",[371,140],"Graphisme",["Date","2017-05-27T07:47:36.000Z"],["Date","2022-12-27T15:36:06.000Z"],"## Gratuiste, qu’est-ce que c’est ?\n\nDans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc. \nDe plus en plus, la communauté s’élève contre ces pratiques et les [dénonce.](https://twitter.com/PayeTonAffiche)\n\n> “ On n’est pas des gratuistes ! ”\n\nComprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez [cette vidéo](https://youtu.be/essNmNOrQto) qui transpose ces pratiques à des métiers “ standards ” et [celle-ci](https://youtu.be/DsstOs-K7gk) qui explique en détails le processus actuel.\n\n## T’es débile du coup ?\n\nJ’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\n\nÉtant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre. \nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\n\n## Le concept\n\nJe compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux. \nCe type de prestation porte le nom de “ **pro bono publico** ” – “ **pour le bien public** ”.\n\nCette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\n\n> Graphiste pro bono, pourquoi pas ?\n\n## Quels genres de services ?\n\nEn toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\n\n### En résumé :\n\n- maquette de site web\n- intégration front-end (en dur ou via wordpress) du site\n- gestion de la mise en ligne du site\n- newsletter (design et/ou intégration)\n- flyers\n- autres petites demandes\n\nVous pouvez avoir un aperçu de mon travail [sur ce même site.](/) J’ai déjà eu l’occasion de travailler pour :\n\n- [Cygnal](/projets/cygnal)\n- [OpenMole](https://openmole.org/)\n- [Good-it](https://good-it.org)\n\n## Dans quelles conditions ?\n\n- l’association doit être active\n- elle doit porter des valeurs que je partage\n- elle doit pouvoir me montrer ses actions\n- elle ne doit pas avoir les moyens de se payer un graphiste\n\n## C’est un peu trop beau pour être vrai ton truc…\n\nIl faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\n\nSi vous êtes intéressés, [envoyez-moi un mail !](mailto:contac@nardu.in)\n\n## Qu’est-ce que t’y gagnes toi ?\n\nSimplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.","src/content/articles/fr/gratuiste.md","80c20493583a842c",{"html":378,"metadata":379},"\u003Ch2 id=\"gratuiste-quest-ce-que-cest\">Gratuiste, qu’est-ce que c’est ?\u003C/h2>\n\u003Cp>Dans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc.\u003Cbr>\nDe plus en plus, la communauté s’élève contre ces pratiques et les \u003Ca href=\"https://twitter.com/PayeTonAffiche\">dénonce.\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“ On n’est pas des gratuistes ! ”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Comprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez \u003Ca href=\"https://youtu.be/essNmNOrQto\">cette vidéo\u003C/a> qui transpose ces pratiques à des métiers “ standards ” et \u003Ca href=\"https://youtu.be/DsstOs-K7gk\">celle-ci\u003C/a> qui explique en détails le processus actuel.\u003C/p>\n\u003Ch2 id=\"tes-débile-du-coup\">T’es débile du coup ?\u003C/h2>\n\u003Cp>J’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\u003C/p>\n\u003Cp>Étant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre.\u003Cbr>\nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\u003C/p>\n\u003Ch2 id=\"le-concept\">Le concept\u003C/h2>\n\u003Cp>Je compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux.\u003Cbr>\nCe type de prestation porte le nom de “ \u003Cstrong>pro bono publico\u003C/strong> ” – “ \u003Cstrong>pour le bien public\u003C/strong> ”.\u003C/p>\n\u003Cp>Cette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Graphiste pro bono, pourquoi pas ?\u003C/p>\n\u003C/blockquote>\n\u003Ch2 id=\"quels-genres-de-services\">Quels genres de services ?\u003C/h2>\n\u003Cp>En toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\u003C/p>\n\u003Ch3 id=\"en-résumé\">En résumé :\u003C/h3>\n\u003Cul>\n\u003Cli>maquette de site web\u003C/li>\n\u003Cli>intégration front-end (en dur ou via wordpress) du site\u003C/li>\n\u003Cli>gestion de la mise en ligne du site\u003C/li>\n\u003Cli>newsletter (design et/ou intégration)\u003C/li>\n\u003Cli>flyers\u003C/li>\n\u003Cli>autres petites demandes\u003C/li>\n\u003C/ul>\n\u003Cp>Vous pouvez avoir un aperçu de mon travail \u003Ca href=\"/\">sur ce même site.\u003C/a> J’ai déjà eu l’occasion de travailler pour :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"/projets/cygnal\">Cygnal\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://openmole.org/\">OpenMole\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://good-it.org\">Good-it\u003C/a>\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"dans-quelles-conditions\">Dans quelles conditions ?\u003C/h2>\n\u003Cul>\n\u003Cli>l’association doit être active\u003C/li>\n\u003Cli>elle doit porter des valeurs que je partage\u003C/li>\n\u003Cli>elle doit pouvoir me montrer ses actions\u003C/li>\n\u003Cli>elle ne doit pas avoir les moyens de se payer un graphiste\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"cest-un-peu-trop-beau-pour-être-vrai-ton-truc\">C’est un peu trop beau pour être vrai ton truc…\u003C/h2>\n\u003Cp>Il faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\u003C/p>\n\u003Cp>Si vous êtes intéressés, \u003Ca href=\"mailto:contac@nardu.in\">envoyez-moi un mail !\u003C/a>\u003C/p>\n\u003Ch2 id=\"quest-ce-que-ty-gagnes-toi\">Qu’est-ce que t’y gagnes toi ?\u003C/h2>\n\u003Cp>Simplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.\u003C/p>",{"headings":380,"imagePaths":405,"frontmatter":406},[381,384,387,390,393,396,399,402],{"depth":150,"slug":382,"text":383},"gratuiste-quest-ce-que-cest","Gratuiste, qu’est-ce que c’est ?",{"depth":150,"slug":385,"text":386},"tes-débile-du-coup","T’es débile du coup ?",{"depth":150,"slug":388,"text":389},"le-concept","Le concept",{"depth":150,"slug":391,"text":392},"quels-genres-de-services","Quels genres de services ?",{"depth":154,"slug":394,"text":395},"en-résumé","En résumé :",{"depth":150,"slug":397,"text":398},"dans-quelles-conditions","Dans quelles conditions ?",{"depth":150,"slug":400,"text":401},"cest-un-peu-trop-beau-pour-être-vrai-ton-truc","C’est un peu trop beau pour être vrai ton truc…",{"depth":150,"slug":403,"text":404},"quest-ce-que-ty-gagnes-toi","Qu’est-ce que t’y gagnes toi ?",[],{"title":227,"subtitle":369,"lang":16,"slug":366,"excerpt":407,"tags":408,"type":61,"createdAt":238,"updatedAt":409},"J’ai cherché un moyen de mettre mes compétences au service d’autrui et je pense avoir trouvé: je vais travailler gratuitement pour des associations.",[371,140],"2022-12-27T15:36:06.000Z","video-compression",{"id":410,"data":412,"body":304,"filePath":417,"digest":418,"rendered":419},{"title":413,"subtitle":301,"lang":16,"tags":414,"type":61,"slug":410,"createdAt":415,"updatedAt":416,"draft":72},"Compression vidéo",[70],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"src/content/articles/fr/video-compression.md","2296c41874b23b3d",{"html":308,"metadata":420},{"headings":421,"imagePaths":422,"frontmatter":423},[],[],{"title":413,"subtitle":301,"lang":16,"draft":72,"slug":410,"excerpt":424,"tags":425,"type":61,"createdAt":426,"updatedAt":170},"Pas encore traduit",[70],"2021-05-05T09:00:00.000Z","fragments",["Map",429,430,440,441,451,452,462,463,473,474,484,485,502,503,517,518,570,571,634,635,696,697,713,714,748,749,782,783,806,807,848,849],"buttons",{"id":429,"data":431,"body":437,"filePath":438,"digest":439,"deferredRender":72},{"title":432,"subtitle":433,"lang":16,"tags":434,"type":427,"slug":429,"createdAt":436,"code":72,"draft":72},"Effets de survol de boutons","Simples mais efficaces.",[435],"CSS",["Date","2020-10-08T09:00:00.000Z"],"## Styles généraux\n\nTous les boutons présents utilisent ces styles comme base en guise de « reset » :\n\n> N'oubliez pas de préfixer si besoin !\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Ajout d'icône\n\n\u003Cbutton role='none' class='btn btn-icon'>\n\t\u003Cspan>Icône\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('./assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double volet\n\n\u003Cbutton role='none' class='btn btn-rideau'>\n\t\u003Cspan>Volet\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Dégradé animé\n\n\u003Cbutton role='none' class='btn btn-gradient'>\n\t\u003Cspan>Dégradé\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Échelle non desctructrice\n\n\u003Cbutton role='none' class='btn btn-scale'>\n\t\u003Cspan>Échelle\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/fr/buttons.mdx","f5d7b03520f96b04","image-full",{"id":440,"data":442,"body":448,"filePath":449,"digest":450,"deferredRender":72},{"title":443,"subtitle":444,"lang":16,"tags":445,"type":427,"slug":440,"createdAt":446,"updatedAt":447},"Image pleine largeur","Casser le conteneur.",[435],["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Image inline\n\nOn est parfois obligé d'utiliser des images dans des balises `img` plutôt que dans un `background` en css. Comment faire alors pour que l'image sorte de son conteneur pour en faire une bannière ? Exemple pratique à partir de ce même site.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_container_9e3939b3ae.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Contexte\n\nConsidérons le html suivant :\n\n```html\n\u003Csection class=\"container\">\n\t\u003Cdiv class=\"hero\">\n\t\t\u003Cimg class=\"hero__image\" src=\"hero.img\" />\n\t\u003C/div>\n\u003C/section>\n```\n\nEt le style suivant :\n\n```css\n.container {\n\tpadding: 0 14px;\n\tmargin-left: auto;\n\tmargin-right: auto;\n\tmax-width: 1040px;\n}\nimg {\n\tmax-width: 100%;\n\theight: auto;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_original_d49f0d11bf.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Déborder du conteneur\n\nAfin de faire prendre à l'image toute la largeur, on agit sur son conteneur :\n\n```css\n.hero {\n\tmargin-left: calc(50% - 50vw);\n\tposition: relative;\n\twidth: 100vw;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_full_2a902f9539.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Faire une bannière\n\nOn peut alors réduire la hauteur du conteneur pour obtenir une bannière plutôt que l'image entière et faire correspondre la hauteur de l'image à la hauteur du conteneur :\n\n```css\n.hero {\n\theight: 200px;\n}\n.hero__image {\n\theight: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_height_81b4ce969a.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nIl faut ensuite forcer l'image à prendre toute la largeur du conteneur :\n\n```css\n.hero__image {\n\twidth: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_deformed_479046d2cb.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nPas top…\n\n### J'ai cassé l'image…\n\n**ENFIN** le code magique pour redonner son ratio à l'image sans la déformer :\n\n```css\n.hero__image {\n\tobject-fit: cover;\n\tobject-position: center; /* à positionner comme on veut */\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_6c164e82b3.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nCette technique s'apparente à l'utilisation d'une image de background mais en dur 😁\n\n## TL;DR\n\nLe code complet :\n\n```css\n.hero {\n\tmargin-left: calc(50% - 50vw);\n\tposition: relative;\n\twidth: 100vw;\n\theight: 200px;\n}\n.hero__image {\n\twidth: 100%;\n\theight: 100%;\n\t-o-object-fit: cover;\n\tobject-fit: cover;\n\t-o-object-position: center;\n\tobject-position: center;\n}\n```","src/content/fragments/fr/image-full.mdx","91ebd97eef5cb8a4","super-cookies",{"id":451,"data":453,"body":459,"filePath":460,"digest":461,"deferredRender":72},{"title":454,"subtitle":455,"lang":16,"tags":456,"type":427,"slug":451,"createdAt":458},"Les meilleurs cookies","Des gâteaux sans consentement.",[457],"cuisine",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Version végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 3/4 de l'aquafaba de 400g de pois chiche (l'eau des pois chiche)\n- 125 grammes d'huile de noix de coco\n- 2 cuillères à café de sirop d'érable\n- 1 plaquette de chocolat (noir) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre si besoin l'huile de noix de coco à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (huile, aquafaba, sirop d'érable)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Version non végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 1 œuf\n- 125 grammes de beurre fondu\n- 2 cuillères à café de miel\n- 1 plaquette de chocolat (noir/blanc/les deux) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre le beurre à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (beurre fondu, œuf, miel)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Notes\n\nLe chocolat peut-être remplacé par n'importe quoi comme des noix, des raisins secs, des légos… (mangez pas des légos soyez sérieux).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Tous les ingrédients mélangés forment une pâte marron.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Les cookies cuits sont bombés et très moelleux.'\n/>","src/content/fragments/fr/super-cookies.mdx","f7a802e0b68cb04a","en-image-full",{"id":462,"data":464,"body":470,"filePath":471,"digest":472,"deferredRender":72},{"title":465,"subtitle":209,"lang":68,"tags":466,"type":467,"slug":462,"createdAt":468,"updatedAt":469,"draft":72},"Full width image",[435],"snippets",["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"[Go back to available snippets](/en/snippets)","src/content/fragments/en/image-full.mdx","2e3dddf593f6d72f","en-super-cookies",{"id":473,"data":475,"body":481,"filePath":482,"digest":483,"deferredRender":72},{"title":476,"subtitle":477,"lang":68,"tags":478,"type":467,"slug":473,"createdAt":480},"The best cookies","Consentless biscuits.",[479],"food",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 tablespoon of baking powder\n- 3/4 of aquafaba from 400g of chickpea (chickpea water)\n- 125 grams of coconut oil\n- 2 teaspoons of maple syrup\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- if necessary, melt the coconut oil over low heat\n- meanwhile, mix all the dry ingredients\n- add all liquid ingredients (oil, aquafaba, maple syrup)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Non vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 table spoon of baking powder\n- 1 egg\n- 125 grams of melted butter\n- 2 teaspoons of honey\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- melt butter over low heat\n- meanwhile, mix all dry ingredients\n- add all liquid ingredients (melted butter, egg, honey)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Notes\n\nChocolate can be replaced by anything like nuts, raisins, legos... (don't eat legos be reasonable).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='All ingredients mixed together to form a brown paste.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='The cookies are round and soft after baking.'\n/>","src/content/fragments/en/super-cookies.mdx","b0c67adad40c177c","array-vs-array",{"id":484,"data":486,"body":492,"filePath":493,"digest":494,"rendered":495},{"title":487,"subtitle":488,"lang":16,"tags":489,"type":427,"slug":484,"createdAt":491,"draft":72},"Filtrer un array avec un autre array","En cours de traduction.",[490],"nuxt.js",["Date","2022-06-08T14:24:06.000Z"],"[Voir les fragments disponibles](/fragments)","src/content/fragments/fr/array-vs-array.md","7321d444177c3841",{"html":496,"metadata":497},"\u003Cp>\u003Ca href=\"/fragments\">Voir les fragments disponibles\u003C/a>\u003C/p>",{"headings":498,"imagePaths":499,"frontmatter":500},[],[],{"title":487,"subtitle":488,"lang":16,"draft":72,"slug":484,"createdAt":170,"excerpt":488,"tags":501,"type":427},[490],"toulouse-fun",{"id":502,"data":504,"body":492,"filePath":509,"digest":510,"rendered":511},{"title":505,"subtitle":488,"lang":16,"tags":506,"type":427,"slug":502,"createdAt":508,"draft":72},"Toulouse yourself",[507],"lifestyle",["Date","2022-06-22T15:34:45.000Z"],"src/content/fragments/fr/toulouse-fun.md","a0c25b438b34c05e",{"html":496,"metadata":512},{"headings":513,"imagePaths":514,"frontmatter":515},[],[],{"title":505,"subtitle":488,"lang":16,"draft":72,"slug":502,"createdAt":223,"excerpt":488,"tags":516,"type":427},[507],"en-toulouse-fun",{"id":517,"data":519,"body":523,"filePath":524,"digest":525,"rendered":526},{"title":505,"subtitle":520,"lang":68,"tags":521,"type":467,"slug":517,"createdAt":522},"Only the bestest",[507],["Date","2022-06-22T15:34:45.000Z"],"Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite. \n**It's always a good idea to make a reservation!**\n\n## Restaurants\n\n### French cuisine\n\n- [Solides](https://www.solides.fr/) — semi-gastronomic\n- [Les impulsifs](https://les-impulsifs-toulouse.eatbu.com/?lang=en) — semi-gastronomic\n- [Sixta](https://sixta-toulouse.fr/) — vege/vegan/gluten friendly\n- [Attila](https://attila.site-solocal.com/) — great **fish restaurant,** just above the Victor Hugo market\n- [Chez Emile](https://www.restaurant-emile.com/) - best [cassoulet](https://en.wikipedia.org/wiki/Cassoulet) in town (or so I'm told)\n\n### Korean\n\n- [Le ptit Louis](https://leptitlouis.fr/) — best of its kind, **only for lunch**\n- [Kongbap](https://kong-bap.com/) — street-food like\n\n### Japanese\n\n- [Iori](https://www.iori.fr/) — best ramen\n- [Japoyaki](https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402) — best sushi/sashimis\n\n## Drinks and snacks\n\n### Bars\n\n- [Le Bièrographe](https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327) — all time favourite, **check out the typical toulouse basement**\n- [A Taula](https://www.facebook.com/ataulatolosa/) — all time favourite in summer, **amazing terrace,** also: great tapas\n- [The Hopscotch Pub](https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385) — good beers, good whiskies, good cocktials, good food\n\n### Cafés & tea rooms\n\n- [Bapz](https://www.bapz.fr/contact) — Excellent pastries / hot beverages\n- [Ô thé divin](https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/) — nice lunch options\n- [Les Rêveries d’Hercule](https://www.lesreveriesdhercule.com/) — Pottery Café, relaxing activity (ceramics need to be baked, there'll be a delay to get them back)\n- Bonus: the best bakeries in [Carmes](https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872) and [Saint-Aubin](https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694) — croissants, baguettes **traditions**, chocolatines and more\n\n### Wine shops\n\n- [l'envie du sud](https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930) — amazing selection of wines and other spirits, excellent advice from the staff\n- [enoteca](https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952) — smaller selection but more beers and great advice from the staff as well\n\n## Other delights\n\n### Ice creams\n\n- [Forno gusto](https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450) — only in the summer\n- [Moustache](https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540) — lots of flavours\n\n### Cheese shop\n\n- [Xavier](https://xavier.fr/) — one of the **best of the country**, two shops in Toulouse, including one at Victor Hugo market\n- [Massembea](https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490) — a serious contender in Toulouse (weird hours)\n\n### Delicatessen\n\n- [Café Bacquié](http://cafe-bacquie.com/) — stock up on fine foods, coffees, teas and other great quality products","src/content/fragments/en/toulouse-fun.md","370491cc68079e8c",{"html":527,"metadata":528},"\u003Cp>Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite.\u003Cbr>\n\u003Cstrong>It’s always a good idea to make a reservation!\u003C/strong>\u003C/p>\n\u003Ch2 id=\"restaurants\">Restaurants\u003C/h2>\n\u003Ch3 id=\"french-cuisine\">French cuisine\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.solides.fr/\">Solides\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://les-impulsifs-toulouse.eatbu.com/?lang=en\">Les impulsifs\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://sixta-toulouse.fr/\">Sixta\u003C/a> — vege/vegan/gluten friendly\u003C/li>\n\u003Cli>\u003Ca href=\"https://attila.site-solocal.com/\">Attila\u003C/a> — great \u003Cstrong>fish restaurant,\u003C/strong> just above the Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.restaurant-emile.com/\">Chez Emile\u003C/a> - best \u003Ca href=\"https://en.wikipedia.org/wiki/Cassoulet\">cassoulet\u003C/a> in town (or so I’m told)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"korean\">Korean\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://leptitlouis.fr/\">Le ptit Louis\u003C/a> — best of its kind, \u003Cstrong>only for lunch\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://kong-bap.com/\">Kongbap\u003C/a> — street-food like\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"japanese\">Japanese\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.iori.fr/\">Iori\u003C/a> — best ramen\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402\">Japoyaki\u003C/a> — best sushi/sashimis\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"drinks-and-snacks\">Drinks and snacks\u003C/h2>\n\u003Ch3 id=\"bars\">Bars\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327\">Le Bièrographe\u003C/a> — all time favourite, \u003Cstrong>check out the typical toulouse basement\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.facebook.com/ataulatolosa/\">A Taula\u003C/a> — all time favourite in summer, \u003Cstrong>amazing terrace,\u003C/strong> also: great tapas\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385\">The Hopscotch Pub\u003C/a> — good beers, good whiskies, good cocktials, good food\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cafés--tea-rooms\">Cafés & tea rooms\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.bapz.fr/contact\">Bapz\u003C/a> — Excellent pastries / hot beverages\u003C/li>\n\u003Cli>\u003Ca href=\"https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/\">Ô thé divin\u003C/a> — nice lunch options\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lesreveriesdhercule.com/\">Les Rêveries d’Hercule\u003C/a> — Pottery Café, relaxing activity (ceramics need to be baked, there’ll be a delay to get them back)\u003C/li>\n\u003Cli>Bonus: the best bakeries in \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872\">Carmes\u003C/a> and \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694\">Saint-Aubin\u003C/a> — croissants, baguettes \u003Cstrong>traditions\u003C/strong>, chocolatines and more\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"wine-shops\">Wine shops\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930\">l’envie du sud\u003C/a> — amazing selection of wines and other spirits, excellent advice from the staff\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952\">enoteca\u003C/a> — smaller selection but more beers and great advice from the staff as well\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"other-delights\">Other delights\u003C/h2>\n\u003Ch3 id=\"ice-creams\">Ice creams\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450\">Forno gusto\u003C/a> — only in the summer\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540\">Moustache\u003C/a> — lots of flavours\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cheese-shop\">Cheese shop\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://xavier.fr/\">Xavier\u003C/a> — one of the \u003Cstrong>best of the country\u003C/strong>, two shops in Toulouse, including one at Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490\">Massembea\u003C/a> — a serious contender in Toulouse (weird hours)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"delicatessen\">Delicatessen\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"http://cafe-bacquie.com/\">Café Bacquié\u003C/a> — stock up on fine foods, coffees, teas and other great quality products\u003C/li>\n\u003C/ul>",{"headings":529,"imagePaths":566,"frontmatter":567},[530,533,536,539,542,545,548,551,554,557,560,563],{"depth":150,"slug":531,"text":532},"restaurants","Restaurants",{"depth":154,"slug":534,"text":535},"french-cuisine","French cuisine",{"depth":154,"slug":537,"text":538},"korean","Korean",{"depth":154,"slug":540,"text":541},"japanese","Japanese",{"depth":150,"slug":543,"text":544},"drinks-and-snacks","Drinks and snacks",{"depth":154,"slug":546,"text":547},"bars","Bars",{"depth":154,"slug":549,"text":550},"cafés--tea-rooms","Cafés & tea rooms",{"depth":154,"slug":552,"text":553},"wine-shops","Wine shops",{"depth":150,"slug":555,"text":556},"other-delights","Other delights",{"depth":154,"slug":558,"text":559},"ice-creams","Ice creams",{"depth":154,"slug":561,"text":562},"cheese-shop","Cheese shop",{"depth":154,"slug":564,"text":565},"delicatessen","Delicatessen",[],{"title":505,"subtitle":520,"lang":68,"slug":517,"excerpt":568,"tags":569,"type":467,"createdAt":223},"Gonna have to trust me on this ¯\\_(ツ)_/¯",[507],"acme-sh-tls-cert",{"id":570,"data":572,"body":578,"filePath":579,"digest":580,"rendered":581},{"title":573,"subtitle":574,"lang":16,"tags":575,"type":427,"slug":570,"createdAt":577},"Certificates TLS robustes avec acme.sh","384-bit de https",[576],"sécurité",["Date","2022-06-08T14:24:06.000Z"],"## Attention\n\nJe ne suis pas du tout un expert en sécurité. J'aime juste les trucs nouveaux et stylés des internets. \nC'est pourquoi j'ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J'ai maintenant un joli 100/100 sur [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nVous pouvez en apprendre (beaucoup) plus [ici](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) et sur les liens cités (en anglais).\n\n## Prérequis\n\n### Installer acme.sh\n\nPour des raisons de simplicité et d'automatisation, j'utilise [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changer l'authorité par défaut\n\nPar défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let's Encrypt car, d'après acme.sh, ils sont les seuls à proposer des certificats ECC.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Utiliser l'api DNS\n\nSi vous en avez la possibilité, la façon la plus simple de générer un certificat est via l'api de votre fournisseur DNS. acme.sh supporte [énormément](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) de fournisseurs DNS.\n\n### Definir la clé api\n\nSuivez la [documentation](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) pour votre fournisseur DNS, généralement:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Émettre le certificat\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Utiliser le mode standalone\n\nSi vous n'avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s'occupe de toutes les vérifications.\n\nLe port `80` doit être disponible.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Exemples\n\n### Multi domaines standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domaine DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Étapes supplémentaires\n\nLe certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\n\n### Version TLS\n\nLimiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu [la différence de compatibilité de 5%](https://caniuse.com/?search=tls%201.) avec 1.2).\n\n### HSTS\n\nUtiliser le header [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/).\n\n```\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Suite cryptographique\n\nUtiliser une suite cryptographique récente et robuste. C'est ici que mes connaissances deviennent limitées… J'ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\n\nJ'avais basé ma première suite sur [cette liste](https://tls.imirhil.fr/ciphers), en la comparant avec celle de la compatibilité (d'anciens ?) [navigateurs](https://tls.imirhil.fr/suite).\n\nJ'ai ensuite demandé à [Aeris](https://twitter.com/aeris22), le créateur de [tls.imirhil.fr](https://tls.imirhil.fr), ses conseils sur cette suite. Il m'a recommandé d'utiliser :\n\n```\nECDHE+AES:ECDHE+CHACHA20\n```\n\nAfin d'atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\n\n```\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/fr/acme-sh-tls-cert.md","82e6d91747c28ea5",{"html":582,"metadata":583},"\u003Ch2 id=\"attention\">Attention\u003C/h2>\n\u003Cp>Je ne suis pas du tout un expert en sécurité. J’aime juste les trucs nouveaux et stylés des internets.\u003Cbr>\nC’est pourquoi j’ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J’ai maintenant un joli 100/100 sur \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>Vous pouvez en apprendre (beaucoup) plus \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">ici\u003C/a> et sur les liens cités (en anglais).\u003C/p>\n\u003Ch2 id=\"prérequis\">Prérequis\u003C/h2>\n\u003Ch3 id=\"installer-acmesh\">Installer acme.sh\u003C/h3>\n\u003Cp>Pour des raisons de simplicité et d’automatisation, j’utilise \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\"># pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">curl\u003C/span>\u003Cspan style=\"color:#98C379\"> https://get.acme.sh\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> | \u003C/span>\u003Cspan style=\"color:#61AFEF\">sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> -s\u003C/span>\u003Cspan style=\"color:#98C379\"> email=mail@domain.tld\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"changer-lauthorité-par-défaut\">Changer l’authorité par défaut\u003C/h3>\n\u003Cp>Par défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let’s Encrypt car, d’après acme.sh, ils sont les seuls à proposer des certificats ECC.\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --set-default-ca\u003C/span>\u003Cspan style=\"color:#D19A66\"> --server\u003C/span>\u003Cspan style=\"color:#98C379\"> letsencrypt\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"utiliser-lapi-dns\">Utiliser l’api DNS\u003C/h2>\n\u003Cp>Si vous en avez la possibilité, la façon la plus simple de générer un certificat est via l’api de votre fournisseur DNS. acme.sh supporte \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">énormément\u003C/a> de fournisseurs DNS.\u003C/p>\n\u003Ch3 id=\"definir-la-clé-api\">Definir la clé api\u003C/h3>\n\u003Cp>Suivez la \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">documentation\u003C/a> pour votre fournisseur DNS, généralement:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">export\u003C/span>\u003Cspan style=\"color:#E06C75\"> PROVIDER_Key\u003C/span>\u003Cspan style=\"color:#56B6C2\">=\u003C/span>\u003Cspan style=\"color:#98C379\">\"YOUR_API_KEY\"\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"émettre-le-certificat\">Émettre le certificat\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> --dns\u003C/span>\u003Cspan style=\"color:#98C379\"> dns_provider\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"utiliser-le-mode-standalone\">Utiliser le mode standalone\u003C/h2>\n\u003Cp>Si vous n’avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s’occupe de toutes les vérifications.\u003C/p>\n\u003Cp>Le port \u003Ccode>80\u003C/code> doit être disponible.\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> --standalone\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"exemples\">Exemples\u003C/h2>\n\u003Ch3 id=\"multi-domaines-standalone\">Multi domaines standalone\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> --standalone\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> www.domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> subdomain.domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"wildcard-domaine-dns\">Wildcard domaine DNS\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> '*.domain.tld'\u003C/span>\u003Cspan style=\"color:#D19A66\"> --dns\u003C/span>\u003Cspan style=\"color:#98C379\"> dns_provider\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"étapes-supplémentaires\">Étapes supplémentaires\u003C/h2>\n\u003Cp>Le certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\u003C/p>\n\u003Ch3 id=\"version-tls\">Version TLS\u003C/h3>\n\u003Cp>Limiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu \u003Ca href=\"https://caniuse.com/?search=tls%201.\">la différence de compatibilité de 5%\u003C/a> avec 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Utiliser le header \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a>.\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>Strict-Transport-Security: max-age=31536000; includeSubDomains\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"suite-cryptographique\">Suite cryptographique\u003C/h3>\n\u003Cp>Utiliser une suite cryptographique récente et robuste. C’est ici que mes connaissances deviennent limitées… J’ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\u003C/p>\n\u003Cp>J’avais basé ma première suite sur \u003Ca href=\"https://tls.imirhil.fr/ciphers\">cette liste\u003C/a>, en la comparant avec celle de la compatibilité (d’anciens ?) \u003Ca href=\"https://tls.imirhil.fr/suite\">navigateurs\u003C/a>.\u003C/p>\n\u003Cp>J’ai ensuite demandé à \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, le créateur de \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, ses conseils sur cette suite. Il m’a recommandé d’utiliser :\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Afin d’atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES256:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":584,"imagePaths":630,"frontmatter":631},[585,588,591,594,597,600,603,606,609,612,615,618,621,624,627],{"depth":150,"slug":586,"text":587},"attention","Attention",{"depth":150,"slug":589,"text":590},"prérequis","Prérequis",{"depth":154,"slug":592,"text":593},"installer-acmesh","Installer acme.sh",{"depth":154,"slug":595,"text":596},"changer-lauthorité-par-défaut","Changer l’authorité par défaut",{"depth":150,"slug":598,"text":599},"utiliser-lapi-dns","Utiliser l’api DNS",{"depth":154,"slug":601,"text":602},"definir-la-clé-api","Definir la clé api",{"depth":154,"slug":604,"text":605},"émettre-le-certificat","Émettre le certificat",{"depth":150,"slug":607,"text":608},"utiliser-le-mode-standalone","Utiliser le mode standalone",{"depth":150,"slug":610,"text":611},"exemples","Exemples",{"depth":154,"slug":613,"text":614},"multi-domaines-standalone","Multi domaines standalone",{"depth":154,"slug":616,"text":617},"wildcard-domaine-dns","Wildcard domaine DNS",{"depth":150,"slug":619,"text":620},"étapes-supplémentaires","Étapes supplémentaires",{"depth":154,"slug":622,"text":623},"version-tls","Version TLS",{"depth":154,"slug":625,"text":626},"hsts","HSTS",{"depth":154,"slug":628,"text":629},"suite-cryptographique","Suite cryptographique",[],{"title":573,"subtitle":574,"lang":16,"slug":570,"createdAt":170,"excerpt":632,"tags":633,"type":427},"La sécurité avec des courbes.",[576],"en-acme-sh-tls-cert",{"id":634,"data":636,"body":642,"filePath":643,"digest":644,"rendered":645},{"title":637,"subtitle":638,"lang":68,"tags":639,"type":467,"slug":634,"createdAt":641},"Strong TLS certificates with acme.sh","384-bit of https",[640],"security",["Date","2022-06-08T14:24:06.000Z"],"## Disclaimer\n\nI'm, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs. \nThis is why I've switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nYou can learn (far) more by reading [this topic](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) and its linked resources.\n\n## Requirements\n\n### Installing acme.sh\n\nFor automation and ease of use purposes, I'm using [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# for using standalone mode, you might have to install as sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changing default authority\n\nBy default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let's Encrypt because according to acme.sh, they're the only ones offering ECC capabilities.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Using your DNS api\n\nIf available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports [a lot](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) of DNS providers.\n\n### Define an api key\n\nFollow the [docs](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) for your DNS provider, usually:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Issue the cert\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Using standalone mode\n\nIf you don't have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\n\nPort `80` must be free.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Examples\n\n### Multi domains standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domain DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Next steps\n\nThe ECC certificate alone will not grant you a high/perfect score.\n\n### TLS version\n\nLimit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a [5% compatibility gap](https://caniuse.com/?search=tls%201.) with 1.2).\n\n### HSTS\n\nUse the [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/) header.\n\n```\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Cipher suite\n\nUse recent and strong ciphers. This is where my knowledge hits its limit… I'm having a really hard time understanding what to use and why.\n\nI've based my initial choices of ciphers on [this list](https://tls.imirhil.fr/ciphers), cross referencing it with (older?) [browser compatibility](https://tls.imirhil.fr/suite).\n\nI then asked [Aeris](https://twitter.com/aeris22), the creator of [tls.imirhil.fr](https://tls.imirhil.fr), about it and he advised me to use the following:\n\n```\nECDHE+AES:ECDHE+CHACHA20\n```\n\nIn order to achieve a perfect score, we can be a little more restrictive with:\n\n```\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/en/acme-sh-tls-cert.md","41577e8aee884f85",{"html":646,"metadata":647},"\u003Ch2 id=\"disclaimer\">Disclaimer\u003C/h2>\n\u003Cp>I’m, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs.\u003Cbr>\nThis is why I’ve switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>You can learn (far) more by reading \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">this topic\u003C/a> and its linked resources.\u003C/p>\n\u003Ch2 id=\"requirements\">Requirements\u003C/h2>\n\u003Ch3 id=\"installing-acmesh\">Installing acme.sh\u003C/h3>\n\u003Cp>For automation and ease of use purposes, I’m using \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\"># for using standalone mode, you might have to install as sudo\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">curl\u003C/span>\u003Cspan style=\"color:#98C379\"> https://get.acme.sh\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> | \u003C/span>\u003Cspan style=\"color:#61AFEF\">sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> -s\u003C/span>\u003Cspan style=\"color:#98C379\"> email=mail@domain.tld\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"changing-default-authority\">Changing default authority\u003C/h3>\n\u003Cp>By default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let’s Encrypt because according to acme.sh, they’re the only ones offering ECC capabilities.\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --set-default-ca\u003C/span>\u003Cspan style=\"color:#D19A66\"> --server\u003C/span>\u003Cspan style=\"color:#98C379\"> letsencrypt\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"using-your-dns-api\">Using your DNS api\u003C/h2>\n\u003Cp>If available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">a lot\u003C/a> of DNS providers.\u003C/p>\n\u003Ch3 id=\"define-an-api-key\">Define an api key\u003C/h3>\n\u003Cp>Follow the \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">docs\u003C/a> for your DNS provider, usually:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">export\u003C/span>\u003Cspan style=\"color:#E06C75\"> PROVIDER_Key\u003C/span>\u003Cspan style=\"color:#56B6C2\">=\u003C/span>\u003Cspan style=\"color:#98C379\">\"YOUR_API_KEY\"\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"issue-the-cert\">Issue the cert\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> --dns\u003C/span>\u003Cspan style=\"color:#98C379\"> dns_provider\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"using-standalone-mode\">Using standalone mode\u003C/h2>\n\u003Cp>If you don’t have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\u003C/p>\n\u003Cp>Port \u003Ccode>80\u003C/code> must be free.\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> --standalone\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"examples\">Examples\u003C/h2>\n\u003Ch3 id=\"multi-domains-standalone\">Multi domains standalone\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> --standalone\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> www.domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> subdomain.domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"wildcard-domain-dns\">Wildcard domain DNS\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> '*.domain.tld'\u003C/span>\u003Cspan style=\"color:#D19A66\"> --dns\u003C/span>\u003Cspan style=\"color:#98C379\"> dns_provider\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"next-steps\">Next steps\u003C/h2>\n\u003Cp>The ECC certificate alone will not grant you a high/perfect score.\u003C/p>\n\u003Ch3 id=\"tls-version\">TLS version\u003C/h3>\n\u003Cp>Limit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a \u003Ca href=\"https://caniuse.com/?search=tls%201.\">5% compatibility gap\u003C/a> with 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Use the \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a> header.\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>Strict-Transport-Security: max-age=31536000; includeSubDomains\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"cipher-suite\">Cipher suite\u003C/h3>\n\u003Cp>Use recent and strong ciphers. This is where my knowledge hits its limit… I’m having a really hard time understanding what to use and why.\u003C/p>\n\u003Cp>I’ve based my initial choices of ciphers on \u003Ca href=\"https://tls.imirhil.fr/ciphers\">this list\u003C/a>, cross referencing it with (older?) \u003Ca href=\"https://tls.imirhil.fr/suite\">browser compatibility\u003C/a>.\u003C/p>\n\u003Cp>I then asked \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, the creator of \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, about it and he advised me to use the following:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>In order to achieve a perfect score, we can be a little more restrictive with:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES256:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":648,"imagePaths":692,"frontmatter":693},[649,652,655,658,661,664,667,670,673,676,679,682,685,688,689],{"depth":150,"slug":650,"text":651},"disclaimer","Disclaimer",{"depth":150,"slug":653,"text":654},"requirements","Requirements",{"depth":154,"slug":656,"text":657},"installing-acmesh","Installing acme.sh",{"depth":154,"slug":659,"text":660},"changing-default-authority","Changing default authority",{"depth":150,"slug":662,"text":663},"using-your-dns-api","Using your DNS api",{"depth":154,"slug":665,"text":666},"define-an-api-key","Define an api key",{"depth":154,"slug":668,"text":669},"issue-the-cert","Issue the cert",{"depth":150,"slug":671,"text":672},"using-standalone-mode","Using standalone mode",{"depth":150,"slug":674,"text":675},"examples","Examples",{"depth":154,"slug":677,"text":678},"multi-domains-standalone","Multi domains standalone",{"depth":154,"slug":680,"text":681},"wildcard-domain-dns","Wildcard domain DNS",{"depth":150,"slug":683,"text":684},"next-steps","Next steps",{"depth":154,"slug":686,"text":687},"tls-version","TLS version",{"depth":154,"slug":625,"text":626},{"depth":154,"slug":690,"text":691},"cipher-suite","Cipher suite",[],{"title":637,"subtitle":638,"lang":68,"slug":634,"createdAt":170,"excerpt":694,"tags":695,"type":467},"Real cert have curves.",[640],"en-visited-links",{"id":696,"data":698,"body":470,"filePath":702,"digest":703,"rendered":704},{"title":699,"subtitle":209,"lang":68,"tags":700,"type":467,"slug":696,"createdAt":701,"draft":72},"Visited links and visuel aid",[18],["Date","2023-06-06T18:34:00.000Z"],"src/content/fragments/en/visited-links.md","cb7c11c12c25067e",{"html":705,"metadata":706},"\u003Cp>\u003Ca href=\"/en/snippets\">Go back to available snippets\u003C/a>\u003C/p>",{"headings":707,"imagePaths":708,"frontmatter":709},[],[],{"title":699,"subtitle":209,"lang":68,"draft":72,"slug":696,"excerpt":710,"tags":711,"type":467,"createdAt":712},"Petit hack CSS",[18],"2023-06-06T18:34:00.000Z","visited-links",{"id":713,"data":715,"body":721,"filePath":722,"digest":723,"rendered":724},{"title":716,"subtitle":717,"lang":16,"tags":718,"type":467,"slug":713,"createdAt":719,"draft":720},"Liens visités et indication visuelle","Comment différencier les liens déjà cliqués",[18],["Date","2023-06-06T18:34:00.000Z"],false,"## La théorie\n\nIl est possible sur le web d'appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu'un lien visité est violet.\n\nGénéralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L'information qu'un lien a déjà été visité ne semble pas indispensable à la navigation. C'est sûrement vrai, mais personnellement, je suis assez content d'avoir un rappel des pages que j'ai déjà consultées lorsque je navigue.\n\nUne information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J'ai alors cherché un moyen d'ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n'est certainement pas idéale, elle se rapproche plus d'une expérience, à priori inoffensive pour l'internaute.\n\n## La spécification\n\nQuand je me suis intéressé à ce qu'il était possible de faire avec les liens déjà visités, j'ai découvert qu'extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu'il était possible de récupérer l'historique de navigation d'un utilisateur grâce aux styles des liens visités. Le sélecteur `:visited` a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. [Plus d'informations dans cet article.](https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector)\n\n## La pratique\n\nQue faire alors, en terme de style, quand on ne peut changer que des couleurs ?\n\nD'après MDN, les propriétés suivantes sont modifiables :\n\n- `color`\n- `background-color`\n- `border-color` (et les propriétés détaillées associées),\n- `column-rule-color`\n- `outline-color`\n- `text-decoration-color`\n- `text-emphasis-color`\n- Les composantes de couleur liées aux attributs SVG `fill` et `stroke`.\n\nChanger la couleur d'un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\n\nEn revanche, il est possible de \" masquer \" un élément en modifiant sa couleur pour qu'elle corresponde à la couleur du fond de la page ou de l'élément parent. On pourrait ainsi imaginer masquer une `border` ou un `outline`.\n\nJ'ai personnellement choisi de faire différemment. J'ai décidé d'utiliser un pseudo-élément `::before` sur l'état non visité du lien puis de le masquer quand celui-ci devient visité.\n\n### Le code\n\n```css {1,4-6}\na {\n\tposition: relative;\n\ttext-decoration: none;\n}\na::before {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 0;\n\tinline-size: 2px;\n\tblock-size: 2px;\n\tborder-radius: 4px;\n\ttransform: translate(-6px, 0);\n\tbackground-color: grey;\n}\na:visited::before {\n\tbackground-color: white;\n}\n```\n\nCes règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\n\n### Accessibilité\n\nOn pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété `content` mais les lecteurs d'écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d'écrans annoncent déjà si un lien est visité avant de lire son intitulé.\n\n## Aller plus loin\n\nAfin de pousser l'expérience un peu plus loin, j'ai tenté d'utiliser des éléments plus explicites pour signifier l'état visité du lien. Bien qu'encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\n\nL'idée est d'avoir un `::before` et un `::after`, chacun contenant une icône en base 64 blanche en tant qu'image de fond. Quand le lien est non visité, le `::before` contient un fond coloré qui fait apparaître l'icône. Quand le lien passe en visité, le fond du `::before` devient blanc et celui du `::after` devient coloré, ce qui masque la première icône et affiche la deuxième.\n\nIl est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l'une sur l'autre.\n\n[Voir la démo sur codepen.](https://codepen.io/narduin/pen/VwVwmrO)","src/content/fragments/fr/visited-links.md","8398f96220bc4ff2",{"html":725,"metadata":726},"\u003Ch2 id=\"la-théorie\">La théorie\u003C/h2>\n\u003Cp>Il est possible sur le web d’appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu’un lien visité est violet.\u003C/p>\n\u003Cp>Généralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L’information qu’un lien a déjà été visité ne semble pas indispensable à la navigation. C’est sûrement vrai, mais personnellement, je suis assez content d’avoir un rappel des pages que j’ai déjà consultées lorsque je navigue.\u003C/p>\n\u003Cp>Une information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J’ai alors cherché un moyen d’ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n’est certainement pas idéale, elle se rapproche plus d’une expérience, à priori inoffensive pour l’internaute.\u003C/p>\n\u003Ch2 id=\"la-spécification\">La spécification\u003C/h2>\n\u003Cp>Quand je me suis intéressé à ce qu’il était possible de faire avec les liens déjà visités, j’ai découvert qu’extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu’il était possible de récupérer l’historique de navigation d’un utilisateur grâce aux styles des liens visités. Le sélecteur \u003Ccode>:visited\u003C/code> a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector\">Plus d’informations dans cet article.\u003C/a>\u003C/p>\n\u003Ch2 id=\"la-pratique\">La pratique\u003C/h2>\n\u003Cp>Que faire alors, en terme de style, quand on ne peut changer que des couleurs ?\u003C/p>\n\u003Cp>D’après MDN, les propriétés suivantes sont modifiables :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>background-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>border-color\u003C/code> (et les propriétés détaillées associées),\u003C/li>\n\u003Cli>\u003Ccode>column-rule-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>outline-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-decoration-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-emphasis-color\u003C/code>\u003C/li>\n\u003Cli>Les composantes de couleur liées aux attributs SVG \u003Ccode>fill\u003C/code> et \u003Ccode>stroke\u003C/code>.\u003C/li>\n\u003C/ul>\n\u003Cp>Changer la couleur d’un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\u003C/p>\n\u003Cp>En revanche, il est possible de ” masquer ” un élément en modifiant sa couleur pour qu’elle corresponde à la couleur du fond de la page ou de l’élément parent. On pourrait ainsi imaginer masquer une \u003Ccode>border\u003C/code> ou un \u003Ccode>outline\u003C/code>.\u003C/p>\n\u003Cp>J’ai personnellement choisi de faire différemment. J’ai décidé d’utiliser un pseudo-élément \u003Ccode>::before\u003C/code> sur l’état non visité du lien puis de le masquer quand celui-ci devient visité.\u003C/p>\n\u003Ch3 id=\"le-code\">Le code\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line highlighted\">\u003Cspan style=\"color:#E06C75\">a\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tposition: \u003C/span>\u003Cspan style=\"color:#D19A66\">relative\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttext-decoration: \u003C/span>\u003Cspan style=\"color:#D19A66\">none\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line highlighted\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line highlighted\">\u003Cspan style=\"color:#E06C75\">a\u003C/span>\u003Cspan style=\"color:#56B6C2\">::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line highlighted\">\u003Cspan style=\"color:#ABB2BF\">\tcontent: \u003C/span>\u003Cspan style=\"color:#98C379\">''\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tposition: \u003C/span>\u003Cspan style=\"color:#D19A66\">absolute\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttop: \u003C/span>\u003Cspan style=\"color:#D19A66\">50\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tleft: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tinline-size: \u003C/span>\u003Cspan style=\"color:#D19A66\">2\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tblock-size: \u003C/span>\u003Cspan style=\"color:#D19A66\">2\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tborder-radius: \u003C/span>\u003Cspan style=\"color:#D19A66\">4\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransform: \u003C/span>\u003Cspan style=\"color:#56B6C2\">translate\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">-6\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-color: grey;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">a\u003C/span>\u003Cspan style=\"color:#56B6C2\">:visited::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-color: \u003C/span>\u003Cspan style=\"color:#D19A66\">white\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Ces règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\u003C/p>\n\u003Ch3 id=\"accessibilité\">Accessibilité\u003C/h3>\n\u003Cp>On pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété \u003Ccode>content\u003C/code> mais les lecteurs d’écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d’écrans annoncent déjà si un lien est visité avant de lire son intitulé.\u003C/p>\n\u003Ch2 id=\"aller-plus-loin\">Aller plus loin\u003C/h2>\n\u003Cp>Afin de pousser l’expérience un peu plus loin, j’ai tenté d’utiliser des éléments plus explicites pour signifier l’état visité du lien. Bien qu’encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\u003C/p>\n\u003Cp>L’idée est d’avoir un \u003Ccode>::before\u003C/code> et un \u003Ccode>::after\u003C/code>, chacun contenant une icône en base 64 blanche en tant qu’image de fond. Quand le lien est non visité, le \u003Ccode>::before\u003C/code> contient un fond coloré qui fait apparaître l’icône. Quand le lien passe en visité, le fond du \u003Ccode>::before\u003C/code> devient blanc et celui du \u003Ccode>::after\u003C/code> devient coloré, ce qui masque la première icône et affiche la deuxième.\u003C/p>\n\u003Cp>Il est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l’une sur l’autre.\u003C/p>\n\u003Cp>\u003Ca href=\"https://codepen.io/narduin/pen/VwVwmrO\">Voir la démo sur codepen.\u003C/a>\u003C/p>",{"headings":727,"imagePaths":745,"frontmatter":746},[728,731,734,737,740,742],{"depth":150,"slug":729,"text":730},"la-théorie","La théorie",{"depth":150,"slug":732,"text":733},"la-spécification","La spécification",{"depth":150,"slug":735,"text":736},"la-pratique","La pratique",{"depth":154,"slug":738,"text":739},"le-code","Le code",{"depth":154,"slug":32,"text":741},"Accessibilité",{"depth":150,"slug":743,"text":744},"aller-plus-loin","Aller plus loin",[],{"title":716,"subtitle":717,"lang":16,"draft":720,"slug":713,"excerpt":710,"tags":747,"type":467,"createdAt":712},[18],"en-buttons",{"id":748,"data":750,"body":755,"filePath":756,"digest":757,"rendered":758},{"title":751,"subtitle":752,"lang":68,"tags":753,"type":467,"slug":748,"createdAt":754,"code":72,"draft":72},"Buttons hover","Simple, but nice.",[435],["Date","2020-10-08T09:00:00.000Z"],"## General rules\n\nAll the buttons use these styles as a “reset”:\n\n> Don't forget to prefix if necessary!\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Add an icon\n\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('~assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double shutter down\n\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Animated gradient\n\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Non destructive scale\n\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/en/buttons.md","ea9a5513a5a4cef4",{"html":759,"metadata":760},"\u003Ch2 id=\"general-rules\">General rules\u003C/h2>\n\u003Cp>All the buttons use these styles as a “reset”:\u003C/p>\n\u003Cblockquote>\n\u003Cp>Don’t forget to prefix if necessary!\u003C/p>\n\u003C/blockquote>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tmargin: \u003C/span>\u003Cspan style=\"color:#D19A66\">20\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#D19A66\"> 0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tpadding: \u003C/span>\u003Cspan style=\"color:#D19A66\">12\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#D19A66\"> 26\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tposition: \u003C/span>\u003Cspan style=\"color:#D19A66\">relative\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tdisplay: \u003C/span>\u003Cspan style=\"color:#D19A66\">inline-block\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\toverflow: \u003C/span>\u003Cspan style=\"color:#D19A66\">hidden\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tfont-size: \u003C/span>\u003Cspan style=\"color:#D19A66\">20\u003C/span>\u003Cspan style=\"color:#E06C75\">rem\u003C/span>\u003Cspan style=\"color:#ABB2BF\">; \u003C/span>\u003Cspan style=\"color:#7F848E;font-style:italic\">/* 20px */\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tline-height: \u003C/span>\u003Cspan style=\"color:#D19A66\">1.6\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttext-align: \u003C/span>\u003Cspan style=\"color:#D19A66\">center\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttext-decoration: \u003C/span>\u003Cspan style=\"color:#D19A66\">none\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tfont-weight: \u003C/span>\u003Cspan style=\"color:#D19A66\">bold\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcursor: \u003C/span>\u003Cspan style=\"color:#D19A66\">pointer\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tborder: \u003C/span>\u003Cspan style=\"color:#D19A66\">none\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tborder-radius: \u003C/span>\u003Cspan style=\"color:#D19A66\">2\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#56B6C2\">\t-moz-appearance\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#D19A66\">none\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#56B6C2\">\t-webkit-appearance\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#D19A66\">none\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcolor: \u003C/span>\u003Cspan style=\"color:#D19A66\">white\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-color: hotpink;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition: background-color \u003C/span>\u003Cspan style=\"color:#D19A66\">0.3\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#D19A66\"> ease\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"add-an-icon\">Add an icon\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-color: hotpink;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#56B6C2\">::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcontent: \u003C/span>\u003Cspan style=\"color:#56B6C2\">url\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#98C379\">'~assets/svg/arrow-right-white.svg'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tposition: \u003C/span>\u003Cspan style=\"color:#D19A66\">absolute\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\twidth: \u003C/span>\u003Cspan style=\"color:#D19A66\">20\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttop: \u003C/span>\u003Cspan style=\"color:#D19A66\">50\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tright: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransform: \u003C/span>\u003Cspan style=\"color:#56B6C2\">translate\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">40\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">-50\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition: transform \u003C/span>\u003Cspan style=\"color:#D19A66\">ease\u003C/span>\u003Cspan style=\"color:#D19A66\"> 0.3\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-color: darkorchid;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransform: \u003C/span>\u003Cspan style=\"color:#56B6C2\">translate\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">-10\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">-50\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> >\u003C/span>\u003Cspan style=\"color:#E06C75\"> span\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tdisplay: \u003C/span>\u003Cspan style=\"color:#D19A66\">inline-block\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\twidth: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\theight: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition: transform \u003C/span>\u003Cspan style=\"color:#D19A66\">0.3\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#D19A66\"> ease\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> >\u003C/span>\u003Cspan style=\"color:#E06C75\"> span\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> >\u003C/span>\u003Cspan style=\"color:#E06C75\"> span\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransform: \u003C/span>\u003Cspan style=\"color:#56B6C2\">translateX\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">-10\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"double-shutter-down\">Double shutter down\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tborder: \u003C/span>\u003Cspan style=\"color:#D19A66\">2\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#D19A66\"> solid\u003C/span>\u003Cspan style=\"color:#D19A66\"> #10113a\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcolor: \u003C/span>\u003Cspan style=\"color:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-color: \u003C/span>\u003Cspan style=\"color:#D19A66\">transparent\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition: \u003C/span>\u003Cspan style=\"color:#D19A66\">color\u003C/span>\u003Cspan style=\"color:#D19A66\"> 0.3\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#D19A66\"> ease\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcolor: \u003C/span>\u003Cspan style=\"color:#D19A66\">white\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground: hotpink;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground: darkorchid;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcontent: \u003C/span>\u003Cspan style=\"color:#98C379\">''\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tposition: \u003C/span>\u003Cspan style=\"color:#D19A66\">absolute\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\theight: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\twidth: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbottom: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tleft: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tz-index: \u003C/span>\u003Cspan style=\"color:#D19A66\">-1\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition: transform \u003C/span>\u003Cspan style=\"color:#D19A66\">0.3\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition-timing-function: \u003C/span>\u003Cspan style=\"color:#D19A66\">ease\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition-timing-function: \u003C/span>\u003Cspan style=\"color:#56B6C2\">cubic-bezier\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">0.75\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">0.125\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">1\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransform: \u003C/span>\u003Cspan style=\"color:#56B6C2\">translateY\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition-delay: \u003C/span>\u003Cspan style=\"color:#D19A66\">0.175\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"animated-gradient\">Animated gradient\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground: \u003C/span>\u003Cspan style=\"color:#56B6C2\">linear-gradient\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">-45\u003C/span>\u003Cspan style=\"color:#E06C75\">deg\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">#ee7752\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">#e73c7e\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">#23a6d5\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">#23d5ab\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-size: \u003C/span>\u003Cspan style=\"color:#D19A66\">400\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#D19A66\"> 400\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-position: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#D19A66\"> 50\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tanimation: GradientReverse \u003C/span>\u003Cspan style=\"color:#D19A66\">0.5\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#D19A66\"> ease\u003C/span>\u003Cspan style=\"color:#D19A66\"> 1\u003C/span>\u003Cspan style=\"color:#D19A66\"> normal\u003C/span>\u003Cspan style=\"color:#D19A66\"> forwards\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tanimation: Gradient \u003C/span>\u003Cspan style=\"color:#D19A66\">0.5\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#D19A66\"> ease\u003C/span>\u003Cspan style=\"color:#D19A66\"> 1\u003C/span>\u003Cspan style=\"color:#D19A66\"> normal\u003C/span>\u003Cspan style=\"color:#D19A66\"> forwards\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">@keyframes\u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\"> Gradient\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t0% {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t\tbackground-position: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#D19A66\"> 50\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t100% {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t\tbackground-position: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#D19A66\"> 100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">@keyframes\u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\"> GradientReverse\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t0% {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t\tbackground-position: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#D19A66\"> 100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t100% {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t\tbackground-position: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#D19A66\"> 50\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"non-destructive-scale\">Non destructive scale\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\toverflow: \u003C/span>\u003Cspan style=\"color:#D19A66\">visible\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcolor: \u003C/span>\u003Cspan style=\"color:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-color: \u003C/span>\u003Cspan style=\"color:#D19A66\">transparent\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"color:#56B6C2\">::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcontent: \u003C/span>\u003Cspan style=\"color:#98C379\">''\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tposition: \u003C/span>\u003Cspan style=\"color:#D19A66\">absolute\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttop: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tleft: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbottom: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\twidth: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tborder: \u003C/span>\u003Cspan style=\"color:#D19A66\">2\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#D19A66\"> solid\u003C/span>\u003Cspan style=\"color:#D19A66\"> #10113a\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tborder-radius: \u003C/span>\u003Cspan style=\"color:#D19A66\">2\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition: transform \u003C/span>\u003Cspan style=\"color:#D19A66\">0.3\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#D19A66\"> ease\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransform: \u003C/span>\u003Cspan style=\"color:#56B6C2\">scale\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">1.1\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":761,"imagePaths":777,"frontmatter":778},[762,765,768,771,774],{"depth":150,"slug":763,"text":764},"general-rules","General rules",{"depth":150,"slug":766,"text":767},"add-an-icon","Add an icon",{"depth":150,"slug":769,"text":770},"double-shutter-down","Double shutter down",{"depth":150,"slug":772,"text":773},"animated-gradient","Animated gradient",{"depth":150,"slug":775,"text":776},"non-destructive-scale","Non destructive scale",[],{"title":751,"subtitle":752,"lang":68,"slug":748,"draft":72,"excerpt":779,"tags":780,"code":72,"type":467,"createdAt":781},"Easy to grab and use hover effects.",[435],"2020-10-08T09:00:00.000Z","en-array-vs-array",{"id":782,"data":784,"body":789,"filePath":790,"digest":791,"rendered":792},{"title":785,"subtitle":786,"lang":68,"tags":787,"type":467,"slug":782,"createdAt":788},"Filter an array against another array","Array vs Array.",[490],["Date","2022-06-08T14:24:06.000Z"],"## Context\n\nFor a project, I had to come up with a way to filter an array of objects based on another array of strings.\n\nIn other words, I needed to include every object which `user` property was found in the second array.\n\nHere is an example:\n\n```javascript\nconst skills = [\n\t{\n\t\tname: 'Be awesome',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Great jokes',\n\t\tuser: 'Jacques'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Beatriz'\n\t}\n]\n\nconst selectedUsers = ['Jean', 'Beatriz']\n```\n\nI thought it would be pretty easy but I guess I'm not familiar enough with javascript 😬\n\n## My solution\n\nAfter a bit of thinking, I came up with the following statement:\n\n> I need to filter the skills based on which users are selected. So I need to loop over the `selectedUsers` array and filter the skills according to their `user` value.\n\nAfter a bit more trials and errors, this is the code I ended up using in a `computed property`:\n\n```javascript\n// index.vue\nconst filteredSkills = selectedUsers.map((user) => {\n\treturn skills.filter((skill) => {\n\t\treturn skill.user === user\n\t})\n})\n```\n\nI used `map()` in order to loop on the second array and used its string value to only include the corresponding skills with `filter()`.\n\nI'm pretty sure there is a better way to do it though…","src/content/fragments/en/array-vs-array.md","c63ba57b1049cf4c",{"html":793,"metadata":794},"\u003Ch2 id=\"context\">Context\u003C/h2>\n\u003Cp>For a project, I had to come up with a way to filter an array of objects based on another array of strings.\u003C/p>\n\u003Cp>In other words, I needed to include every object which \u003Ccode>user\u003C/code> property was found in the second array.\u003C/p>\n\u003Cp>Here is an example:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">const\u003C/span>\u003Cspan style=\"color:#E5C07B\"> skills\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tname\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Be awesome'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tuser\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Jean'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tname\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Great jokes'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tuser\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Jacques'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tname\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tuser\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Jean'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tname\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tuser\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Beatriz'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">const\u003C/span>\u003Cspan style=\"color:#E5C07B\"> selectedUsers\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> [\u003C/span>\u003Cspan style=\"color:#98C379\">'Jean'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#98C379\">'Beatriz'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">]\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>I thought it would be pretty easy but I guess I’m not familiar enough with javascript 😬\u003C/p>\n\u003Ch2 id=\"my-solution\">My solution\u003C/h2>\n\u003Cp>After a bit of thinking, I came up with the following statement:\u003C/p>\n\u003Cblockquote>\n\u003Cp>I need to filter the skills based on which users are selected. So I need to loop over the \u003Ccode>selectedUsers\u003C/code> array and filter the skills according to their \u003Ccode>user\u003C/code> value.\u003C/p>\n\u003C/blockquote>\n\u003Cp>After a bit more trials and errors, this is the code I ended up using in a \u003Ccode>computed property\u003C/code>:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">const\u003C/span>\u003Cspan style=\"color:#E5C07B\"> filteredSkills\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#E5C07B\"> selectedUsers\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">map\u003C/span>\u003Cspan style=\"color:#ABB2BF\">((\u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\">user\u003C/span>\u003Cspan style=\"color:#ABB2BF\">) \u003C/span>\u003Cspan style=\"color:#C678DD\">=>\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">\treturn\u003C/span>\u003Cspan style=\"color:#E5C07B\"> skills\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">filter\u003C/span>\u003Cspan style=\"color:#ABB2BF\">((\u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\">skill\u003C/span>\u003Cspan style=\"color:#ABB2BF\">) \u003C/span>\u003Cspan style=\"color:#C678DD\">=>\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">\t\treturn\u003C/span>\u003Cspan style=\"color:#E5C07B\"> skill\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E06C75\">user\u003C/span>\u003Cspan style=\"color:#56B6C2\"> ===\u003C/span>\u003Cspan style=\"color:#E06C75\"> user\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t})\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">})\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>I used \u003Ccode>map()\u003C/code> in order to loop on the second array and used its string value to only include the corresponding skills with \u003Ccode>filter()\u003C/code>.\u003C/p>\n\u003Cp>I’m pretty sure there is a better way to do it though…\u003C/p>",{"headings":795,"imagePaths":802,"frontmatter":803},[796,799],{"depth":150,"slug":797,"text":798},"context","Context",{"depth":150,"slug":800,"text":801},"my-solution","My solution",[],{"title":785,"subtitle":786,"lang":68,"slug":782,"createdAt":170,"excerpt":804,"tags":805,"type":467},"My peak javascript",[490],"nuxt-graphql-static",{"id":806,"data":808,"body":814,"filePath":815,"digest":816,"rendered":817},{"title":809,"subtitle":810,"lang":16,"tags":811,"type":427,"slug":806,"createdAt":812,"updatedAt":813},"Site statique et requêtes GraphQL avec Nuxt.js","Le client graphql est roi.",[490],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## Le problème\n\nJe me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (nouvel onglet)').\nAprès quelques recherches, voici [le bug constaté par quelqu'un d'autre](https://github.com/nuxt-community/apollo-module/issues/339 'Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)') sur github.\n\nIl semblerait que le module en l'état ne gère pas correctement la génération statique avec `nuxt generate`.\n\nJe trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les `\u003Cnuxt-link>` ne fonctionnait pas.\n\n## La solution 🙌\n\nHeureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\n\n[Nuxt graphql request à la rescousse !](https://github.com/gomah/nuxt-graphql-request 'Dépôt github du module (nouvel onglet)')\n\n### La conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### La requête\n\nLa meilleure méthode à ce jour est d'utiliser `asyncData` dans les pages et `fetch` dans les composants. Utiliser `fetch` dans les pages ne fonctionne pas bien du tout avec `nuxt generate`.\n\nJ'installe également le paquet `graphql-tag` (uniquement en `devDependencies`) afin de pouvoir importer directement des fichiers `.gql`\n\nExemple de fichier :\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Dans une page\n\n```javascript\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n async asyncData({ $graphql }) {\n const data = await $graphql.default.request(homepageQuery)\n return { data }\n },\n}\n\u003C/script>\n```\n\n#### Dans un composant\n\nIl est plus prudent d'attendre que `fetch` ait reçu une réponse avant d'afficher quoi que ce soit. On peut utiliser `$fetchState` afin d'être tranquille ([documentation](https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation sur la méthode fetch (nouvel onglet)')).\n\n```javascript\n// Header.vue\n\u003Ctemplate>\n \u003Cheader v-if=\"!$fetchState.pending\">\n …\n \u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n data() {\n return {\n data: {},\n }\n },\n async fetch() {\n try {\n const data = await this.$graphql.default.request(headerQuery)\n this.data = data\n } catch (error) {\n console.error(JSON.stringify(error, undefined, 2))\n }\n },\n}\n\u003C/script>\n```\n\n### Les options\n\nPour passer des options à la requête, par exemple pour une version multilingue avec [nuxt/i18n](https://i18n.nuxtjs.org/ 'Documentation de nuxt i18n (nouvel onglet)') et/ou un paramètre d'url dans le cadre d'une page dynamique :\n\n```javascript\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n async asyncData({ $graphql, app, params }) {\n const locale = app.i18n.localeProperties.iso\n const data = await $graphql.default.request(articleQuery, {\n code: locale,\n slug: params.slug,\n })\n return { data }\n },\n}\n\u003C/script>\n```","src/content/fragments/fr/nuxt-graphql-static.md","73b6cc6b4fed04f5",{"html":818,"metadata":819},"\u003Ch2 id=\"le-problème\">Le problème\u003C/h2>\n\u003Cp>Je me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (nouvel onglet)\">nuxt apollo\u003C/a>.\nAprès quelques recherches, voici \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)\">le bug constaté par quelqu’un d’autre\u003C/a> sur github.\u003C/p>\n\u003Cp>Il semblerait que le module en l’état ne gère pas correctement la génération statique avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>Je trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les \u003Ccode><nuxt-link>\u003C/code> ne fonctionnait pas.\u003C/p>\n\u003Ch2 id=\"la-solution\">La solution 🙌\u003C/h2>\n\u003Cp>Heureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\" title=\"Dépôt github du module (nouvel onglet)\">Nuxt graphql request à la rescousse !\u003C/a>\u003C/p>\n\u003Ch3 id=\"la-conf\">La conf\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// nuxt.config.js\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">buildModules\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#98C379\"> 'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> clients\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\"> default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> endpoint\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> options\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> headers\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> authorization\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">},\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"la-requête\">La requête\u003C/h3>\n\u003Cp>La meilleure méthode à ce jour est d’utiliser \u003Ccode>asyncData\u003C/code> dans les pages et \u003Ccode>fetch\u003C/code> dans les composants. Utiliser \u003Ccode>fetch\u003C/code> dans les pages ne fonctionne pas bien du tout avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>J’installe également le paquet \u003Ccode>graphql-tag\u003C/code> (uniquement en \u003Ccode>devDependencies\u003C/code>) afin de pouvoir importer directement des fichiers \u003Ccode>.gql\u003C/code>\u003C/p>\n\u003Cp>Exemple de fichier :\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"graphql\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\"># homepage.gql\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">query\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\thomepage\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\ttitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tsubtitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\thero\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\t\tid\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\t\talt\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"dans-une-page\">Dans une page\u003C/h4>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">import homepageQuery from '~/graphql/queries/singles/homepage'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">export default \u003C/span>\u003Cspan style=\"color:#C678DD\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> async\u003C/span>\u003Cspan style=\"color:#61AFEF\"> asyncData\u003C/span>\u003Cspan style=\"color:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"color:#E06C75\">$graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> const \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#C678DD\"> await\u003C/span>\u003Cspan style=\"color:#E5C07B\"> $graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">request\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#E06C75\">homepageQuery\u003C/span>\u003Cspan style=\"color:#ABB2BF\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> return { \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"dans-un-composant\">Dans un composant\u003C/h4>\n\u003Cp>Il est plus prudent d’attendre que \u003Ccode>fetch\u003C/code> ait reçu une réponse avant d’afficher quoi que ce soit. On peut utiliser \u003Ccode>$fetchState\u003C/code> afin d’être tranquille (\u003Ca href=\"https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation sur la méthode fetch (nouvel onglet)\">documentation\u003C/a>).\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// Header.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">template\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> <\u003C/span>\u003Cspan style=\"color:#E06C75\">header\u003C/span>\u003Cspan style=\"color:#D19A66;font-style:italic\"> v-if\u003C/span>\u003Cspan style=\"color:#56B6C2\">=\u003C/span>\u003Cspan style=\"color:#98C379\">\"!$fetchState.pending\"\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> …\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> </\u003C/span>\u003Cspan style=\"color:#E06C75\">header\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">template\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">import headerQuery from '~/graphql/queries/singles/header'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">export default \u003C/span>\u003Cspan style=\"color:#C678DD\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\"> data\u003C/span>\u003Cspan style=\"color:#ABB2BF\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> return {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> data\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> async\u003C/span>\u003Cspan style=\"color:#61AFEF\"> fetch\u003C/span>\u003Cspan style=\"color:#ABB2BF\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> try {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\"> const\u003C/span>\u003Cspan style=\"color:#E5C07B\"> data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#C678DD\"> await\u003C/span>\u003Cspan style=\"color:#E5C07B\"> this\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">request\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#E06C75\">headerQuery\u003C/span>\u003Cspan style=\"color:#ABB2BF\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E5C07B\"> this\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#E06C75\"> data\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> } catch (error) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> console.\u003C/span>\u003Cspan style=\"color:#61AFEF\">error\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(JSON.stringify(\u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\">error\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\">undefined\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, 2))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\"> }\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"les-options\">Les options\u003C/h3>\n\u003Cp>Pour passer des options à la requête, par exemple pour une version multilingue avec \u003Ca href=\"https://i18n.nuxtjs.org/\" title=\"Documentation de nuxt i18n (nouvel onglet)\">nuxt/i18n\u003C/a> et/ou un paramètre d’url dans le cadre d’une page dynamique :\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// _slug.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">import articleQuery from '~/graphql/queries/articles'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">export default \u003C/span>\u003Cspan style=\"color:#C678DD\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> async\u003C/span>\u003Cspan style=\"color:#61AFEF\"> asyncData\u003C/span>\u003Cspan style=\"color:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"color:#E06C75\">$graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#E06C75\">app\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#E06C75\">params\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> const \u003C/span>\u003Cspan style=\"color:#E06C75\">locale\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#E5C07B\"> app\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">i18n\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">localeProperties\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E06C75\">iso\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> const \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#C678DD\"> await\u003C/span>\u003Cspan style=\"color:#E5C07B\"> $graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">request\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#E06C75\">articleQuery\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> code\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#E06C75\">locale\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> slug\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#E5C07B\">params\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E06C75\">slug\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> })\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> return { \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":820,"imagePaths":843,"frontmatter":844},[821,824,827,830,833,837,840],{"depth":150,"slug":822,"text":823},"le-problème","Le problème",{"depth":150,"slug":825,"text":826},"la-solution","La solution 🙌",{"depth":154,"slug":828,"text":829},"la-conf","La conf",{"depth":154,"slug":831,"text":832},"la-requête","La requête",{"depth":834,"slug":835,"text":836},4,"dans-une-page","Dans une page",{"depth":834,"slug":838,"text":839},"dans-un-composant","Dans un composant",{"depth":154,"slug":841,"text":842},"les-options","Les options",[],{"title":809,"subtitle":810,"lang":16,"slug":806,"createdAt":170,"updatedAt":845,"excerpt":846,"tags":847,"type":427},"2022-09-08T13:43:33.000Z","Quand le module gql le plus utilisé ne fonctionne pas…",[490],"en-nuxt-graphql-static",{"id":848,"data":850,"body":856,"filePath":857,"digest":858,"rendered":859},{"title":851,"subtitle":852,"lang":68,"tags":853,"type":467,"slug":848,"createdAt":854,"updatedAt":855},"Static website and GraphQL queries with Nuxt.js","Graphql client is king.",[490],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## The problem\n\nI encountered a nasty bug while using static generation with Nuxt and [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (new tab)') client.\nI found [the issue](https://github.com/nuxt-community/apollo-module/issues/339 'Github issue on nuxt/apollo repository (new tab)') already reported on github.\n\nIt seems the module doesn't handle static generation correctly with `nuxt generate`.\n\nI could find request to my local API url after the static generation. Moreover, it also seemed like `\u003Cnuxt-link>` navigation was broken.\n\n## The solution 🙌\n\nFortunately, there is another Nuxt module that handles GraphQL requests!\n\n[Nuxt graphql request to the rescue!](https://github.com/gomah/nuxt-graphql-request)\n\n### The conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### The request\n\nThe best approach so far is to use `asyncData` in pages and `fetch` in components. Using `fetch` in pages does not work well at all with `nuxt generate`.\n\nI also install the `graphql-tag` package (only in `devDependencies`) to be able to import directly `.gql` files.\n\nQuery example:\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Inside a page\n\n```javascript\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n async asyncData({ $graphql }) {\n const data = await $graphql.default.request(homepageQuery)\n return { data }\n },\n}\n\u003C/script>\n```\n\n#### Inside a component\n\nIt is safer to wait until `fetch` has received a response before displaying anything. You can use `$fetchState` to be sure ([documentation](https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation on the fetch hook (new tab)')).\n\n```javascript\n// Header.vue\n\u003Ctemplate>\n \u003Cheader v-if=\"!$fetchState.pending\">\n …\n \u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n data() {\n return {\n data: {},\n }\n },\n async fetch() {\n try {\n const data = await this.$graphql.default.request(headerQuery)\n this.data = data\n } catch (error) {\n console.error(JSON.stringify(error, undefined, 2))\n }\n },\n}\n\u003C/script>\n```\n\n### Options\n\nTo pass options to the request, for example for a multilingual version with [nuxt/i18n](https://i18n.nuxtjs.org/) and/or a url parameter in a dynamic page:\n\n```javascript\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n async asyncData({ $graphql, app, params }) {\n const locale = app.i18n.localeProperties.iso\n const data = await $graphql.default.request(articleQuery, {\n code: locale,\n slug: params.slug,\n })\n return { data }\n },\n}\n\u003C/script>\n```","src/content/fragments/en/nuxt-graphql-static.md","181e8091294eb858",{"html":860,"metadata":861},"\u003Ch2 id=\"the-problem\">The problem\u003C/h2>\n\u003Cp>I encountered a nasty bug while using static generation with Nuxt and \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (new tab)\">nuxt apollo\u003C/a> client.\nI found \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Github issue on nuxt/apollo repository (new tab)\">the issue\u003C/a> already reported on github.\u003C/p>\n\u003Cp>It seems the module doesn’t handle static generation correctly with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I could find request to my local API url after the static generation. Moreover, it also seemed like \u003Ccode><nuxt-link>\u003C/code> navigation was broken.\u003C/p>\n\u003Ch2 id=\"the-solution\">The solution 🙌\u003C/h2>\n\u003Cp>Fortunately, there is another Nuxt module that handles GraphQL requests!\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\">Nuxt graphql request to the rescue!\u003C/a>\u003C/p>\n\u003Ch3 id=\"the-conf\">The conf\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// nuxt.config.js\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">buildModules\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#98C379\"> 'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> clients\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\"> default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> endpoint\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> options\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> headers\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> authorization\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">},\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"the-request\">The request\u003C/h3>\n\u003Cp>The best approach so far is to use \u003Ccode>asyncData\u003C/code> in pages and \u003Ccode>fetch\u003C/code> in components. Using \u003Ccode>fetch\u003C/code> in pages does not work well at all with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I also install the \u003Ccode>graphql-tag\u003C/code> package (only in \u003Ccode>devDependencies\u003C/code>) to be able to import directly \u003Ccode>.gql\u003C/code> files.\u003C/p>\n\u003Cp>Query example:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"graphql\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\"># homepage.gql\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">query\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\thomepage\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\ttitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tsubtitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\thero\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\t\tid\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\t\talt\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"inside-a-page\">Inside a page\u003C/h4>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">import homepageQuery from '~/graphql/queries/singles/homepage'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">export default \u003C/span>\u003Cspan style=\"color:#C678DD\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> async\u003C/span>\u003Cspan style=\"color:#61AFEF\"> asyncData\u003C/span>\u003Cspan style=\"color:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"color:#E06C75\">$graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> const \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#C678DD\"> await\u003C/span>\u003Cspan style=\"color:#E5C07B\"> $graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">request\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#E06C75\">homepageQuery\u003C/span>\u003Cspan style=\"color:#ABB2BF\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> return { \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"inside-a-component\">Inside a component\u003C/h4>\n\u003Cp>It is safer to wait until \u003Ccode>fetch\u003C/code> has received a response before displaying anything. You can use \u003Ccode>$fetchState\u003C/code> to be sure (\u003Ca href=\"https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation on the fetch hook (new tab)\">documentation\u003C/a>).\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// Header.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">template\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> <\u003C/span>\u003Cspan style=\"color:#E06C75\">header\u003C/span>\u003Cspan style=\"color:#D19A66;font-style:italic\"> v-if\u003C/span>\u003Cspan style=\"color:#56B6C2\">=\u003C/span>\u003Cspan style=\"color:#98C379\">\"!$fetchState.pending\"\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> …\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> </\u003C/span>\u003Cspan style=\"color:#E06C75\">header\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">template\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">import headerQuery from '~/graphql/queries/singles/header'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">export default \u003C/span>\u003Cspan style=\"color:#C678DD\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\"> data\u003C/span>\u003Cspan style=\"color:#ABB2BF\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> return {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> data\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> async\u003C/span>\u003Cspan style=\"color:#61AFEF\"> fetch\u003C/span>\u003Cspan style=\"color:#ABB2BF\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> try {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\"> const\u003C/span>\u003Cspan style=\"color:#E5C07B\"> data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#C678DD\"> await\u003C/span>\u003Cspan style=\"color:#E5C07B\"> this\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">request\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#E06C75\">headerQuery\u003C/span>\u003Cspan style=\"color:#ABB2BF\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E5C07B\"> this\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#E06C75\"> data\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> } catch (error) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> console.\u003C/span>\u003Cspan style=\"color:#61AFEF\">error\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(JSON.stringify(\u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\">error\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\">undefined\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, 2))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\"> }\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"options\">Options\u003C/h3>\n\u003Cp>To pass options to the request, for example for a multilingual version with \u003Ca href=\"https://i18n.nuxtjs.org/\">nuxt/i18n\u003C/a> and/or a url parameter in a dynamic page:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// _slug.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">import articleQuery from '~/graphql/queries/articles'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">export default \u003C/span>\u003Cspan style=\"color:#C678DD\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> async\u003C/span>\u003Cspan style=\"color:#61AFEF\"> asyncData\u003C/span>\u003Cspan style=\"color:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"color:#E06C75\">$graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#E06C75\">app\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#E06C75\">params\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> const \u003C/span>\u003Cspan style=\"color:#E06C75\">locale\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#E5C07B\"> app\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">i18n\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">localeProperties\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E06C75\">iso\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> const \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#C678DD\"> await\u003C/span>\u003Cspan style=\"color:#E5C07B\"> $graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">request\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#E06C75\">articleQuery\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> code\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#E06C75\">locale\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> slug\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#E5C07B\">params\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E06C75\">slug\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> })\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> return { \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":862,"imagePaths":884,"frontmatter":885},[863,866,869,872,875,878,881],{"depth":150,"slug":864,"text":865},"the-problem","The problem",{"depth":150,"slug":867,"text":868},"the-solution","The solution 🙌",{"depth":154,"slug":870,"text":871},"the-conf","The conf",{"depth":154,"slug":873,"text":874},"the-request","The request",{"depth":834,"slug":876,"text":877},"inside-a-page","Inside a page",{"depth":834,"slug":879,"text":880},"inside-a-component","Inside a component",{"depth":154,"slug":882,"text":883},"options","Options",[],{"title":851,"subtitle":852,"lang":68,"slug":848,"createdAt":170,"updatedAt":845,"excerpt":886,"tags":887,"type":467},"When the most used gql module doesn't work…",[490],"veille",["Map",269,890],{"id":269,"data":891,"body":893,"filePath":894,"digest":895,"rendered":896},{"lang":16,"title":269,"updatedAt":892},["Date","2023-04-20T17:12:06.000Z"],"- [mmm.page](https://build.mmm.page/) - Éditeur de sites web très simples, en glisser-déposer, pour n'importe quoi.\n- [Color.io](https://www.color.io/) - Éditeur photo en ligne.\n- [Addy's toolkit](https://toolkit.addy.codes/) - Outils et ressources pour les designers et développeurs sites web.\n- [L’accessibilité n’est pas une variable d’ajustement](https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/) — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n > L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\n- [3D en CSS (english)](https://garden.bradwoods.io/notes/css/3d) – Explications et exemples des propriétés 3D en CSS.\n- [Climat : Comment ne pas déprimer ?](https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html) – Podcast.\n- [Fable (english)](https://fable.app) – Application de motion design.\n- [Rive (english)](https://rive.app) – Application de motion design.\n- [Cake Desk](https://cakedesk.app/) – Application de facturation.\n- [Ombre fluide en CSS](https://shadows.brumm.af/) – Générateur.\n- [Smol CSS](https://smolcss.dev/) – Collection de fragments CSS.\n- [Ajustement optique](https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/) (english) – Aligner visuellement plutôt que techniquement.\n- [Datawrapper](https://blog.datawrapper.de/category/datavis-dos-and-donts/) (english) – Conseils pour montrer de la donnée.\n- [Assistivlabs](https://assistivlabs.com/) (english) – Service de test des technologies d'assistance (browserstack mais pour l'accessibilité).\n- [Les caractères fantaisistes et l'accessibilité](https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/) – Explications et exemples de l'enfer que sont les caractères Unicode pour les technologies d'assistance.\n- [Créer un champ `time` sur le web](https://adamsilver.io/blog/designing-a-time-input-backed-by-research/) (english) – Article.\n- [La cascade](https://la-cascade.io) – Collection d'articles sur le CSS.\n- [Tabby](https://tabby.sh) (english) – An alternative terminal app.\n- [Newglyph](https://newglyph.com/) – Fonderie indépendante.\n- [\u003Cspan lang=\"en\">Headless UI\u003C/span>](https://headlessui.com/vue/dialog) (english) – Librairie de composants vue et react.\n- [Vie privée sexy](https://privacy.sexy) (english) – Outils de confidentialité pour windows et macos.\n- [33 concepts JavaScript](https://github.com/leonardomso/33-js-concepts) (english) – Articles.\n- [Formbricks](https://formbricks.com/) (english) – Alternative open source à google form/typeform.\n- [Animations de chargement SVG](https://github.com/n3r4zzurr0/svg-spinners) – Collection.\n- [a11yphant](https://a11yphant.com/) (english) – Challenges de code pour apprendre l'accessibilité.\n- [CSS moderne](https://moderncss.dev/) (english) – Fragments CSS.\n- [Conteneur moderne en CSS](https://twitter.com/KevinJPowell/status/1501555193799925761) (english) – Tweet de Kevin Powell ❤️","src/data/veille/2023.md","1135beec386f207f",{"html":897,"metadata":898},"\u003Cul>\n\u003Cli>\u003Ca href=\"https://build.mmm.page/\">mmm.page\u003C/a> - Éditeur de sites web très simples, en glisser-déposer, pour n’importe quoi.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.color.io/\">Color.io\u003C/a> - Éditeur photo en ligne.\u003C/li>\n\u003Cli>\u003Ca href=\"https://toolkit.addy.codes/\">Addy’s toolkit\u003C/a> - Outils et ressources pour les designers et développeurs sites web.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/\">L’accessibilité n’est pas une variable d’ajustement\u003C/a> — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n\u003Cblockquote>\n\u003Cp>L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\u003C/p>\n\u003C/blockquote>\n\u003C/li>\n\u003Cli>\u003Ca href=\"https://garden.bradwoods.io/notes/css/3d\">3D en CSS (english)\u003C/a> – Explications et exemples des propriétés 3D en CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html\">Climat : Comment ne pas déprimer ?\u003C/a> – Podcast.\u003C/li>\n\u003Cli>\u003Ca href=\"https://fable.app\">Fable (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://rive.app\">Rive (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://cakedesk.app/\">Cake Desk\u003C/a> – Application de facturation.\u003C/li>\n\u003Cli>\u003Ca href=\"https://shadows.brumm.af/\">Ombre fluide en CSS\u003C/a> – Générateur.\u003C/li>\n\u003Cli>\u003Ca href=\"https://smolcss.dev/\">Smol CSS\u003C/a> – Collection de fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/\">Ajustement optique\u003C/a> (english) – Aligner visuellement plutôt que techniquement.\u003C/li>\n\u003Cli>\u003Ca href=\"https://blog.datawrapper.de/category/datavis-dos-and-donts/\">Datawrapper\u003C/a> (english) – Conseils pour montrer de la donnée.\u003C/li>\n\u003Cli>\u003Ca href=\"https://assistivlabs.com/\">Assistivlabs\u003C/a> (english) – Service de test des technologies d’assistance (browserstack mais pour l’accessibilité).\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/\">Les caractères fantaisistes et l’accessibilité\u003C/a> – Explications et exemples de l’enfer que sont les caractères Unicode pour les technologies d’assistance.\u003C/li>\n\u003Cli>\u003Ca href=\"https://adamsilver.io/blog/designing-a-time-input-backed-by-research/\">Créer un champ \u003Ccode>time\u003C/code> sur le web\u003C/a> (english) – Article.\u003C/li>\n\u003Cli>\u003Ca href=\"https://la-cascade.io\">La cascade\u003C/a> – Collection d’articles sur le CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://tabby.sh\">Tabby\u003C/a> (english) – An alternative terminal app.\u003C/li>\n\u003Cli>\u003Ca href=\"https://newglyph.com/\">Newglyph\u003C/a> – Fonderie indépendante.\u003C/li>\n\u003Cli>\u003Ca href=\"https://headlessui.com/vue/dialog\">\u003Cspan lang=\"en\">Headless UI\u003C/span>\u003C/a> (english) – Librairie de composants vue et react.\u003C/li>\n\u003Cli>\u003Ca href=\"https://privacy.sexy\">Vie privée sexy\u003C/a> (english) – Outils de confidentialité pour windows et macos.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/leonardomso/33-js-concepts\">33 concepts JavaScript\u003C/a> (english) – Articles.\u003C/li>\n\u003Cli>\u003Ca href=\"https://formbricks.com/\">Formbricks\u003C/a> (english) – Alternative open source à google form/typeform.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/n3r4zzurr0/svg-spinners\">Animations de chargement SVG\u003C/a> – Collection.\u003C/li>\n\u003Cli>\u003Ca href=\"https://a11yphant.com/\">a11yphant\u003C/a> (english) – Challenges de code pour apprendre l’accessibilité.\u003C/li>\n\u003Cli>\u003Ca href=\"https://moderncss.dev/\">CSS moderne\u003C/a> (english) – Fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/KevinJPowell/status/1501555193799925761\">Conteneur moderne en CSS\u003C/a> (english) – Tweet de Kevin Powell ❤️\u003C/li>\n\u003C/ul>",{"headings":899,"imagePaths":900,"frontmatter":901},[],[],{"lang":16,"title":269,"updatedAt":902},"2023-04-20T17:12:06.000Z","HPsections",["Map",905,906,926,927,943,944,960,961,985,986],"011-offre",{"id":905,"data":907,"body":914,"filePath":915,"digest":916,"rendered":917},{"type":908,"lang":16,"uid":909,"image":910,"order":911,"quickTitle":912,"quickImage":913,"reference":39},"section","offre","/assets/images/home/offre-1.1.svg",1.1,"Mes offres en freelance","/assets/images/home/icon-desktop.svg","## L'offre site web classique\n\nCette offre est destinée à un public souhaitant **se doter d'un site web**, sans forcément intégrer l'accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du [référentiel général d'amélioration de l'accessibilité](https://accessibilite.numerique.gouv.fr/) (\u003Cabbr>RGAA\u003C/abbr>).\n\nL'objectif principal de cette offre étant d'**établir une présence en ligne** pour le client. Que cette dernière ait un but informatif et/ou éditorial.\n\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->","src/data/HP/011-offre.md","290ecd1ed94a1087",{"html":918,"metadata":919},"\u003Ch2 id=\"loffre-site-web-classique\">L’offre site web classique\u003C/h2>\n\u003Cp>Cette offre est destinée à un public souhaitant \u003Cstrong>se doter d’un site web\u003C/strong>, sans forcément intégrer l’accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du \u003Ca href=\"https://accessibilite.numerique.gouv.fr/\">référentiel général d’amélioration de l’accessibilité\u003C/a> (\u003Cabbr>RGAA\u003C/abbr>).\u003C/p>\n\u003Cp>L’objectif principal de cette offre étant d’\u003Cstrong>établir une présence en ligne\u003C/strong> pour le client. Que cette dernière ait un but informatif et/ou éditorial.\u003C/p>\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->",{"headings":920,"imagePaths":924,"frontmatter":925},[921],{"depth":150,"slug":922,"text":923},"loffre-site-web-classique","L’offre site web classique",[],{"type":908,"uid":909,"lang":16,"image":910,"order":911,"quickTitle":912,"quickImage":913,"reference":39},"012-offre",{"id":926,"data":928,"body":931,"filePath":932,"digest":933,"rendered":934},{"type":908,"lang":16,"image":929,"order":930,"reference":50},"/assets/images/home/offre-1.2.svg",1.2,"## L'offre accessibilité avancée\n\nCette offre s'adresse plus spécifiquement aux entités pour lesquelles **l'accessibilité du site est un critère majeur.** Qu'il s'agisse d'une création ou d'une mise en conformité après un audit d'accessibilité.\n\nLorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\n\n- [Rose Primaire](https://roseprimaire.com/) pour le conseil et l'accompagnement du projet ;\n- [Sylvain Plantier](https://jedessinebien.com/) et/ou [Benoît Etchevery](http://ben-etche.com/) pour l'illustration et la direction artistique.\n\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->","src/data/HP/012-offre.md","2a3bf3411b3c171b",{"html":935,"metadata":936},"\u003Ch2 id=\"loffre-accessibilité-avancée\">L’offre accessibilité avancée\u003C/h2>\n\u003Cp>Cette offre s’adresse plus spécifiquement aux entités pour lesquelles \u003Cstrong>l’accessibilité du site est un critère majeur.\u003C/strong> Qu’il s’agisse d’une création ou d’une mise en conformité après un audit d’accessibilité.\u003C/p>\n\u003Cp>Lorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://roseprimaire.com/\">Rose Primaire\u003C/a> pour le conseil et l’accompagnement du projet ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://jedessinebien.com/\">Sylvain Plantier\u003C/a> et/ou \u003Ca href=\"http://ben-etche.com/\">Benoît Etchevery\u003C/a> pour l’illustration et la direction artistique.\u003C/li>\n\u003C/ul>\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->",{"headings":937,"imagePaths":941,"frontmatter":942},[938],{"depth":150,"slug":939,"text":940},"loffre-accessibilité-avancée","L’offre accessibilité avancée",[],{"type":908,"lang":16,"order":930,"image":929,"reference":50},"013-offre",{"id":943,"data":945,"body":948,"filePath":949,"digest":950,"rendered":951},{"type":908,"lang":16,"image":946,"order":947},"/assets/images/home/offre-1.3.svg",1.3,"## Et l'éco-conception alors ?\n\nJe ne conçois pas l'éco-conception comme une offre. C'est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l'éco-conception sans accessibilité, j'applique donc ces méthodologies quelque soit le projet !","src/data/HP/013-offre.md","03e37f364ac27cb4",{"html":952,"metadata":953},"\u003Ch2 id=\"et-léco-conception-alors\">Et l’éco-conception alors ?\u003C/h2>\n\u003Cp>Je ne conçois pas l’éco-conception comme une offre. C’est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l’éco-conception sans accessibilité, j’applique donc ces méthodologies quelque soit le projet !\u003C/p>",{"headings":954,"imagePaths":958,"frontmatter":959},[955],{"depth":150,"slug":956,"text":957},"et-léco-conception-alors","Et l’éco-conception alors ?",[],{"type":908,"lang":16,"order":947,"image":946},"020-methodo",{"id":960,"data":962,"body":967,"filePath":968,"digest":969,"rendered":970},{"type":908,"lang":16,"uid":963,"image":964,"order":150,"quickTitle":965,"quickImage":966},"methodology","/assets/images/home/methodo.svg","Ma méthodologie","/assets/images/home/icon-methodo.svg","## Méthodologie\n\n### Accessibilité par défaut\n\nEngagé pour un web plus accessible, je crée des **sites web** en m'appuyant sur le [référentiel général d'amélioration de l'accessibilité (RGAA)](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) ainsi que sur les bonnes pratiques [Opquast.](https://www.opquast.com/rendre-le-web-meilleur/)\n\n### Sobriété par choix\n\nJe privilégie le développement de **sites statiques** en adoptant une approche [d'éco-conception numérique.](https://eco-conception.designersethiques.org/guide/fr/) \nC'est-à-dire que le site est pensé pour n'embarquer que les fonctionnalités nécessaires à son utilisation.\n\nCette approche présente de **nombreux avantages :**\n\n- chargement rapide des pages ;\n- sécurité renforcée ;\n- coûts serveur réduits ;\n- maintenance facilitée.\n\nLorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l'interface. Cela permet de garantir que **le site reste en ligne** même si le CMS venait à ne plus fonctionner.","src/data/HP/020-methodo.md","75a09b4e0b1e926b",{"html":971,"metadata":972},"\u003Ch2 id=\"méthodologie\">Méthodologie\u003C/h2>\n\u003Ch3 id=\"accessibilité-par-défaut\">Accessibilité par défaut\u003C/h3>\n\u003Cp>Engagé pour un web plus accessible, je crée des \u003Cstrong>sites web\u003C/strong> en m’appuyant sur le \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité (RGAA)\u003C/a> ainsi que sur les bonnes pratiques \u003Ca href=\"https://www.opquast.com/rendre-le-web-meilleur/\">Opquast.\u003C/a>\u003C/p>\n\u003Ch3 id=\"sobriété-par-choix\">Sobriété par choix\u003C/h3>\n\u003Cp>Je privilégie le développement de \u003Cstrong>sites statiques\u003C/strong> en adoptant une approche \u003Ca href=\"https://eco-conception.designersethiques.org/guide/fr/\">d’éco-conception numérique.\u003C/a>\u003Cbr>\nC’est-à-dire que le site est pensé pour n’embarquer que les fonctionnalités nécessaires à son utilisation.\u003C/p>\n\u003Cp>Cette approche présente de \u003Cstrong>nombreux avantages :\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>chargement rapide des pages ;\u003C/li>\n\u003Cli>sécurité renforcée ;\u003C/li>\n\u003Cli>coûts serveur réduits ;\u003C/li>\n\u003Cli>maintenance facilitée.\u003C/li>\n\u003C/ul>\n\u003Cp>Lorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l’interface. Cela permet de garantir que \u003Cstrong>le site reste en ligne\u003C/strong> même si le CMS venait à ne plus fonctionner.\u003C/p>",{"headings":973,"imagePaths":983,"frontmatter":984},[974,977,980],{"depth":150,"slug":975,"text":976},"méthodologie","Méthodologie",{"depth":154,"slug":978,"text":979},"accessibilité-par-défaut","Accessibilité par défaut",{"depth":154,"slug":981,"text":982},"sobriété-par-choix","Sobriété par choix",[],{"type":908,"uid":963,"lang":16,"image":964,"order":150,"quickTitle":965,"quickImage":966},"030-about",{"id":985,"data":987,"body":992,"filePath":993,"digest":994,"rendered":995},{"type":908,"lang":16,"uid":988,"image":989,"order":154,"quickTitle":990,"quickImage":991},"about","/assets/images/home/about.svg","Moi","/assets/images/home/icon-heart.svg","## À propos\n\n### Formations personnelles\n\nAfin de solidifier mes compétences, j'ai suivi les formations et passé les certifications suivantes :\n\n- [Opquast](https://directory.opquast.com/fr/certificat/CTQSKP/) - Maîtrise de la qualité en projet web ;\n- Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\n\n### Formations des autres\n\nDepuis plusieurs années, j'interviens dans différents campus afin de dispenser des cours de développement web.\n\n### Temps libre\n\nJ’essaie de contribuer à des [projets open source](https://git.nardu.in/explore/repos) qui me tiennent à cœur et je m'engage localement avec le collectif [good-it!](https://www.good-it.org/)\n\nAh et j’écris [des articles](/articles) aussi ! Des articles sur le design, le développement web et l’informatique.","src/data/HP/030-about.md","a7abff6d744406ce",{"html":996,"metadata":997},"\u003Ch2 id=\"à-propos\">À propos\u003C/h2>\n\u003Ch3 id=\"formations-personnelles\">Formations personnelles\u003C/h3>\n\u003Cp>Afin de solidifier mes compétences, j’ai suivi les formations et passé les certifications suivantes :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://directory.opquast.com/fr/certificat/CTQSKP/\">Opquast\u003C/a> - Maîtrise de la qualité en projet web ;\u003C/li>\n\u003Cli>Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"formations-des-autres\">Formations des autres\u003C/h3>\n\u003Cp>Depuis plusieurs années, j’interviens dans différents campus afin de dispenser des cours de développement web.\u003C/p>\n\u003Ch3 id=\"temps-libre\">Temps libre\u003C/h3>\n\u003Cp>J’essaie de contribuer à des \u003Ca href=\"https://git.nardu.in/explore/repos\">projets open source\u003C/a> qui me tiennent à cœur et je m’engage localement avec le collectif \u003Ca href=\"https://www.good-it.org/\">good-it!\u003C/a>\u003C/p>\n\u003Cp>Ah et j’écris \u003Ca href=\"/articles\">des articles\u003C/a> aussi ! Des articles sur le design, le développement web et l’informatique.\u003C/p>",{"headings":998,"imagePaths":1011,"frontmatter":1012},[999,1002,1005,1008],{"depth":150,"slug":1000,"text":1001},"à-propos","À propos",{"depth":154,"slug":1003,"text":1004},"formations-personnelles","Formations personnelles",{"depth":154,"slug":1006,"text":1007},"formations-des-autres","Formations des autres",{"depth":154,"slug":1009,"text":1010},"temps-libre","Temps libre",[],{"type":908,"uid":988,"lang":16,"image":989,"order":154,"quickTitle":990,"quickImage":991}] \ No newline at end of file diff --git a/astro.config.mjs b/astro.config.mjs index 8bb12a7..d6cd124 100755 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,25 +1,30 @@ -import { defineConfig } from "astro/config"; +import { defineConfig } from 'astro/config' + +import { transformerMetaHighlight } from '@shikijs/transformers' // https://astro.build/config -import mdx from "@astrojs/mdx"; -import sitemap from "@astrojs/sitemap"; +import mdx from '@astrojs/mdx' +import sitemap from '@astrojs/sitemap' // https://astro.build/config export default defineConfig({ - site: "https://www.nardu.in", - build: { - format: "directory", - }, - i18n: { - locales: ["fr", "en"], - defaultLocale: "fr", - }, - image: { - domains: ["assets.nardu.in"], - remotePatterns: [{ protocol: "https" }], + site: 'https://www.nardu.in', + build: { + format: 'directory' }, - integrations: [ - mdx(), - sitemap(), - ], -}); + i18n: { + locales: ['fr', 'en'], + defaultLocale: 'fr' + }, + image: { + domains: ['assets.nardu.in'], + remotePatterns: [{ protocol: 'https' }] + }, + integrations: [mdx(), sitemap()], + markdown: { + shikiConfig: { + theme: 'one-dark-pro', + transformers: [transformerMetaHighlight()] + } + } +}) diff --git a/bun.lockb b/bun.lockb index 44152a49937e42750d551455e4844b246724d021..3ac73a9d088bfa1618cdc76c421d7e996ed12f2b 100755 GIT binary patch delta 31322 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 delta 30704 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 U7VOoU9Q$amR&bbk?owC(7wX)@`Tzg` diff --git a/package.json b/package.json index 0157e68..7293ee8 100755 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "sharp": "^0.33.5" }, "devDependencies": { + "@shikijs/transformers": "^1.24.4", "autoprefixer": "^10.4.20", "postcss": "^8.4.49", "prettier": "^3.4.2", diff --git a/src/components/EditorialContent.astro b/src/components/EditorialContent.astro index 236e35f..a2f7d7d 100755 --- a/src/components/EditorialContent.astro +++ b/src/components/EditorialContent.astro @@ -10,8 +10,6 @@ const { Content, headings } = await render(content) const toc = headings.map((heading) => { return heading }) - -import '../styles/vendor/one-dark-pro.css' --- <div class='sidebar region'> diff --git a/src/components/MetaDate.astro b/src/components/MetaDate.astro index 3d66d63..2ceb8fa 100755 --- a/src/components/MetaDate.astro +++ b/src/components/MetaDate.astro @@ -1,6 +1,12 @@ --- +import type { ArticleFrontmatter, FragmentFrontmatter } from '../content.config' + +type Props = { + item: ArticleFrontmatter | FragmentFrontmatter +} + const { item } = Astro.props -const locale: 'fr' | 'en' = item.frontmatter.lang +const locale: 'fr' | 'en' = item.lang let ui = { published: 'Publié le', @@ -43,9 +49,9 @@ function rawDate(date: Date) { ) } { - formatDate(item.createdAt) != formatDate(item.updatedAt) && - !!item.createdAt && - !!item.updatedAt && ( + !!item.createdAt && + !!item.updatedAt && + formatDate(item.createdAt) != formatDate(item.updatedAt) && ( <p class='meta__date'> {ui.updated} : <time datetime={rawDate(item.updatedAt)}> diff --git a/src/content/fragments/fr/visited-links.md b/src/content/fragments/fr/visited-links.md index eb4aaa9..5d00dba 100755 --- a/src/content/fragments/fr/visited-links.md +++ b/src/content/fragments/fr/visited-links.md @@ -45,7 +45,7 @@ J'ai personnellement choisi de faire différemment. J'ai décidé d'utiliser un ### Le code -```css +```css {1,4-6} a { position: relative; text-decoration: none; diff --git a/src/i18n/en.json b/src/i18n/en.json deleted file mode 100755 index 7ceeebf..0000000 --- a/src/i18n/en.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "accueil": "home", - "tagline": "Freelance web developer specialized in accessibility.", - "copyright": "(re)Made with Astro", - "contact": { - "title": "contact", - "email": "Send me an email (open in application).", - "tel": "Call or text me (open in application).", - "contenuVide": "Soon: really nice content." - }, - "header": { - "skipLink": "Skip to content", - "mainNav": "Main menu", - "homeLink": "Back to homepage" - }, - "sitemap": "Site map", - "prevNext": { - "contenus": "Similar content", - "precedent": "Previous", - "suivant": "Next" - }, - "article": { - "titre": "articles", - "tagline": "I blog, sometimes.", - "published": "Published on {datetime|date(options)}" - }, - "meta": { - "publication": "Published on", - "modification": "Last updated on", - "credit": "Image by" - }, - "fragments": { - "titre": "snippets", - "tagline": "School with Nicool." - }, - "references": { - "titre": "work", - "slug": "work", - "cta": "Visit website", - "tagline": "Some work." - }, - "veille": { - "titre": "Around the web", - "tagline": "Some links that interested me." - }, - "erreur": { - "introuvable": "Sorry, page not found.", - "autre": "Oups… sorry about that.", - "lienRetour": "Back to the home page" - }, - "seo": { - "meta": { - "description": "Web developer specialized in accessibility and eco-design in Toulouse, France. Development of custom websites, RGAA compliance, maintenance, etc." - }, - "article": { - "title": "Articles", - "description": "A few articles about graphic design and front-end development." - }, - "code": { - "title": "Snippets", - "description": "Snippets of fresh, easy and accessible code." - }, - "references": { - "title": "Work", - "description": "A few case studies I worked on as a front-end developer." - } - } -} diff --git a/src/i18n/fr.json b/src/i18n/fr.json deleted file mode 100755 index 7583f20..0000000 --- a/src/i18n/fr.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "accueil": "accueil", - "tagline": "Développeur web spécialisé en accessibilité.", - "copyright": "(re)Fait avec Astro", - "contact": { - "title": "contact", - "email": "Envoyez-moi un mail (ouverture du logiciel automatique).", - "tel": "Contactez-moi par téléphone (ouverture du logiciel automatique)." - }, - "contenuVide": "Bientôt ici : du contenu de qualité", - "header": { - "skipLink": "Accéder au contenu", - "mainNav": "Menu principal", - "homeLink": "Accueil du site" - }, - "sitemap": "Plan du site", - "prevNext": { - "contenus": "Contenus similaires", - "precedent": "Précédent", - "suivant": "Suivant" - }, - "article": { - "titre": "articles", - "tagline": "Je blog, un peu.", - "published": "Publié le {datetime|date(options)}" - }, - "meta": { - "publication": "Publié le", - "modification": "Mis à jour le", - "credit": "Image par" - }, - "fragments": { - "titre": "fragments", - "tagline": "Les tutos de Nico mdr." - }, - "references": { - "titre": "références", - "slug": "references", - "cta": "Consulter le site", - "tagline": "Quelques références." - }, - "veille": { - "titre": "veille", - "tagline": "Des liens, en vrac." - }, - "erreur": { - "introuvable": "Page introuvable", - "autre": "Oups… désolé pour cette erreur.", - "lienRetour": "Retour à l’accueil" - }, - "seo": { - "meta": { - "description": "Développeur web spécialisé en accessibilité numérique et éco-conception à Toulouse. Création de sites web sur mesure, mise en conformité RGAA, maintenance, etc." - }, - "article": { - "title": "Articles", - "description": "Quelques articles sur le développement web front-end et l'informatique à Toulouse." - }, - "code": { - "title": "Fragments", - "description": "Fragments de codes stylés, faciles et accessibles." - }, - "references": { - "title": "Références", - "description": "Quelques travaux réalisés en tant que et développeur web front-end à Toulouse." - } - } -} diff --git a/src/i18n/ui.ts b/src/i18n/ui.ts deleted file mode 100644 index e83786c..0000000 --- a/src/i18n/ui.ts +++ /dev/null @@ -1,150 +0,0 @@ -export const languages = { - en: 'English', - fr: 'Français' -} - -export const defaultLang = 'fr' - -export const ui = { - en: { - accueil: 'home', - tagline: 'Freelance web developer specialized in accessibility.', - copyright: '(re)Made with Astro', - contact: { - title: 'contact', - email: 'Send me an email (open in application).', - tel: 'Call or text me (open in application).', - contenuVide: 'Soon: really nice content.' - }, - header: { - skipLink: 'Skip to content', - mainNav: 'Main menu', - homeLink: 'Back to homepage' - }, - sitemap: 'Site map', - prevNext: { - contenus: 'Similar content', - precedent: 'Previous', - suivant: 'Next' - }, - article: { - titre: 'articles', - tagline: 'I blog, sometimes.', - published: 'Published on {datetime|date(options)}' - }, - meta: { - publication: 'Published on', - modification: 'Last updated on', - credit: 'Image by' - }, - fragments: { - titre: 'snippets', - tagline: 'School with Nicool.' - }, - references: { - titre: 'work', - slug: 'work', - cta: 'Visit website', - tagline: 'Some work.' - }, - veille: { - titre: 'Around the web', - tagline: 'Some links that interested me.' - }, - erreur: { - introuvable: 'Sorry, page not found.', - autre: 'Oups… sorry about that.', - lienRetour: 'Back to the home page' - }, - seo: { - meta: { - description: - 'Web developer specialized in accessibility and eco-design in Toulouse, France. Development of custom websites, RGAA compliance, maintenance, etc.' - }, - article: { - title: 'Articles', - description: - 'A few articles about graphic design and front-end development.' - }, - code: { - title: 'Snippets', - description: 'Snippets of fresh, easy and accessible code.' - }, - references: { - title: 'Work', - description: 'A few case studies I worked on as a front-end developer.' - } - } - }, - fr: { - accueil: 'accueil', - tagline: 'Développeur web spécialisé en accessibilité.', - copyright: '(re)Fait avec Astro', - contact: { - title: 'contact', - email: 'Envoyez-moi un mail (ouverture du logiciel automatique).', - tel: 'Contactez-moi par téléphone (ouverture du logiciel automatique).' - }, - contenuVide: 'Bientôt ici : du contenu de qualité', - header: { - skipLink: 'Accéder au contenu', - mainNav: 'Menu principal', - homeLink: 'Accueil du site' - }, - sitemap: 'Plan du site', - prevNext: { - contenus: 'Contenus similaires', - precedent: 'Précédent', - suivant: 'Suivant' - }, - article: { - titre: 'articles', - tagline: 'Je blog, un peu.', - published: 'Publié le {datetime|date(options)}' - }, - meta: { - publication: 'Publié le', - modification: 'Mis à jour le', - credit: 'Image par' - }, - fragments: { - titre: 'fragments', - tagline: 'Les tutos de Nico mdr.' - }, - references: { - titre: 'références', - slug: 'references', - cta: 'Consulter le site', - tagline: 'Quelques références.' - }, - veille: { - titre: 'veille', - tagline: 'Des liens, en vrac.' - }, - erreur: { - introuvable: 'Page introuvable', - autre: 'Oups… désolé pour cette erreur.', - lienRetour: 'Retour à l’accueil' - }, - seo: { - meta: { - description: - 'Développeur web spécialisé en accessibilité numérique et éco-conception à Toulouse. Création de sites web sur mesure, mise en conformité RGAA, maintenance, etc.' - }, - article: { - title: 'Articles', - description: - "Quelques articles sur le développement web front-end et l'informatique à Toulouse." - }, - code: { - title: 'Fragments', - description: 'Fragments de codes stylés, faciles et accessibles.' - }, - references: { - title: 'Références', - description: - 'Quelques travaux réalisés en tant que et développeur web front-end à Toulouse.' - } - } - } -} as const diff --git a/src/pages/articles/[id].astro b/src/pages/articles/[id].astro index a500d1c..b7ee360 100755 --- a/src/pages/articles/[id].astro +++ b/src/pages/articles/[id].astro @@ -1,37 +1,16 @@ --- -import { createStaticPaths } from 'astro-i18n' - -import { getCollection } from 'astro:content' - import EditorialContent from '../../components/EditorialContent.astro' import BaseLayout from '../../layouts/BaseLayout.astro' +import { getCollection } from 'astro:content' -export const getStaticPaths = createStaticPaths( - async ({ langCode }) => { - const articles = await getCollection('articles', ({ data }) => { - console.log(langCode) - return data.lang === langCode - }) - return articles.map((article) => ({ - params: { id: article.data.slug }, - props: { article } - })) - }, - import.meta.url -) - -// export async function getStaticPaths() { -// const articles = await getCollection("articles", ({ data }) => { -// console.log(astroI18n.langCode); -// return data.lang === astroI18n.langCode; -// }); -// console.log(articles); - -// return articles.map((article) => ({ -// params: { slug: article.data.slug }, -// props: { article }, -// })); -// } +// 1. Generate a new path for every collection entry +export async function getStaticPaths() { + const articles = await getCollection('articles') + return articles.map((article) => ({ + params: { id: article.data.slug }, + props: { article } + })) +} const { article } = Astro.props --- diff --git a/src/pages/articles/i18n/en.json b/src/pages/articles/i18n/en.json deleted file mode 100755 index d19f427..0000000 --- a/src/pages/articles/i18n/en.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "pageName": "Articles", - "subtitle": "I blog, sometimes." -} diff --git a/src/pages/articles/i18n/fr.json b/src/pages/articles/i18n/fr.json deleted file mode 100755 index f280ce0..0000000 --- a/src/pages/articles/i18n/fr.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "pageName": "Articles", - "subtitle": "Je blog, un peu." -} diff --git a/src/pages/articles/index.astro b/src/pages/articles/index.astro index 6536934..42dc653 100755 --- a/src/pages/articles/index.astro +++ b/src/pages/articles/index.astro @@ -1,29 +1,42 @@ --- -import { l, t, astroI18n } from "astro-i18n"; -astroI18n.init(Astro); - // New astro content collections -import { getCollection } from "astro:content"; +import { getCollection } from 'astro:content' -import BaseLayout from "../../layouts/BaseLayout.astro"; -import ListCards from "../../components/ListCards.astro"; +import BaseLayout from '../../layouts/BaseLayout.astro' +import ListCards from '../../components/ListCards.astro' -const localizedPost = await getCollection("articles", ({ data }) => { - return data.lang === astroI18n.langCode && !data.draft; -}); -// sort articles by descending publication date -const sortedArticles = localizedPost.sort( - (a, b) => b.data.createdAt - a.data.createdAt -); +const frArticles = await getCollection('articles', ({ data }) => { + return data.lang === 'fr' && !data.draft +}).then((entries) => + // sort results + entries.sort( + (a, b) => b.data.createdAt.getTime() - a.data.createdAt.getTime() + ) +) +const enArticles = await getCollection('articles', ({ data }) => { + return data.lang === 'en' && !data.draft +}).then((entries) => + // sort results + entries.sort( + (a, b) => b.data.createdAt.getTime() - a.data.createdAt.getTime() + ) +) -const pageTitle = t("index.articles.pageName"); +const pageTitle = 'Articles' --- <BaseLayout pageTitle={pageTitle}> - <section class="region flow"> - <h1>{t("index.articles.pageName")}</h1> - <h2>{t("index.articles.subtitle")}</h2> - <ListCards list={sortedArticles} routeName={t("article.titre")} /> + <section class='region flow'> + <h1>{pageTitle}</h1> + <h2>Je blog, un peu.</h2> + <section class='flow'> + <h3>En français</h3> + <ListCards list={frArticles} routeName='articles' /> + </section> + <section class='flow' lang='en'> + <h3>In english</h3> + <ListCards list={enArticles} routeName='articles' /> + </section> </section> </BaseLayout> @@ -31,14 +44,10 @@ const pageTitle = t("index.articles.pageName"); .flow h2 + :global(*) { margin-block-start: var(--space-m-l); } - h1 { - text-transform: capitalize; - } - h1, - h2 { - padding-inline-start: var(--space-xs-s); - } h2 { color: var(--color-brique); } + section + section { + margin-block-start: var(--space-l-xl); + } </style> diff --git a/src/pages/fragments/[id].astro b/src/pages/fragments/[id].astro index a95d2d9..8e584a9 100755 --- a/src/pages/fragments/[id].astro +++ b/src/pages/fragments/[id].astro @@ -1,38 +1,21 @@ --- -import { createStaticPaths } from 'astro-i18n' -// import { astroI18n } from "astro-i18n"; - import { getCollection } from 'astro:content' import EditorialContent from '../../components/EditorialContent.astro' import BaseLayout from '../../layouts/BaseLayout.astro' -export const getStaticPaths = createStaticPaths( - async ({ langCode }) => { - const snippets = await getCollection('fragments', ({ data }) => { - return data.lang === langCode - }) - return snippets.map((snippet) => ({ - params: { id: snippet.data.slug }, - props: { snippet } - })) - }, - import.meta.url -) +// 1. Generate a new path for every collection entry +export async function getStaticPaths() { + const fragments = await getCollection('fragments') + return fragments.map((fragment) => ({ + params: { id: fragment.data.slug }, + props: { fragment } + })) +} -// export async function getStaticPaths() { -// const snippets = await getCollection("fragments", ({ data }) => { -// return data.lang === astroI18n.langCode; -// }); -// return snippets.map((snippet) => ({ -// params: { slug: snippet.data.slug }, -// props: { snippet }, -// })); -// } - -const { snippet } = Astro.props +const { fragment } = Astro.props --- -<BaseLayout pageTitle={snippet.data.title}> - <EditorialContent content={snippet} /> +<BaseLayout pageTitle={fragment.data.title}> + <EditorialContent content={fragment} /> </BaseLayout> diff --git a/src/pages/fragments/i18n/en.json b/src/pages/fragments/i18n/en.json deleted file mode 100755 index ad96840..0000000 --- a/src/pages/fragments/i18n/en.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "pageName": "Snippets", - "subtitle": "School with Nicool." -} diff --git a/src/pages/fragments/i18n/fr.json b/src/pages/fragments/i18n/fr.json deleted file mode 100755 index 67fc483..0000000 --- a/src/pages/fragments/i18n/fr.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "pageName": "Fragments", - "subtitle": "Les tutos de Nico mdr." -} diff --git a/src/pages/fragments/index.astro b/src/pages/fragments/index.astro index 4bf18a9..9460240 100755 --- a/src/pages/fragments/index.astro +++ b/src/pages/fragments/index.astro @@ -1,29 +1,42 @@ --- -import { l, t, astroI18n } from "astro-i18n"; -astroI18n.init(Astro); - // New astro content collections -import { getCollection } from "astro:content"; +import { getCollection } from 'astro:content' -import BaseLayout from "../../layouts/BaseLayout.astro"; -import ListCards from "../../components/ListCards.astro"; +import BaseLayout from '../../layouts/BaseLayout.astro' +import ListCards from '../../components/ListCards.astro' -const localizedPost = await getCollection("fragments", ({ data }) => { - return data.lang === astroI18n.langCode && !data.draft; -}); -// sort snippets by descending publication date -const sortedPosts = localizedPost.sort( - (a, b) => b.data.createdAt - a.data.createdAt -); +const frFragments = await getCollection('fragments', ({ data }) => { + return data.lang === 'fr' && !data.draft +}).then((entries) => + // sort results + entries.sort( + (a, b) => b.data.createdAt.getTime() - a.data.createdAt.getTime() + ) +) +const enFragments = await getCollection('fragments', ({ data }) => { + return data.lang === 'en' && !data.draft +}).then((entries) => + // sort results + entries.sort( + (a, b) => b.data.createdAt.getTime() - a.data.createdAt.getTime() + ) +) -const pageTitle = t("index.fragments.pageName"); +const pageTitle = 'Fragments' --- <BaseLayout pageTitle={pageTitle}> - <section class="region flow"> - <h1>{t("index.fragments.pageName")}</h1> - <h2>{t("index.fragments.subtitle")}</h2> - <ListCards list={sortedPosts} routeName={t("fragments.titre")} /> + <section class='region flow'> + <h1>{pageTitle}</h1> + <h2>Les tutos de Nico mdr</h2> + <section class='flow'> + <h3>En français</h3> + <ListCards list={frFragments} routeName='fragments' /> + </section> + <section class='flow' lang='en'> + <h3>In english</h3> + <ListCards list={enFragments} routeName='fragments' /> + </section> </section> </BaseLayout> @@ -31,14 +44,10 @@ const pageTitle = t("index.fragments.pageName"); .flow h2 + :global(*) { margin-block-start: var(--space-m-l); } - h1 { - text-transform: capitalize; - } - h1, - h2 { - padding-inline-start: var(--space-xs-s); - } h2 { color: var(--color-brique); } + section + section { + margin-block-start: var(--space-l-xl); + } </style> diff --git a/src/pages/i18n/en.json b/src/pages/i18n/en.json deleted file mode 100755 index 307f442..0000000 --- a/src/pages/i18n/en.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "title": "Crafting <a href='#methodology' class='clean-link'>sober and accessible</a> <span class='highlight'>websites</span>", - "subtitle": "Learn more about…", - "quoi": "I design <strong>websites</strong> and <strong>web applications</strong> following <a href='https://www.a11yproject.com/' title='A11y project’s website (new window)' target='_blank' rel='noreferer noopener' >accessibility</a> best practices.", - "comment": "More precisely, I create web and mobile interfaces. From UX to UI, from development to deployment. I put digital accessibility standards, for which I have obtained the <a href='https://directory.opquast.com/fr/certificat/CTQSKP/' title='My Opquast certificate (new window)' target='_blank' rel='noreferer noopener'>Opquast certification</a>, forwards. I also keep <a href='https://en.wikipedia.org/wiki/Ecological_design' title='eco-design definition (new window)' target='_blank' rel='noreferer noopener'>eco-design</a> in mind when working.", - "opensource": "I try to contribute to <a class='u-nice-links' href='https://git.nardu.in/explore/repos' title='Open source projects I worked on (new window)' target='_blank' rel='noreferer noopener'>open source projects</a> that I enjoy.", - "writing": "Oh and I write <a class='u-nice-links' href='/en/articles'>articles!</a> Articles about design and the web in general.", - "latestProjects": "Latest projects", - "latestArticles": "Latest articles", - "allProjects": "All projects", - "allArticles": "Browse all articles", - "latestSnippets": "Latest snippets", - "allSnippets": "Browse all snippets", - "toc": "table of content" -} diff --git a/src/pages/i18n/fr.json b/src/pages/i18n/fr.json deleted file mode 100755 index 61f76ed..0000000 --- a/src/pages/i18n/fr.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "title": "Création de <span class='highlight'>sites web</span> <a href='/articles/faq' class='clean-link'>sobres et accessibles</a>", - "subtitle": "Apprenez-en plus sur…", - "quoi": "Je crée des <strong>sites</strong> et des <strong>applications web</strong> en suivant les bonnes pratiques <a href='https://access42.net/decouvrir-accessibilite' title='Définition selon Access42 (nouvelle fenêtre)' target='_blank' rel='noreferer noopener' >d’accessibilités</a>.", - "comment": "Plus précisément, je crée des interfaces web et mobiles. De l’ergonomie jusqu’au design final, de l’intégration jusqu’à la mise en ligne. Je mets en avant les standards d’accessibilité numérique, pour lesquels j’ai obtenu la <a href='https://directory.opquast.com/fr/certificat/CTQSKP/' title='Certificat Opquast personnel (nouvelle fenêtre)' target='_blank' rel='noreferer noopener'>certification Opquast</a>. Je m’inscris également dans une démarche <a href='https://www.ademe.fr/expertises/consommer-autrement/passer-a-laction/ameliorer-pratiques/lecoconception' title='Définition de l’ADEME (nouvelle fenêtre)' rel='noopener noreferer'>d’éco-conception</a> des services que je propose.", - "opensource": "J’essaie de contribuer à des <a href='https://git.nardu.in/explore/repos' title='Projets sur lesquels j’ai travaillé (nouvelle fenêtre)' target='_blank' rel='noreferer noopener'>projets open source</a> qui me tiennent à cœur.", - "writing": "Ah et j’écris <a href='/articles'>des articles</a> aussi ! Des articles sur le graphisme et l’informatique.", - "latestProjects": "Derniers projets", - "latestArticles": "Derniers articles", - "allProjects": "Tous les projets", - "allArticles": "Consulter tous les articles", - "latestSnippets": "Derniers fragments", - "allSnippets": "Consulter tous les fragments", - "toc": "table des matières" -} diff --git a/src/pages/references/i18n/en.json b/src/pages/references/i18n/en.json deleted file mode 100755 index 5105d00..0000000 --- a/src/pages/references/i18n/en.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "pageName": "Work", - "subtitle": "Some fine websites right here." -} diff --git a/src/pages/references/i18n/fr.json b/src/pages/references/i18n/fr.json deleted file mode 100755 index e04ca6b..0000000 --- a/src/pages/references/i18n/fr.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "pageName": "Références", - "subtitle": "Des sites web de qualité." -} diff --git a/src/pages/references/index.astro b/src/pages/references/index.astro index c976dae..8ccb11e 100755 --- a/src/pages/references/index.astro +++ b/src/pages/references/index.astro @@ -1,29 +1,24 @@ --- -import { l, t, astroI18n } from "astro-i18n"; -astroI18n.init(Astro); +import { getCollection } from 'astro:content' -// New astro content collections -import { getCollection } from "astro:content"; +import BaseLayout from '../../layouts/BaseLayout.astro' +import ListCards from '../../components/ListCards.astro' -import BaseLayout from "../../layouts/BaseLayout.astro"; -import ListCards from "../../components/ListCards.astro"; +const allReferences = await getCollection('references').then((entries) => + // sort results + entries.sort( + (a, b) => b.data.createdAt.getTime() - a.data.createdAt.getTime() + ) +) -const localizedPost = await getCollection("references", ({ data }) => { - return data.lang === astroI18n.langCode && !data.draft; -}); -// sort references by descending publication date -const sortedReferences = localizedPost.sort( - (a, b) => b.data.createdAt - a.data.createdAt -); - -const pageTitle = t("index.references.pageName"); +const pageTitle = 'Références' --- <BaseLayout pageTitle={pageTitle}> - <section class="region flow"> - <h1>{t("index.references.pageName")}</h1> - <h2>{t("index.references.subtitle")}</h2> - <ListCards list={sortedReferences} routeName={t("references.slug")} /> + <section class='region flow'> + <h1>{pageTitle}</h1> + <h2>Des sites web de qualité.</h2> + <ListCards list={allReferences} routeName='references' /> </section> </BaseLayout> @@ -31,13 +26,6 @@ const pageTitle = t("index.references.pageName"); .flow h2 + :global(*) { margin-block-start: var(--space-m-l); } - h1 { - text-transform: capitalize; - } - h1, - h2 { - padding-inline-start: var(--space-xs-s); - } h2 { color: var(--color-brique); } diff --git a/src/pages/veille/i18n/en.json b/src/pages/veille/i18n/en.json deleted file mode 100755 index 9660f98..0000000 --- a/src/pages/veille/i18n/en.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "pageName": "External stuff", - "subtitle": "Links, articles, videos…" -} diff --git a/src/pages/veille/i18n/fr.json b/src/pages/veille/i18n/fr.json deleted file mode 100755 index b10f877..0000000 --- a/src/pages/veille/i18n/fr.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "pageName": "Veille", - "subtitle": "Des liens, des articles, des vidéos… en vrac." -} diff --git a/src/pages/veille/index.astro b/src/pages/veille/index.astro index 02dd5c3..71011d8 100755 --- a/src/pages/veille/index.astro +++ b/src/pages/veille/index.astro @@ -1,34 +1,35 @@ --- -import { t, astroI18n } from "astro-i18n"; -astroI18n.init(Astro); +import { getCollection, render } from 'astro:content' -const pageTitle = t("index.veille.pageName"); +import BaseLayout from '../../layouts/BaseLayout.astro' -import BaseLayout from "../../layouts/BaseLayout.astro"; -import MetaDate from "../../components/MetaDate.astro"; +const allVeille = await getCollection('veille').then(async (entries) => { + return Promise.all( + entries.map(async (entry) => { + // render and return entry + content + const { Content } = await render(entry) + return { + ...entry, + Content + } + }) + ) +}) -// get all content -const allSections = Object.values( - import.meta.glob("../../data/veille/**/*.md", { eager: true }) -); -// only keep the right locale version -const localizedSections = allSections.filter((section) => { - return section.frontmatter.lang === astroI18n.langCode; -}); +const pageTitle = 'Veille' --- <BaseLayout pageTitle={pageTitle}> - <section class="region flow"> + <section class='region flow'> <h1>{pageTitle}</h1> - <p>{t("index.veille.subtitle")}</p> + <p>Des liens, des articles, des vidéos… en vrac.</p> </section> { - localizedSections.map((section) => ( - <section class="flow content"> - <h2>{section.frontmatter.title}</h2> - <MetaDate item={section.frontmatter} /> - <section.Content /> + allVeille.map(({ data, Content }) => ( + <section class='flow content'> + <h2>{data.title}</h2> + <Content /> </section> )) } diff --git a/src/styles/global/global-styles.css b/src/styles/global/global-styles.css index 89438b7..9fe406e 100755 --- a/src/styles/global/global-styles.css +++ b/src/styles/global/global-styles.css @@ -79,13 +79,13 @@ hr.small { block-size: 2px; } -ul:not([role="list"]), -ol:not([role="list"]) { +ul:not([role='list']), +ol:not([role='list']) { padding-inline-start: 1rem; } -ul:not([role="list"]) > li + li, -ol:not([role="list"]) > li + li { +ul:not([role='list']) > li + li, +ol:not([role='list']) > li + li { margin-block-start: var(--space-xs); } @@ -159,7 +159,7 @@ button[disabled] { text-decoration: none; } .nice-link::after { - content: ""; + content: ''; position: absolute; left: 0; bottom: -2px; @@ -204,24 +204,46 @@ blockquote code { /* code highlight */ -.content :not(pre) > code { - padding: var(--space-3xs) var(--space-2xs); - position: relative; - display: inline-block; +.astro-code, +code { font-size: var(--size--1); font-family: var(--font-code); } +.astro-code { + position: relative; + border-radius: var(--radius-small); + padding-block: var(--space-xs); + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; -.content :not(pre) > code:before { - content: ""; - position: absolute; - inset: 0px -1px; - background: var(--color-light-grey); - border-radius: 4px; - z-index: -1; + code { + padding-inline: var(--space-s); + white-space: pre-wrap; + display: block; + inline-size: fit-content; + min-inline-size: 100%; + } } -.content code[class*="language-"], -.content pre[class*="language-"] { - white-space: pre-wrap; +.line { + &.highlighted::before { + content: ''; + position: absolute; + display: inline-block; + inline-size: 100%; + block-size: 1lh; + inset-inline-start: 0; + background-color: hsla(0, 0%, 80%, 0.1); + } } -- 2.45.2 From fa61a2816076382b5e39011b9ff9dc30f68e7c12 Mon Sep 17 00:00:00 2001 From: nico <contact@nardu.in> Date: Wed, 1 Jan 2025 22:35:54 +0100 Subject: [PATCH 06/16] cleanup + better code blocks + redirects --- .astro/content-modules.mjs | 6 +- .astro/content.d.ts | 206 ------------- .astro/data-store.json | 2 +- astro.config.mjs | 54 +++- bun.lockb | Bin 222308 -> 231283 bytes package.json | 2 + src/content/articles/en/2025.md | 13 + src/content/articles/en/sci-hub-blocage.mdx | 2 +- src/content/articles/fr/sci-hub-blocage.mdx | 2 +- src/content/fragments/en/acme-sh-tls-cert.md | 6 +- .../fragments/en/nuxt-graphql-static.md | 60 ++-- src/content/fragments/fr/acme-sh-tls-cert.md | 6 +- src/content/fragments/fr/image-full.mdx | 47 +-- .../fragments/fr/nuxt-graphql-static.md | 60 ++-- src/content/fragments/fr/visited-links.md | 2 +- .../wotfard/wotfard-medium-webfont.woff2 | Bin 33004 -> 0 bytes .../wotfard/wotfard-regular-webfont.woff2 | Bin 31908 -> 0 bytes .../wotfard/wotfard-semibold-webfont.woff2 | Bin 33060 -> 0 bytes src/pages/articles/[id].astro | 6 +- src/pages/articles/index.astro | 2 +- src/pages/fragments/[id].astro | 5 +- src/pages/fragments/index.astro | 2 +- src/pages/index.astro | 1 - src/styles/compositions/sidebar.css | 2 +- src/styles/editorial/buttons.css | 150 +++++----- src/styles/global/fonts.css | 35 --- src/styles/global/global-styles.css | 42 +-- src/styles/global/reset.css | 56 ++-- src/styles/global/variables.css | 8 +- src/styles/style.css | 24 +- src/styles/utilities/waves.css | 71 ----- src/styles/utilities/wrapper.css | 1 + src/styles/vendor/one-dark-pro.css | 271 ------------------ src/utils/i18n.ts | 28 -- 34 files changed, 284 insertions(+), 888 deletions(-) create mode 100644 src/content/articles/en/2025.md delete mode 100755 src/fonts/wotfard/wotfard-medium-webfont.woff2 delete mode 100755 src/fonts/wotfard/wotfard-regular-webfont.woff2 delete mode 100755 src/fonts/wotfard/wotfard-semibold-webfont.woff2 delete mode 100755 src/styles/global/fonts.css delete mode 100755 src/styles/utilities/waves.css delete mode 100755 src/styles/vendor/one-dark-pro.css delete mode 100644 src/utils/i18n.ts diff --git a/.astro/content-modules.mjs b/.astro/content-modules.mjs index 4169cc6..2ca7e6f 100644 --- a/.astro/content-modules.mjs +++ b/.astro/content-modules.mjs @@ -2,13 +2,13 @@ export default new Map([ ["src/content/articles/en/after-effects-expressions.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fafter-effects-expressions.mdx&astroContentModuleFlag=true")], ["src/content/articles/en/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], +["src/content/fragments/en/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fimage-full.mdx&astroContentModuleFlag=true")], ["src/content/articles/en/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], ["src/content/articles/en/video-compression.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fvideo-compression.mdx&astroContentModuleFlag=true")], +["src/content/fragments/en/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], +["src/content/articles/fr/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], ["src/content/fragments/fr/buttons.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fbuttons.mdx&astroContentModuleFlag=true")], ["src/content/fragments/fr/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fimage-full.mdx&astroContentModuleFlag=true")], ["src/content/fragments/fr/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], -["src/content/articles/fr/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], -["src/content/fragments/en/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fimage-full.mdx&astroContentModuleFlag=true")], -["src/content/fragments/en/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], ["src/content/articles/fr/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")]]); \ No newline at end of file diff --git a/.astro/content.d.ts b/.astro/content.d.ts index 6ea9a82..e69de29 100644 --- a/.astro/content.d.ts +++ b/.astro/content.d.ts @@ -1,206 +0,0 @@ -declare module 'astro:content' { - interface Render { - '.mdx': Promise<{ - Content: import('astro').MarkdownInstance<{}>['Content']; - headings: import('astro').MarkdownHeading[]; - remarkPluginFrontmatter: Record<string, any>; - components: import('astro').MDXInstance<{}>['components']; - }>; - } -} - -declare module 'astro:content' { - export interface RenderResult { - Content: import('astro/runtime/server/index.js').AstroComponentFactory; - headings: import('astro').MarkdownHeading[]; - remarkPluginFrontmatter: Record<string, any>; - } - interface Render { - '.md': Promise<RenderResult>; - } - - export interface RenderedContent { - html: string; - metadata?: { - imagePaths: Array<string>; - [key: string]: unknown; - }; - } -} - -declare module 'astro:content' { - type Flatten<T> = T extends { [K: string]: infer U } ? U : never; - - export type CollectionKey = keyof AnyEntryMap; - export type CollectionEntry<C extends CollectionKey> = Flatten<AnyEntryMap[C]>; - - export type ContentCollectionKey = keyof ContentEntryMap; - export type DataCollectionKey = keyof DataEntryMap; - - type AllValuesOf<T> = T extends any ? T[keyof T] : never; - type ValidContentEntrySlug<C extends keyof ContentEntryMap> = AllValuesOf< - ContentEntryMap[C] - >['slug']; - - /** @deprecated Use `getEntry` instead. */ - export function getEntryBySlug< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug<C> | (string & {}), - >( - collection: C, - // Note that this has to accept a regular string too, for SSR - entrySlug: E, - ): E extends ValidContentEntrySlug<C> - ? Promise<CollectionEntry<C>> - : Promise<CollectionEntry<C> | undefined>; - - /** @deprecated Use `getEntry` instead. */ - export function getDataEntryById<C extends keyof DataEntryMap, E extends keyof DataEntryMap[C]>( - collection: C, - entryId: E, - ): Promise<CollectionEntry<C>>; - - export function getCollection<C extends keyof AnyEntryMap, E extends CollectionEntry<C>>( - collection: C, - filter?: (entry: CollectionEntry<C>) => entry is E, - ): Promise<E[]>; - export function getCollection<C extends keyof AnyEntryMap>( - collection: C, - filter?: (entry: CollectionEntry<C>) => unknown, - ): Promise<CollectionEntry<C>[]>; - - export function getEntry< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug<C> | (string & {}), - >(entry: { - collection: C; - slug: E; - }): E extends ValidContentEntrySlug<C> - ? Promise<CollectionEntry<C>> - : Promise<CollectionEntry<C> | undefined>; - export function getEntry< - C extends keyof DataEntryMap, - E extends keyof DataEntryMap[C] | (string & {}), - >(entry: { - collection: C; - id: E; - }): E extends keyof DataEntryMap[C] - ? Promise<DataEntryMap[C][E]> - : Promise<CollectionEntry<C> | undefined>; - export function getEntry< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug<C> | (string & {}), - >( - collection: C, - slug: E, - ): E extends ValidContentEntrySlug<C> - ? Promise<CollectionEntry<C>> - : Promise<CollectionEntry<C> | undefined>; - export function getEntry< - C extends keyof DataEntryMap, - E extends keyof DataEntryMap[C] | (string & {}), - >( - collection: C, - id: E, - ): E extends keyof DataEntryMap[C] - ? string extends keyof DataEntryMap[C] - ? Promise<DataEntryMap[C][E]> | undefined - : Promise<DataEntryMap[C][E]> - : Promise<CollectionEntry<C> | undefined>; - - /** Resolve an array of entry references from the same collection */ - export function getEntries<C extends keyof ContentEntryMap>( - entries: { - collection: C; - slug: ValidContentEntrySlug<C>; - }[], - ): Promise<CollectionEntry<C>[]>; - export function getEntries<C extends keyof DataEntryMap>( - entries: { - collection: C; - id: keyof DataEntryMap[C]; - }[], - ): Promise<CollectionEntry<C>[]>; - - export function render<C extends keyof AnyEntryMap>( - entry: AnyEntryMap[C][string], - ): Promise<RenderResult>; - - export function reference<C extends keyof AnyEntryMap>( - collection: C, - ): import('astro/zod').ZodEffects< - import('astro/zod').ZodString, - C extends keyof ContentEntryMap - ? { - collection: C; - slug: ValidContentEntrySlug<C>; - } - : { - collection: C; - id: keyof DataEntryMap[C]; - } - >; - // Allow generic `string` to avoid excessive type errors in the config - // if `dev` is not running to update as you edit. - // Invalid collection names will be caught at build time. - export function reference<C extends string>( - collection: C, - ): import('astro/zod').ZodEffects<import('astro/zod').ZodString, never>; - - type ReturnTypeOrOriginal<T> = T extends (...args: any[]) => infer R ? R : T; - type InferEntrySchema<C extends keyof AnyEntryMap> = import('astro/zod').infer< - ReturnTypeOrOriginal<Required<ContentConfig['collections'][C]>['schema']> - >; - - type ContentEntryMap = { - - }; - - type DataEntryMap = { - "HPsections": Record<string, { - id: string; - body?: string; - collection: "HPsections"; - data: InferEntrySchema<"HPsections">; - rendered?: RenderedContent; - filePath?: string; -}>; -"articles": Record<string, { - id: string; - body?: string; - collection: "articles"; - data: InferEntrySchema<"articles">; - rendered?: RenderedContent; - filePath?: string; -}>; -"fragments": Record<string, { - id: string; - body?: string; - collection: "fragments"; - data: InferEntrySchema<"fragments">; - rendered?: RenderedContent; - filePath?: string; -}>; -"references": Record<string, { - id: string; - body?: string; - collection: "references"; - data: InferEntrySchema<"references">; - rendered?: RenderedContent; - filePath?: string; -}>; -"veille": Record<string, { - id: string; - body?: string; - collection: "veille"; - data: InferEntrySchema<"veille">; - rendered?: RenderedContent; - filePath?: string; -}>; - - }; - - type AnyEntryMap = ContentEntryMap & DataEntryMap; - - export type ContentConfig = typeof import("../src/content.config.js"); -} diff --git a/.astro/data-store.json b/.astro/data-store.json index 4c7de64..e0d231f 100644 --- a/.astro/data-store.json +++ b/.astro/data-store.json @@ -1 +1 @@ -[["Map",1,2,9,10,61,62,427,428,888,889,903,904],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.1.1","content-config-digest","8021b3469f132349","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"site\":\"https://www.nardu.in\",\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[\"assets.nardu.in\"],\"remotePatterns\":[{\"protocol\":\"https\"}]},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":\"shiki\",\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"one-dark-pro\",\"themes\":{},\"wrap\":false,\"transformers\":[{\"name\":\"@shikijs/transformers:meta-highlight\"}]},\"remarkPlugins\":[],\"rehypePlugins\":[],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"i18n\":{\"defaultLocale\":\"fr\",\"locales\":[\"fr\",\"en\"],\"routing\":{\"prefixDefaultLocale\":false,\"redirectToDefaultLocale\":true,\"fallbackType\":\"redirect\"}},\"security\":{\"checkOrigin\":true},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"responsiveImages\":false},\"legacy\":{\"collections\":false}}","references",["Map",11,12,25,26,39,40,50,51],"3w",{"id":11,"data":13,"filePath":21,"digest":22,"rendered":23},{"title":11,"subtitle":14,"url":15,"lang":16,"slug":11,"tags":17,"createdAt":20},"J'ai fait de la doc!","https://3-w.fr","fr",[18,19],"Front-end","documentation",["Date","2022-10-19T18:02:00.000Z"],"src/content/references/3w.md","0d3d94c8af754e1b",{"html":24},"","natureo",{"id":25,"data":27,"filePath":36,"digest":37,"rendered":38},{"title":28,"subtitle":29,"url":30,"lang":16,"slug":25,"tags":31,"createdAt":35},"Nature en Occitanie","La sobriété au naturel.","https://www.natureo.org/",[18,32,33,34],"accessibilité","éco-conception","CMS",["Date","2023-04-19T18:02:00.000Z"],"src/content/references/natureo.md","6a7169b855b57024",{"html":24},"parole-expression",{"id":39,"data":41,"filePath":47,"digest":48,"rendered":49},{"title":42,"subtitle":43,"url":44,"lang":16,"slug":39,"tags":45,"createdAt":46},"Parole Expression","Un nouveau site pour l'association.","https://www.paroleexpression.fr/",[18,33,34],["Date","2022-04-19T17:11:00.000Z"],"src/content/references/parole-expression.md","ec95a408f8c3e99c",{"html":24},"rose-primaire",{"id":50,"data":52,"filePath":58,"digest":59,"rendered":60},{"title":53,"subtitle":54,"url":55,"lang":16,"slug":50,"tags":56,"createdAt":57},"Rose Primaire","Une agence comme on l'aime.","https://roseprimaire.com/",[18,32,33,34],["Date","2023-04-19T17:11:00.000Z"],"src/content/references/rose-primaire.md","a0133200cf1bee58",{"html":24},"articles",["Map",63,64,76,77,89,90,102,103,113,114,124,125,134,135,171,172,205,206,224,225,239,240,269,270,298,299,315,316,366,367,410,411],"en-after-effects-expressions",{"id":63,"data":65,"body":73,"filePath":74,"digest":75,"deferredRender":72},{"title":66,"subtitle":67,"lang":68,"tags":69,"type":61,"slug":63,"createdAt":71,"code":72},"After Effects Expressions","Animation on steroïds.","en",[70],"Design",["Date","2019-04-24T09:00:00.000Z"],true,"import AstroImage from '../../../components/AstroImage.astro'\n\n## An ever lasting battle\n\nThere is very little documentation and the existing one is hard to find or very old. Very often I just don't have the time to dive into expression learning while animating even though it could help the entire project on the long term.\nSo the last time I had to do a complex animation, **I took the damn time!**\n\n## The begining of the end (of keyframes).\n\nEveryone uses expressions whether they know it or not. Most of the time it's a rather transparent process for the animator. For example: when parenting a property to another one, After Effects creates an expression for us.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/basic_expression_d81b12f1ac.jpeg'\n\twidth='728'\n\theight='80'\n\talt='Parenting the position of the form to a null creates an expression.'\n/>\n\nOver the last updates, Adobe has made an effort to make expressions more accessible to everyone. For example, the expression box is now resembling a code editor thanks to code-coloring and auto-completion features. After Effects expression feel like JavaScript with custom functions.\n\nThose custom functions can be called through a menu once you enabled the expressions on a property. It offers organized shortcut and proper syntax to all of AE native functions and a bunch of JavaScript standard ones.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/shortcut_39cc19d383.jpeg'\n\twidth='728'\n\theight='322'\n\talt='Alt + Click the stopwatch to access the shortcuts.'\n/>\n\n## So I need to learn javascript to do motion design now?\n\n### Why bother?\n\nI know that most animators don't have any kind of development background. However, if Adobe thought it best to let us use expressions, I think we ought to, at least, try.\n\n> A lot of incredible professionals like [Mt Mograph](https://www.mtmograph.com/) and [Video Copilot](https://videocopilot.net/) use expressions.\n\nLike every optimization process, building an expressions knowledge takes time. However, like all optimization process, you will benefit from it afterwards.\n\n### Where to learn\n\nI've gathered a list of my favourite learning grounds. Plenty more exist, **go get'em!**\n\n- [Adobe official expression starter guide (FR)](https://helpx.adobe.com/fr/after-effects/using/expression-language-reference.html)\n- [Adobe official expression basic (EN)](https://helpx.adobe.com/after-effects/using/expression-basics.html)\n- [Adobe forums for expressions](https://community.adobe.com/t5/after-effects/bd-p/after-effects?page=1&sort=latest_replies&filter=all&topics=label-expressions)\n- [Creative Cow expressions forums](https://creativecow.net/forums/forum/adobe-after-effects-expressions/)\n- [Youtube channel about expressions](https://www.youtube.com/playlist?list=PLvr5U5ZSt6IzHyvSL9fo0M9NRPsTvra31)\n- [All expressions explained](http://aescript.jecool.net/reference/)\n- [All expressions explained again](http://expressions.aenhancers.com/index.html)\n- [Nice examples of basic expressions](https://www.schoolofmotion.com/tutorials/amazing-expressions-in-after-effects)\n\n## Real world example\n\n### Number counter\n\nLet's say you need to animate a rather simple counter from 0% to 100%.\n\n- Start by creating a text layer. Define your typographic choices, colours, etc.\n- On the effect menu add expression options > slider control\n- Alt + Click the Source text property\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/alt-counter.mp4' type='video/mp4' />\n\u003C/video>\n\n- Parent the source text to the slider control through the pickwhip.\n\n\u003Cvideo width='462' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/pickwhip.mp4' type='video/mp4' />\n\u003C/video>\n\nYou should get something like this in the expressions panel:\n\n```javascript\neffect(\"Slider Control\")(\"Slider\")​\n```\n\n- Set two keyframes on the slider from 0 to 100. The text should update accordingly.\n- By default, After Effects does not round numbers. In the expression panel, wrap your expression with the `Math.round()` function.\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/round.mp4' type='video/mp4' />\n\u003C/video>\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\"))​\n```\n\nGreat! We have a working counter. But we wanted a percentage counter. We could add a % glyph in another text layer but let's not.\n\nStill in the expression panel, we're going to add a string containing the % glyph, using basic JavaScript concatenation: `+ '%'`\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\")) + '%'​\n```\n\n\u003Cvideo width='538' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/percent.mp4' type='video/mp4' />\n\u003C/video>\n\n**And there we go!** A fully functioning and customizable counter using a slider controller and expressions.","src/content/articles/en/after-effects-expressions.mdx","3b6f88fbf35af1a4","en-sci-hub-unblock",{"id":76,"data":78,"body":86,"filePath":87,"digest":88,"deferredRender":72},{"title":79,"subtitle":80,"lang":68,"tags":81,"type":61,"slug":76,"createdAt":84,"updatedAt":85},"Access blocked Sci-hub","The science of sharing.",[82,83],"Internet","Science",["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nThe current sci-hub address is: \u003Ca href=\"https://sci-hub.se\" rel=\"noreferer noopener\">sci-hub.se\u003C/a>\n\n## What is this about?\n\nNot being a researcher myself, here’s an [extremely well done explanatory video](https://youtu.be/rcgxY__YXEc) on the subject of scientific publication (french audio with auto subtitle).\n\n> “This is outrageous!”​\n\nI noticed that my ISP was indeed blocking access. I have not yet been able to check for the other suppliers, but I imagine that they have all complied with the court decision.\nThe restriction in place is quite basic. This is a “DNS” block. A DNS is a server that is used to link a domain name: **www.sci-hub.tw** to an IP address: **186.2.163.90**\nIt is, in a way, the Internet phone book. Without the address, it is impossible to contact the domain. What ISPs have certainly done: block requests to the [sci-hub.se.](http://sci-hub.se/) domain name. As a result, no IP address is returned and the site is not accessible.\n\n## How to bypass this?\n\n- Either by using a VPN\n- Either by modifying the DNS servers of your computers/Internet box\n\nI would recommend the second solution because it allows you to protect yourself against future blockages/filtering/censorship from your ISP and does not require any financial compensation.\nI will focus on change from a computer because it will be effective wherever you are and not only from your home.\n\n### MacOs\n\nGo to:\n\n1. System Preferences\n1. Network\n1. (wi-fi and/or ethernet)\n1. Advanced\n1. DNS\n\nFrom there, you can add DNS servers by clicking the + icon. Click ok and apply the new settings. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS network and DNS settings'\n/>\n\n### Windows (10)\n\nGo to:\n\n1. System Settings\n1. Network & Internet\n1. Change adapter options\n1. Right click your adapter then “properties”\n1. Select “internet protocol version 4” (and/or 6)\n1. Properties\n1. Use the following DNS server addresses\n\nFrom there, you can add DNS servers. Click save. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Windows system settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows network settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows network connections settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows network adapter settings'\n/>\n\n## Which DNS?\n\nThere are many DNS servers available. The best known are Google, Cloudflare and OpenDNS. If you really want to use Google’s, I’ll let you look up their address. Here are my recommendations in order of preference.\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMy favorite since it is a [french association](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net)\n\nQuand9 is a non-profit foundation offering free public DNS servers. Their classic servers offer filtering of identified malicious domains. They do not collect data and are \u003Cabbr title=\"General Data Protection Regulation\">GDPR\u003C/abbr>-compliant.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## That's it.\n\nBy changing these settings, you are free from your ISPs and their content filtering rules.\n\nFor the moment, these restrictions are almost symbolic because if Sci-hub were to change its url, the block would no longer work. But the publishers’ victory in court shows that they have not had their last word. We are therefore not immune to a wider and stronger block in the future.\n\nIf you want to learn more about the struggle of the people who fight to ensure that research is not a paid commodity, I recommend [this documentary](https://youtu.be/y_CQATGOX2w) on Aaron Shwartz. Or [this article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) about the founder of Sci-hub.\n\nIn the meantime, good readings to all of you. We stand with you!","src/content/articles/en/sci-hub-blocage.mdx","8959506d941cdcc5","en-the-day-I-jamd",{"id":89,"data":91,"body":99,"filePath":100,"digest":101,"deferredRender":72},{"title":92,"subtitle":93,"lang":68,"tags":94,"type":61,"slug":89,"createdAt":97,"updatedAt":98},"The day I Jam’d","A story of unusual tools and fun gambles.",[95,96],"Dev","Jamstack",["Date","2020-10-08T09:00:00.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## The not so easy choice\n\nWhen I was still using Wordpress for my personal website, I thought it would be nice to try [OpenLiteSpeed](https://openlitespeed.org) webserver. Being a designer, I always like to have a graphical interface and I heard OLS had very nice caching and overall performances.\n\n## FIGHT!\n\nA few years later, I learned about Jamstack and its incredible potential. Not being impulsive at all, I chose to entirely remake my website with tools like [11ty](https://www.11ty.dev/) and [Strapi](https://strapi.io/).\n\nI remember Strapi still being in alpha/beta and colleagues telling me it was a risky gamble, especially since I was pretty new to the node.js world.\n\n> Open source and french? Sign me up!\n\nSo I started recreating my website identically with 11ty and Strapi. Same hosting on a Digital Ocean droplet, same webserver, same content. I had done a fair amout of performance optimizations on my wordpress install so I was eager to compare the results with the new static version.\n\nBoy did they exceed my expectations! With almost no optimization on the static side, I got the following results.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 53/100 on Wordpress.'\n/>\n\nDespite a lot of efforts I could not do better. I’m no expert in caching, do not use CDN and relied on plugins to achieve a lot of stuff (php not being my strongest skill 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 97/100 on jamstack.'\n/>\n\nAlmost **zero** special configuration (I was too anxious to test) and I reached an awesome score. I know lighthouse scores are not everything but hey, **53 vs 97**… I’ll take it!\n\n## Now kiss 🥰\n\nBoth of these approaches have their benefits and drawbacks. As a freelance, my clients often prefer or ask for Wordpress because of its reputation. I always present a Jamstack alternative when possible but it’s still scary to most compared to Wordpress. I feel however that it’s going to be easier to use Jamstack with time.\n\n## I did it again…\n\nHere we are now, a quarantine and a few months later and this website is running with… [Nuxt.js](https://nuxtjs.org/). I know, I’m sorry, I couldn’t resist the latest [nuxt content](https://content.nuxtjs.org/) functionnality.\n\nSo I re-did everything again… and let me just say: **wow**, what an experience!\nI **love** developing with Nuxt. Using nuxt content allowed me to focus on design and, well, content.\nNo more Apollo client and graphQL query, only markdown and a few promises.\n\nDon’t get me wrong, I really like working with Strapi and its graphQL capabilities but for the purpose of this website, nuxt content does it (extremely well).\n\nI’m still using Strapi as a way to upload, store and manage images, videos, gifs, etc. It might be too much for this use case but I like to know that I can still go back to it if I want to! Also, I spent quite a bit of time setting it up with OpenLiteSpeed and I’m still too attached to this accomplishment to let it go.\n\n## In the end\n\nWordpress, Jamstack, vanilla everything… Does it really matter? For me, the dev experience was far more enjoyable working with 11ty, nuxt.js and strapi than with Wordpress.\n\nOn the performance and accessibility side, it also seems to be the better/smarter choice. It might not be everytime! ¯\\\\\\_(ツ)\\_/¯\n\nCan’t wait to learn [astro](https://astro.build/) and start from scratch again!","src/content/articles/en/the-day-I-jamd.mdx","60b77e216e02f618","en-video-compression",{"id":102,"data":104,"body":110,"filePath":111,"digest":112,"deferredRender":72},{"title":105,"subtitle":106,"lang":68,"tags":107,"type":61,"slug":102,"createdAt":108,"updatedAt":109},"Video compression","Encode like you mean it.",[70],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Let's play.\n\nVideos are everywhere. **EVERYWHERE!** But videos can and will be huge when 4k becomes an internet standard. Currently, 1920x1080 is king and we usually have no problem hosting or playing this resolution.\n\n## Because we can doesn't mean we should.\n\nRight now, the (good) trend of web performance is on the rise. Everyone wants a blazing fast loading website, which might not be possible if we send requests to 100mb (or even more) videos.\n\nWith a good connection, users will not see the difference. But if we go down that path, nor will they with a 300mb one. So the goal is to make every asset as small as possible. It's already the case with images. But it's simpler and faster than video encoding.\n\n## Small size, best quality.\n\nLet's say we exported​ a 1920x1080 video from Premiere Pro with these basic settings:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-premiere-1.jpeg'\n\twidth='673'\n\theight='800'\n/>\n\nIt's gorgeous, it's Full HD, it's 1:30 minute of excellent editing but it's 50mb… What a shame.\n\n> We can already bring down the size from Premiere or Media Encoder by selecting CBR instead of VBR and using a low bitrate (like 2 or 3).\n\nLet's now use [Handbrake!](https://handbrake.fr/) It's free, open source and multi platform. You can also read this great article from [Ueno](https://loremipsum.ueno.co/dear-ueno-how-do-you-compress-videos-6657ebd9dd28?gi=930afecec398) on video encoding.\n\n**Please please PLEASE. Never export videos from within After Effects.**\n\n## Handbrake\n\n### Summary screen\n\nWhile it's not as nice as Premiere Pro, it has way more exporting capabilities. Follow these steps to use good standard settings:\n\n1. Open your source video\n1. Select a preset corresponding to your future usage like Fast 1080p30\n1. Check Web Optimized\n1. Keep MPEG-4 as the format\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-1.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Video screen\n\n1. Keep H.264 (x264) or use H.264 nvidia nvenc if you can (crazy fast encoding by nvidia)\n1. Choose Constant Quality and try a value between 20 and 30​ (higher = smaller size but lower quality)\n1. Choose Peak Framerate. If you don't know the framerate, keep the default setting\n1. Choose the type of video you are encoding (film, animation…)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-2.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Audio screen\n\nIf you don't have audio, be sure to set the audio channel to none.\nIf you have an audio channel, these settings are great and will not influence the size much​:\n\n1. Codec AAC\n1. Samplerate 44.1\n1. Bitrate 192 to 256 (your choice)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-3.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Export!\n\nI used a RF of 25 for this example and no audio.\n\n1. My Premiere Pro video was 50,6mb\n1. My Handbrake video is 5,5mb​\n\n> What a save!\n\n​I ended up dividing the original size by 10. Which is cool.\nI tried with a RF of 30. The video was still pretty good and only 3,3mb.\n\n## Exporting for the web\n\nNow that we know how to properly compress videos, let's go further. Say we have a website with a lot of videos on the same page. We still want to load the content as fast as possible. So our videos need to be as small as possible. We won't do better than previously seen using mp4/H.264. However, we can use **webm/VP9.**\nWebm is an html video format and VP9 is its latest codec.\n\nUsing Handbrake and webm/VP9, we can achieve really great compression without losing too much quality (or none at all depending on the settings). I was able to divide by 4 the size of a video using these presets:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-4.jpg'\n\twidth='728'\n\theight='313'\n\talt=''\n/>\n\nThe only down side is that it takes some time to encode. It will depend on the video length and your computing power.\n\nI tried various settings but I read [here](https://trac.ffmpeg.org/wiki/Encode/VP9) that VP9 is supposed to be used with two-pass encoding. You then have to find the right bitrate (here 1000) for your situation.","src/content/articles/en/video-compression.mdx","5bb9f69df6c651d1","sci-hub-blocage",{"id":113,"data":115,"body":121,"filePath":122,"digest":123,"deferredRender":72},{"title":116,"subtitle":117,"lang":16,"tags":118,"type":61,"slug":113,"createdAt":119,"updatedAt":120},"Sci-hub bloqué, comment contourner","La science du partage.",[82,83],["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nL'adresse actuelle de sci-hub est : [sci-hub.se](https://sci-hub.se)\n\n## Résumé de la situation\n\nN’étant pas moi-même directement chercheur, je vous laisse regarder [cette vidéo](https://youtu.be/rcgxY__YXEc) explicative extrêmement bien faite sur le sujet de la publication scientifique.\n\n> “ Mais c’est scandaleux ! ”​\n\nJ’ai constaté que le blocage était actif chez SFR. Je n’ai pas encore pu vérifier pour les autres fournisseurs mais j’imagine qu’ils se sont tous conformés à la décision de justice.\nLe blocage mis en place est assez basique. Il s’agit d’un blocage “ DNS ”.\n\nUn DNS est un serveur qui sert à faire le lien entre un nom de domaine : **sci-hub.tw** et une adresse IP : **186.2.163.90**.\n\nC’est en quelque sorte l’annuaire d’internet. Sans l’adresse, impossible de contacter le domaine. Ce que les FAI ont certainement fait : bloquer les requêtes au nom de domaine [sci-hub.se.](http://sci-hub.se/) Ainsi, aucune adresse IP n’est renvoyée et le site n’est pas accessible.\n\n## Comment contourner ce blocage ?\n\n- Soit en utilisant un VPN\n- Soit en modifiant les serveurs DNS de vos ordinateurs/box internet\n\nJe recommande la deuxième solution car elle permet de se prémunir contre de futurs blocages/filtrages/censures de la part de votre FAI et ne nécessite pas de contrepartie financière.\nJe vais me focaliser sur le changement depuis un ordinateur car il sera effectif où que vous soyez.\n\n### Sur MacOs\n\nOuvrez :\n\n1. Préférences système\n1. Réseau\n1. Ethernet et/ou Wi-fi\n1. Avancé\n1. DNS\n1. Serveurs DNS\n\nDe là, vous pouvez ajouter des serveurs DNS en cliquant sur l'icône +. Cliquez sur ok et appliquez les nouveaux paramètres. Vous devrez peut-être redémarrer votre ordinateur pour que les changements fonctionnent.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS réglages réseau et DNS'\n/>\n\n### Sur Windows (ici 10)\n\nOuvrez :\n\n1. Réglages\n1. Réseau et internet\n1. Modifier les options de l'adaptateur\n1. Clic droit sur les propriétés de votre interface réseau\n1. Selectionnez « protocole Internet version 4 » (et/ou 6)\n1. Propriétés\n1. Utiliser l’adresse de serveur DNS suivante\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Réglages windows'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows réglages réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows régalges connections réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows options adaptateur réseau'\n/>\n\n## Quels serveurs DNS utiliser ?\n\nIl y a de nombreux serveurs DNS accessibles. Les plus connus étant ceux de Google, Cloudflare et OpenDNS. Si vous tenez vraiment à utiliser ceux de Google, je vous laisse chercher leur adresse. Voici mes recommandations par ordre de préférence.\n\nPlusieurs fournisseurs :\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMes favoris puisqu’il s’agit d’une [association française.](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net/fr)\n\nQuand9 est une fondation à but non lucratif proposant des serveurs DNS publics et gratuits. Leurs serveur classiques offrent un filtrage de domaines malveillants identifiés. Ils ne collectent pas de données et sont conforment au \u003Cabbr title=\"Règlement général sur la protection des données\">RGPD\u003C/abbr>.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## C'est tout.\n\nEn modifiant ces réglages, vous vous affranchissez de vos fournisseurs d’accès et de leurs règles de filtrage du contenu.\n\nPour l’instant, ces blocages sont presque symboliques car si Sci-hub venait à changer d’url, le blocage ne fonctionnerait plus. Mais la victoire des éditeurs au tribunal montre qu’ils n’ont pas dit leur dernier mot. Nous ne sommes donc pas à l’abri d’un futur blocage plus large et plus dur à contrer.\n\nSi vous voulez en apprendre plus sur le combat de ces gens qui se battent pour que la recherche ne soit pas une marchandise, je vous conseille [ce documentaire](https://youtu.be/y_CQATGOX2w) sur Aaron Shwartz. Ou plus simplement [cet article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) sur la fondatrice de Sci-hub.\n\nEn attendant, bonnes lectures à tou·te·s. On est avec vous !","src/content/articles/fr/sci-hub-blocage.mdx","6438fdc02b91ec59","the-day-I-jamd",{"id":124,"data":126,"body":131,"filePath":132,"digest":133,"deferredRender":72},{"title":92,"subtitle":127,"lang":16,"tags":128,"type":61,"slug":124,"createdAt":129,"updatedAt":130},"Des paris, des outils et du fun.",[95,96],["Date","2020-10-08T07:47:36.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## La solution de non facilité\n\nLorsque j’utilisais encore Wordpress pour mon site web personnel, j’ai voulu essayer le serveur web \u003Ca href=\"https://openlitespeed.org\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">OpenLiteSpeed (en anglais)\u003C/a>. En tant que designer, j’ai toujours aimé avoir une interface graphique et j’avais entendu dire qu’OLS jouissait de bonnes performances en général et de cache en particulier.\n\n## Battez-vous!\n\nQuelques années plus tard, je découvrais l’univers Jamstack et son incroyable potentiel. N’étant pas du tout impulsif, j’ai choisi de refaire entièrement mon site web avec des outils comme \u003Ca href=\"https://www.11ty.dev/\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">11ty (en anglais)\u003C/a> et \u003Ca href=\"https://strapi.io/\" hreflang=\"en\">Strapi (en anglais)\u003C/a>.\n\nJe me souviens que Strapi était encore en alpha/beta et que certains collègues me disaient que c’était un pari risqué, surtout que je découvrais à peine le monde de node.js.\n\n> Open source et français ? Je dis banco !\n\nJ’ai donc commencé à recréer mon site web à l’identique avec 11ty et Strapi. Même hébergement chez Digital Ocean, même serveur web, même contenu. J’avais fait pas mal d’optimisations de performances sur mon installation wordpress, j’étais donc impatient de comparer les résultats avec la nouvelle version statique.\n\nJ’en suis resté pantois ! Quasiment sans optimisation du côté statique, j’ai obtenu les résultats ci-dessous.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 53/100 sur Wordpress.'\n/>\n\nMalgré beaucoup d’efforts, je n’ai pas pu faire mieux. Je ne suis pas un expert en cache, je n’utilise pas de CDN et je me suis appuyé sur des plugins pour réaliser beaucoup de choses (php n’étant pas ma spécialité 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 97/100 en Jamstack.'\n/>\n\nPresque **zéro** configuration spéciale (j’étais trop impatient de tester) et j’ai atteint un score impressionnant. Je sais que les scores lighthouse ne font pas tout mais **53 contre 97**… Ça me va !\n\n## Embrassez-vous 🥰\n\nCes deux approches ont leurs avantages et leurs inconvénients. En tant que freelance, mes clients préfèrent ou demandent souvent Wordpress en raison de sa réputation. Je présente toujours une alternative Jamstack lorsque c’est possible, mais cela reste effrayant la plupart du temps par rapport à Wordpress. Je pense cependant qu’il sera plus facile d’utiliser la Jamstack avec le temps.\n\n## Encore et encore…\n\nNous voici maintenant une quarantaine et quelques mois plus tard et ce site fonctionne avec… [Nuxt.js](https://fr.nuxtjs.org/). Je sais, je suis désolé, je n’ai pas pu résister à la dernière fonctionnalité [\u003Cspan lang=\"en\">nuxt content\u003C/span>](https://content.nuxtjs.org/fr) de Nuxt.\n\nDu coup j’ai tout refait… et laissez-moi vous dire : **wow**, quelle expérience !\nJ’adore développer avec Nuxt. L’utilisation de \u003Cspan lang=\"en\">nuxt content\u003C/span> m’a permis de me concentrer sur le design et, évidemment, sur le contenu.\nPlus de client Apollo ni de requête graphQL, seulement du \u003Cspan lang=\"en\">markdown\u003C/span> et quelques promesses.\n\nAttention, j’aime beaucoup travailler avec Strapi et son interface graphQL mais pour les besoins de ce site, \u003Cspan lang=\"en\">nuxt content\u003C/span> fait le \u003Cspan lang=\"en\">job\u003C/span> (extrêmement bien).\n\nJ’utilise toujours Strapi pour téléverser, stocker et gérer les images, vidéos, gifs, etc. C’est peut-être trop pour ce que j’en fait mais j’aime savoir que je peux toujours y revenir si j’ai envie ! De plus, j’ai passé pas mal de temps à le mettre en place avec \u003Cspan lang=\"en\">OpenLiteSpeed\u003C/span> et je suis encore trop attaché à cette réussite pour la laisser tomber.\n\n## Et en fait à la fin\n\nWordpress, Jamstack, fait main… Est-ce vraiment important ? Pour moi, l’expérience de développement a été bien plus agréable en travaillant avec 11ty, nuxt.js et strapi qu’avec Wordpress.\n\nDu point de vue de la performance et de l’accessibilité, il semble également que ce soit le choix le plus judicieux. Ce n’est peut-être pas le cas à chaque fois ! ¯\\\\\\_(ツ)\\_/¯\n\nJ’ai hâte d’apprendre \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> et de tout recommencer à zéro !","src/content/articles/fr/the-day-I-jamd.mdx","57bd292bda8b6632","en-2022",{"id":134,"data":136,"body":142,"filePath":143,"digest":144,"rendered":145},{"title":137,"subtitle":138,"lang":68,"tags":139,"type":61,"slug":134,"createdAt":141},"Nico v2.0","2022 update of many things.",[140],"Freelance",["Date","2022-06-08T14:24:06.000Z"],"After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\n\n## Services\n\n### No more print\n\nEven though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for \"classic\" graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\n\n### Internet all the way\n\nOn the other hand, I spend my time **doing web stuff.** A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer **more specific web offerings,** in which I have specialised.\n\nThus, **accessibility** and **eco-design** become integrated expertises in my practice. They are no longer options on a quote but **my core business.**\n\n## The website\n\nI have reworked my website, especially the homepage and its content, to better reflect these decisions.\n\nI have also made several behavioural changes:\n\n- external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven't found a good reason to continue using this behaviour;\n- I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu);\n- \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\n- I only trigger animations if the user has not asked the system to reduce the amount motion [(reference)](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).\n\nI am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello [astro](https://astro.build/) 👀).\n\n## Le Nico\n\nOn a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\n\nI have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.","src/content/articles/en/2022.md","7b98592763cb0929",{"html":146,"metadata":147},"\u003Cp>After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\u003C/p>\n\u003Ch2 id=\"services\">Services\u003C/h2>\n\u003Ch3 id=\"no-more-print\">No more print\u003C/h3>\n\u003Cp>Even though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for “classic” graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\u003C/p>\n\u003Ch3 id=\"internet-all-the-way\">Internet all the way\u003C/h3>\n\u003Cp>On the other hand, I spend my time \u003Cstrong>doing web stuff.\u003C/strong> A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer \u003Cstrong>more specific web offerings,\u003C/strong> in which I have specialised.\u003C/p>\n\u003Cp>Thus, \u003Cstrong>accessibility\u003C/strong> and \u003Cstrong>eco-design\u003C/strong> become integrated expertises in my practice. They are no longer options on a quote but \u003Cstrong>my core business.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Cp>I have reworked my website, especially the homepage and its content, to better reflect these decisions.\u003C/p>\n\u003Cp>I have also made several behavioural changes:\u003C/p>\n\u003Cul>\n\u003Cli>external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven’t found a good reason to continue using this behaviour;\u003C/li>\n\u003Cli>I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a>;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\u003C/li>\n\u003Cli>I only trigger animations if the user has not asked the system to reduce the amount motion \u003Ca href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion\">(reference)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>I am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello \u003Ca href=\"https://astro.build/\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>On a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\u003C/p>\n\u003Cp>I have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.\u003C/p>",{"headings":148,"imagePaths":166,"frontmatter":167},[149,153,157,160,163],{"depth":150,"slug":151,"text":152},2,"services","Services",{"depth":154,"slug":155,"text":156},3,"no-more-print","No more print",{"depth":154,"slug":158,"text":159},"internet-all-the-way","Internet all the way",{"depth":150,"slug":161,"text":162},"the-website","The website",{"depth":150,"slug":164,"text":165},"le-nico","Le Nico",[],{"title":137,"subtitle":138,"lang":68,"slug":134,"excerpt":168,"tags":169,"type":61,"createdAt":170},"Changes in my services, the website and myself.",[140],"2022-06-08T14:24:06.000Z","en-2023",{"id":171,"data":173,"body":179,"filePath":180,"digest":181,"rendered":182},{"title":174,"subtitle":175,"lang":68,"tags":176,"type":61,"slug":171,"createdAt":177,"updatedAt":178},"Nico v2.5","Update 2023.",[140],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"This article will be updated when I have something new to share during the year 2023.\n\n## The website\n\n### Technologies\n\nOops... I (re)did it again.\n\nI have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself [in 2022 !](/en/articles/2022/#the-website)\n\nI will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\n\nMy \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I'm back to a solid **95/100** without any particular optimization. With some small efforts, I've reached the good old 100/100.\n\nI then did a work of modernization of the codebase. Hello CSS variables and goodbye `media queries`. In no particular order, here are some of the improvements I made:\n\n- `flexbox` and `grid` to adapt the layout to different screen sizes;\n- CSS variables for colors, font sizes and margins;\n- some `container queries`, just to try;\n- logical CSS properties (`inline` and `block` instead of `width` and `height` for example).\n\nI took this opportunity to publish [the source code](https://git.nardu.in/nardu.in/website-astro) on my git repository.\n\n**Update #1:** I've added [an RSS feed](/en/rss.xml) as I find myself using it more and more on other websites.\n\n### Analytics\n\nI removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\n\nIt's nice to see that your site is consulted, but if there is no other purpose behind it, it's an extra resource loaded for nothing by visitors. Maybe I'll reactivate the tracking when I have a use for it (other than flattering my ego).\n\nPrevious visit reports can be found at [this link.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Content\n\n- I've added a [work](/en/work/) page to list some of my projects.\n- I've also added [a page](/en/veille/) where I list some interesting things from around the web.\n\n## Additional projects\n\nI'm still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at [3-w.fr](https://3-w.fr/) (an address I am very proud of).\n\nI have to update it more regularly but I hope that the platform will help students progress!\n\n**More to come soon!**","src/content/articles/en/2023.md","489c650e66cced63",{"html":183,"metadata":184},"\u003Cp>This article will be updated when I have something new to share during the year 2023.\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oops… I (re)did it again.\u003C/p>\n\u003Cp>I have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself \u003Ca href=\"/en/articles/2022/#the-website\">in 2022 !\u003C/a>\u003C/p>\n\u003Cp>I will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\u003C/p>\n\u003Cp>My \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I’m back to a solid \u003Cstrong>95/100\u003C/strong> without any particular optimization. With some small efforts, I’ve reached the good old 100/100.\u003C/p>\n\u003Cp>I then did a work of modernization of the codebase. Hello CSS variables and goodbye \u003Ccode>media queries\u003C/code>. In no particular order, here are some of the improvements I made:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> and \u003Ccode>grid\u003C/code> to adapt the layout to different screen sizes;\u003C/li>\n\u003Cli>CSS variables for colors, font sizes and margins;\u003C/li>\n\u003Cli>some \u003Ccode>container queries\u003C/code>, just to try;\u003C/li>\n\u003Cli>logical CSS properties (\u003Ccode>inline\u003C/code> and \u003Ccode>block\u003C/code> instead of \u003Ccode>width\u003C/code> and \u003Ccode>height\u003C/code> for example).\u003C/li>\n\u003C/ul>\n\u003Cp>I took this opportunity to publish \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">the source code\u003C/a> on my git repository.\u003C/p>\n\u003Cp>\u003Cstrong>Update #1:\u003C/strong> I’ve added \u003Ca href=\"/en/rss.xml\">an RSS feed\u003C/a> as I find myself using it more and more on other websites.\u003C/p>\n\u003Ch3 id=\"analytics\">Analytics\u003C/h3>\n\u003Cp>I removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\u003C/p>\n\u003Cp>It’s nice to see that your site is consulted, but if there is no other purpose behind it, it’s an extra resource loaded for nothing by visitors. Maybe I’ll reactivate the tracking when I have a use for it (other than flattering my ego).\u003C/p>\n\u003Cp>Previous visit reports can be found at \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">this link.\u003C/a>\u003C/p>\n\u003Ch3 id=\"content\">Content\u003C/h3>\n\u003Cul>\n\u003Cli>I’ve added a \u003Ca href=\"/en/work/\">work\u003C/a> page to list some of my projects.\u003C/li>\n\u003Cli>I’ve also added \u003Ca href=\"/en/veille/\">a page\u003C/a> where I list some interesting things from around the web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"additional-projects\">Additional projects\u003C/h2>\n\u003Cp>I’m still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (an address I am very proud of).\u003C/p>\n\u003Cp>I have to update it more regularly but I hope that the platform will help students progress!\u003C/p>\n\u003Cp>\u003Cstrong>More to come soon!\u003C/strong>\u003C/p>",{"headings":185,"imagePaths":199,"frontmatter":200},[186,187,190,193,196],{"depth":150,"slug":161,"text":162},{"depth":154,"slug":188,"text":189},"technologies","Technologies",{"depth":154,"slug":191,"text":192},"analytics","Analytics",{"depth":154,"slug":194,"text":195},"content","Content",{"depth":150,"slug":197,"text":198},"additional-projects","Additional projects",[],{"title":174,"subtitle":175,"lang":68,"slug":171,"excerpt":201,"tags":202,"type":61,"createdAt":203,"updatedAt":204},"New changes.",[140],"2023-02-03T17:41:00.000Z","2023-05-17T17:41:00.000Z","en-faq",{"id":205,"data":207,"body":212,"filePath":213,"digest":214,"rendered":215},{"title":208,"subtitle":209,"lang":68,"tags":210,"type":61,"slug":205,"createdAt":211,"draft":72},"Accessibility and sobriety","Translation in progress, stay tuned ;)",[140],["Date","2022-06-22T15:34:45.000Z"],"[Go back to available articles](/en/articles)","src/content/articles/en/faq.md","82d516449896f6ca",{"html":216,"metadata":217},"\u003Cp>\u003Ca href=\"/en/articles\">Go back to available articles\u003C/a>\u003C/p>",{"headings":218,"imagePaths":219,"frontmatter":220},[],[],{"title":208,"subtitle":209,"lang":68,"slug":205,"draft":72,"excerpt":221,"tags":222,"type":61,"createdAt":223},"Why, how et and especially what.",[140],"2022-06-22T15:34:45.000Z","en-gratuiste",{"id":224,"data":226,"body":212,"filePath":230,"digest":231,"rendered":232},{"title":227,"subtitle":209,"lang":68,"tags":228,"type":61,"slug":224,"createdAt":229,"draft":72},"Gratuiste",[70,140],["Date","2017-05-27T07:47:36.000Z"],"src/content/articles/en/gratuiste.md","ebec75d19f0ff741",{"html":216,"metadata":233},{"headings":234,"imagePaths":235,"frontmatter":236},[],[],{"title":227,"subtitle":209,"lang":68,"slug":224,"draft":72,"excerpt":209,"tags":237,"type":61,"createdAt":238},[70,140],"2017-05-27T07:47:36.000Z","2022",{"id":239,"data":241,"body":245,"filePath":246,"digest":247,"rendered":248},{"title":137,"subtitle":242,"lang":16,"tags":243,"type":61,"slug":239,"createdAt":244},"Mise à jour 2022 de plein de trucs.",[140],["Date","2022-06-08T14:24:06.000Z"],"Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\n\n## Les services\n\n### J’arrête le print\n\nMême si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\n\n### J’internet à fond\n\nÀ l’inverse, je passe mon temps à **faire du web.** Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer **des offres web plus précises,** dans lesquelles je me suis spécialisé.\n\nAinsi, **l’accessibilité numérique** et **l’éco-conception** deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien **mon cœur de métier.**\n\n## Le site\n\nJ’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\n\nJ’ai également fait plusieurs changements de comportements :\n\n- les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\n- j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec [cette analyse](https://twitter.com/HTeuMeuLeu/status/1370310316496728065) de [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu) ;\n- [idem pour la favicon](https://twitter.com/HTeuMeuLeu/status/1370310312214339586) ;\n- je ne déclenche les animations que si l'utilisateur n'a pas demandé au système de minimiser la quantité d'animation ou de mouvement [(référence de l'option)](https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion).\n\nJe suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> 👀).\n\n## Le Nico\n\nD’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif [Good-it!](https://www.good-it.org/) et en participant activement à son développement.\n\nJ’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.","src/content/articles/fr/2022.md","2589166172138721",{"html":249,"metadata":250},"\u003Cp>Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\u003C/p>\n\u003Ch2 id=\"les-services\">Les services\u003C/h2>\n\u003Ch3 id=\"jarrête-le-print\">J’arrête le print\u003C/h3>\n\u003Cp>Même si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\u003C/p>\n\u003Ch3 id=\"jinternet-à-fond\">J’internet à fond\u003C/h3>\n\u003Cp>À l’inverse, je passe mon temps à \u003Cstrong>faire du web.\u003C/strong> Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer \u003Cstrong>des offres web plus précises,\u003C/strong> dans lesquelles je me suis spécialisé.\u003C/p>\n\u003Cp>Ainsi, \u003Cstrong>l’accessibilité numérique\u003C/strong> et \u003Cstrong>l’éco-conception\u003C/strong> deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien \u003Cstrong>mon cœur de métier.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Cp>J’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\u003C/p>\n\u003Cp>J’ai également fait plusieurs changements de comportements :\u003C/p>\n\u003Cul>\n\u003Cli>les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\u003C/li>\n\u003Cli>j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\">cette analyse\u003C/a> de \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a> ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\">idem pour la favicon\u003C/a> ;\u003C/li>\n\u003Cli>je ne déclenche les animations que si l’utilisateur n’a pas demandé au système de minimiser la quantité d’animation ou de mouvement \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion\">(référence de l’option)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>Je suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>D’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif \u003Ca href=\"https://www.good-it.org/\">Good-it!\u003C/a> et en participant activement à son développement.\u003C/p>\n\u003Cp>J’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.\u003C/p>",{"headings":251,"imagePaths":265,"frontmatter":266},[252,255,258,261,264],{"depth":150,"slug":253,"text":254},"les-services","Les services",{"depth":154,"slug":256,"text":257},"jarrête-le-print","J’arrête le print",{"depth":154,"slug":259,"text":260},"jinternet-à-fond","J’internet à fond",{"depth":150,"slug":262,"text":263},"le-site","Le site",{"depth":150,"slug":164,"text":165},[],{"title":137,"subtitle":242,"lang":16,"slug":239,"excerpt":267,"tags":268,"type":61,"createdAt":170},"Évolution des services, du site et de moi-même.",[140],"2023",{"id":269,"data":271,"body":276,"filePath":277,"digest":278,"rendered":279},{"title":174,"subtitle":272,"lang":16,"tags":273,"type":61,"slug":269,"createdAt":274,"updatedAt":275},"Mise à jour 2023.",[140],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"Cet article sera mis à jour lorsque j'aurai des nouveautés à partager au cours de l'année 2023.\n\n## Le site\n\n### Technologies\n\nOups… je l'ai encore (re)fait.\n\nJ'ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même [en 2022 !](/articles/2022/#le-site)\n\nJe ferai certainement un ou deux articles/fragments sur Astro et les extensions que j'ai utilisées. En tout cas c'était super comme expérience. Nuxt v2 n'étant plus vraiment à jour, les performances n'étaient plus au rendez-vous. Astro a complètement corrigé ça.\n\nMon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide **95/100** sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\n\nJ'ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les `media queries`. En vrac, voici certaines améliorations que j'ai mises en place :\n\n- `flexbox` et `grid` pour adapter la mise en page aux différentes tailles d'écran ;\n- variables CSS pour les couleurs, les tailles de polices et les marges ;\n- quelques \u003Cspan lang=\"en\">`container queries`\u003C/span> pour essayer ;\n- propriétés logiques CSS (\u003Cspan lang=\"en\">`inline`\u003C/span> et \u003Cspan lang=\"en\">`block`\u003C/span> à la place de \u003Cspan lang=\"en\">`width`\u003C/span> et \u003Cspan lang=\"en\">`height`\u003C/span> par exemple).\n\nJ'en ai profité pour publier [le code source](https://git.nardu.in/nardu.in/website-astro) sur mon dépôt git.\n\n**Mise à jour #1 :** J'ai ajouté [un flux RSS](/rss.xml) car j'utilise de plus en plus le RSS sur d'autres sites web.\n\n### Suivi des visites\n\nJ’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n'était collectée et je consultais rarement les rapports.\n\nC'est sympa de voir que son site est visité, mais s'il n'y a aucun autre but derrière, c'est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j'en aurai l'utilité (autre que flatter mon égo).\n\nLes rapports de visites précédents sont consultables sur [ce lien.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Contenu\n\n- J'ai ajouté une page [références](/references/) pour lister certains de mes projets.\n- J'ai également ajouté [une page](/veille/) où je répertorie des choses intéressantes trouvées sur le web.\n\n## Projets annexes\n\nJe continue d'enseigner le développement web cette année. Afin d'étoffer mes supports de cours, j'ai mis en place un mini site de documentation disponible à l'adresse [3-w.fr](https://3-w.fr/) (adresse dont je suis très fier).\n\nIl faut que j'arrive à être plus régulier dans sa mise à jour mais j'ai bon espoir que la plateforme aide les élèves à progresser !\n\n**Plus de trucs bientôt!**","src/content/articles/fr/2023.md","d97f4a5af975333f",{"html":280,"metadata":281},"\u003Cp>Cet article sera mis à jour lorsque j’aurai des nouveautés à partager au cours de l’année 2023.\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oups… je l’ai encore (re)fait.\u003C/p>\n\u003Cp>J’ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même \u003Ca href=\"/articles/2022/#le-site\">en 2022 !\u003C/a>\u003C/p>\n\u003Cp>Je ferai certainement un ou deux articles/fragments sur Astro et les extensions que j’ai utilisées. En tout cas c’était super comme expérience. Nuxt v2 n’étant plus vraiment à jour, les performances n’étaient plus au rendez-vous. Astro a complètement corrigé ça.\u003C/p>\n\u003Cp>Mon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide \u003Cstrong>95/100\u003C/strong> sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\u003C/p>\n\u003Cp>J’ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les \u003Ccode>media queries\u003C/code>. En vrac, voici certaines améliorations que j’ai mises en place :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> et \u003Ccode>grid\u003C/code> pour adapter la mise en page aux différentes tailles d’écran ;\u003C/li>\n\u003Cli>variables CSS pour les couleurs, les tailles de polices et les marges ;\u003C/li>\n\u003Cli>quelques \u003Cspan lang=\"en\">\u003Ccode>container queries\u003C/code>\u003C/span> pour essayer ;\u003C/li>\n\u003Cli>propriétés logiques CSS (\u003Cspan lang=\"en\">\u003Ccode>inline\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>block\u003C/code>\u003C/span> à la place de \u003Cspan lang=\"en\">\u003Ccode>width\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>height\u003C/code>\u003C/span> par exemple).\u003C/li>\n\u003C/ul>\n\u003Cp>J’en ai profité pour publier \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">le code source\u003C/a> sur mon dépôt git.\u003C/p>\n\u003Cp>\u003Cstrong>Mise à jour #1 :\u003C/strong> J’ai ajouté \u003Ca href=\"/rss.xml\">un flux RSS\u003C/a> car j’utilise de plus en plus le RSS sur d’autres sites web.\u003C/p>\n\u003Ch3 id=\"suivi-des-visites\">Suivi des visites\u003C/h3>\n\u003Cp>J’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n’était collectée et je consultais rarement les rapports.\u003C/p>\n\u003Cp>C’est sympa de voir que son site est visité, mais s’il n’y a aucun autre but derrière, c’est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j’en aurai l’utilité (autre que flatter mon égo).\u003C/p>\n\u003Cp>Les rapports de visites précédents sont consultables sur \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">ce lien.\u003C/a>\u003C/p>\n\u003Ch3 id=\"contenu\">Contenu\u003C/h3>\n\u003Cul>\n\u003Cli>J’ai ajouté une page \u003Ca href=\"/references/\">références\u003C/a> pour lister certains de mes projets.\u003C/li>\n\u003Cli>J’ai également ajouté \u003Ca href=\"/veille/\">une page\u003C/a> où je répertorie des choses intéressantes trouvées sur le web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"projets-annexes\">Projets annexes\u003C/h2>\n\u003Cp>Je continue d’enseigner le développement web cette année. Afin d’étoffer mes supports de cours, j’ai mis en place un mini site de documentation disponible à l’adresse \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (adresse dont je suis très fier).\u003C/p>\n\u003Cp>Il faut que j’arrive à être plus régulier dans sa mise à jour mais j’ai bon espoir que la plateforme aide les élèves à progresser !\u003C/p>\n\u003Cp>\u003Cstrong>Plus de trucs bientôt!\u003C/strong>\u003C/p>",{"headings":282,"imagePaths":294,"frontmatter":295},[283,284,285,288,291],{"depth":150,"slug":262,"text":263},{"depth":154,"slug":188,"text":189},{"depth":154,"slug":286,"text":287},"suivi-des-visites","Suivi des visites",{"depth":154,"slug":289,"text":290},"contenu","Contenu",{"depth":150,"slug":292,"text":293},"projets-annexes","Projets annexes",[],{"title":174,"subtitle":272,"lang":16,"slug":269,"excerpt":296,"tags":297,"type":61,"createdAt":203,"updatedAt":204},"Suite des évolutions.",[140],"after-effects-expressions",{"id":298,"data":300,"body":304,"filePath":305,"digest":306,"rendered":307},{"title":66,"subtitle":301,"lang":16,"tags":302,"type":61,"slug":298,"createdAt":303,"draft":72},"En cours de traduction, revenez bientôt ;)",[70],["Date","2019-04-24T09:00:00.000Z"],"[Retour aux articles](/articles)","src/content/articles/fr/after-effects-expressions.md","884d725859a7bab5",{"html":308,"metadata":309},"\u003Cp>\u003Ca href=\"/articles\">Retour aux articles\u003C/a>\u003C/p>",{"headings":310,"imagePaths":311,"frontmatter":312},[],[],{"title":66,"subtitle":301,"lang":16,"draft":72,"slug":298,"excerpt":301,"tags":313,"type":61,"createdAt":314},[70],"2019-04-24T09:00:00.000Z","faq",{"id":315,"data":317,"body":322,"filePath":323,"digest":324,"rendered":325},{"title":318,"subtitle":319,"lang":16,"tags":320,"type":61,"slug":315,"createdAt":321},"Accessibilité, sobriété et F.A.Q.","Explications sur ma vision et mon fonctionnement.",[140],["Date","2022-06-22T15:34:45.000Z"],"## l'Accessibilité\n\n### Quèsaco ?\n\nD'après [access42 :](https://access42.net)\n\n> L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\n\nAinsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que **n'importe quel visiteur** puisse l'utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais **ce n'est pas le cas !**\n\nLorsqu'un site est pensé et conçu avec l'accessibilité en tête, il ne prend **pas plus de temps** qu'un projet qui ne le fait pas. En revanche, **corriger** un site existant qui n'a pas bénéficié de cette réflexion en amont **demande beaucoup plus d'efforts.**\n\n### Pourquoi c'est important ?\n\nAprès avoir été sensibilisé à l'accessibilité et aux [situations frustrantes voire bloquantes](https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles) que rencontrent les personnes handicapées sur le web, j'ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m'a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\n\n## l'Éco-conception\n\n### Quèsaco ?\n\nD'après le collectif [\u003Cspan lang=\"en\">green it\u003C/span> :](https://www.greenit.fr)\n\n> L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\n\nIl s'agit ici pour moi de créer des produits les plus sobres possibles. C'est-à-dire de développer ou d'utiliser une fonctionnalité uniquement si elle est indispensable.\n\nPar exemple, mettre en place **un formulaire de contact** sur un site web implique plusieurs choses :\n\n- développer un formulaire\n- envoyer les données au serveur\n- vérifier les données envoyées\n- envoyer les données par mail\n- confirmer l'envoi du mail (en fournissant une copie)\n- gérer les erreurs à chaque étape\n\nUn site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d'effectuer ces opérations (ou un prestataire qui s'en charge). C'est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu'un formulaire. Dans le cas d'un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\n\n### Pourquoi c'est important ?\n\nL'éco-conception fait beaucoup de bien à la qualité globale d'un site et à l'expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\n\n## F.A.Q.\n\n### Cette démarche est-elle opportuniste ?\n\n**Non.** Il est vrai que l'accessibilité et, surtout, l'éco-conception, commencent à être « tendance ». On pourrait donc croire que j'en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c'est ma responsabilité de créer des sites web accessibles et éco-conçus **par défaut.**\n\n### Un site accessible est-il plus cher ?\n\n**Oui et non.** Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l'accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j'augmente mes tarifs suite à l'obtention de certifications relatives à mon activité.\n\n### Mon site sera-t-il 100 % accessible ?\n\n**Non,** je ne suis pas en mesure de garantir ou de certifier la conformité totale d'un site au [référentiel général d'amélioration de l'accessibilité.](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d'un site. Cependant, je peux vous accompagner avant et après l'audit afin d'anticiper puis de corriger les critères d'accessibilité requis. [Access42](https://access42.net/) et [Tanaguru](https://www.tanaguru.com/) font parties de ces entreprises spécialisées.\n\n### Pourquoi ne pas utiliser un outil automatique ?\n\nCar ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom [sous peine de procès](https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/)), ne sont pas des solutions micracles. Lisez [cet article](https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/) d'une experte en accessibilité et/ou [ce test](https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/) de différents outils pour en savoir plus.\n\n### Un site éco-conçu et accessible peut-il être beau ?\n\n**Oui, évidemment.** Je vous laisse juger par vous-même avec [cette liste](https://lowww.directory/) de sites éco-conçus. En ce qui concerne l'accessibilité, elle n'impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d'un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l'utilisation d'un produit.","src/content/articles/fr/faq.md","65e9e60bcd00806c",{"html":326,"metadata":327},"\u003Ch2 id=\"laccessibilité\">l’Accessibilité\u003C/h2>\n\u003Ch3 id=\"quèsaco\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après \u003Ca href=\"https://access42.net\">access42 :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Ainsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que \u003Cstrong>n’importe quel visiteur\u003C/strong> puisse l’utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais \u003Cstrong>ce n’est pas le cas !\u003C/strong>\u003C/p>\n\u003Cp>Lorsqu’un site est pensé et conçu avec l’accessibilité en tête, il ne prend \u003Cstrong>pas plus de temps\u003C/strong> qu’un projet qui ne le fait pas. En revanche, \u003Cstrong>corriger\u003C/strong> un site existant qui n’a pas bénéficié de cette réflexion en amont \u003Cstrong>demande beaucoup plus d’efforts.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>Après avoir été sensibilisé à l’accessibilité et aux \u003Ca href=\"https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles\">situations frustrantes voire bloquantes\u003C/a> que rencontrent les personnes handicapées sur le web, j’ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m’a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\u003C/p>\n\u003Ch2 id=\"léco-conception\">l’Éco-conception\u003C/h2>\n\u003Ch3 id=\"quèsaco-1\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après le collectif \u003Ca href=\"https://www.greenit.fr\">\u003Cspan lang=\"en\">green it\u003C/span> :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Il s’agit ici pour moi de créer des produits les plus sobres possibles. C’est-à-dire de développer ou d’utiliser une fonctionnalité uniquement si elle est indispensable.\u003C/p>\n\u003Cp>Par exemple, mettre en place \u003Cstrong>un formulaire de contact\u003C/strong> sur un site web implique plusieurs choses :\u003C/p>\n\u003Cul>\n\u003Cli>développer un formulaire\u003C/li>\n\u003Cli>envoyer les données au serveur\u003C/li>\n\u003Cli>vérifier les données envoyées\u003C/li>\n\u003Cli>envoyer les données par mail\u003C/li>\n\u003Cli>confirmer l’envoi du mail (en fournissant une copie)\u003C/li>\n\u003Cli>gérer les erreurs à chaque étape\u003C/li>\n\u003C/ul>\n\u003Cp>Un site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d’effectuer ces opérations (ou un prestataire qui s’en charge). C’est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu’un formulaire. Dans le cas d’un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important-1\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>L’éco-conception fait beaucoup de bien à la qualité globale d’un site et à l’expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\u003C/p>\n\u003Ch2 id=\"faq\">F.A.Q.\u003C/h2>\n\u003Ch3 id=\"cette-démarche-est-elle-opportuniste\">Cette démarche est-elle opportuniste ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non.\u003C/strong> Il est vrai que l’accessibilité et, surtout, l’éco-conception, commencent à être « tendance ». On pourrait donc croire que j’en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c’est ma responsabilité de créer des sites web accessibles et éco-conçus \u003Cstrong>par défaut.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"un-site-accessible-est-il-plus-cher\">Un site accessible est-il plus cher ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui et non.\u003C/strong> Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l’accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j’augmente mes tarifs suite à l’obtention de certifications relatives à mon activité.\u003C/p>\n\u003Ch3 id=\"mon-site-sera-t-il-100-accessible\">Mon site sera-t-il 100 % accessible ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non,\u003C/strong> je ne suis pas en mesure de garantir ou de certifier la conformité totale d’un site au \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité.\u003C/a> Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d’un site. Cependant, je peux vous accompagner avant et après l’audit afin d’anticiper puis de corriger les critères d’accessibilité requis. \u003Ca href=\"https://access42.net/\">Access42\u003C/a> et \u003Ca href=\"https://www.tanaguru.com/\">Tanaguru\u003C/a> font parties de ces entreprises spécialisées.\u003C/p>\n\u003Ch3 id=\"pourquoi-ne-pas-utiliser-un-outil-automatique\">Pourquoi ne pas utiliser un outil automatique ?\u003C/h3>\n\u003Cp>Car ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom \u003Ca href=\"https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/\">sous peine de procès\u003C/a>), ne sont pas des solutions micracles. Lisez \u003Ca href=\"https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/\">cet article\u003C/a> d’une experte en accessibilité et/ou \u003Ca href=\"https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/\">ce test\u003C/a> de différents outils pour en savoir plus.\u003C/p>\n\u003Ch3 id=\"un-site-éco-conçu-et-accessible-peut-il-être-beau\">Un site éco-conçu et accessible peut-il être beau ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui, évidemment.\u003C/strong> Je vous laisse juger par vous-même avec \u003Ca href=\"https://lowww.directory/\">cette liste\u003C/a> de sites éco-conçus. En ce qui concerne l’accessibilité, elle n’impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d’un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l’utilisation d’un produit.\u003C/p>",{"headings":328,"imagePaths":362,"frontmatter":363},[329,332,335,338,341,343,345,347,350,353,356,359],{"depth":150,"slug":330,"text":331},"laccessibilité","l’Accessibilité",{"depth":154,"slug":333,"text":334},"quèsaco","Quèsaco ?",{"depth":154,"slug":336,"text":337},"pourquoi-cest-important","Pourquoi c’est important ?",{"depth":150,"slug":339,"text":340},"léco-conception","l’Éco-conception",{"depth":154,"slug":342,"text":334},"quèsaco-1",{"depth":154,"slug":344,"text":337},"pourquoi-cest-important-1",{"depth":150,"slug":315,"text":346},"F.A.Q.",{"depth":154,"slug":348,"text":349},"cette-démarche-est-elle-opportuniste","Cette démarche est-elle opportuniste ?",{"depth":154,"slug":351,"text":352},"un-site-accessible-est-il-plus-cher","Un site accessible est-il plus cher ?",{"depth":154,"slug":354,"text":355},"mon-site-sera-t-il-100-accessible","Mon site sera-t-il 100 % accessible ?",{"depth":154,"slug":357,"text":358},"pourquoi-ne-pas-utiliser-un-outil-automatique","Pourquoi ne pas utiliser un outil automatique ?",{"depth":154,"slug":360,"text":361},"un-site-éco-conçu-et-accessible-peut-il-être-beau","Un site éco-conçu et accessible peut-il être beau ?",[],{"title":318,"subtitle":319,"lang":16,"slug":315,"excerpt":364,"tags":365,"type":61,"createdAt":223},"Pourquoi, comment et surtout quèsaco.",[140],"gratuiste",{"id":366,"data":368,"body":374,"filePath":375,"digest":376,"rendered":377},{"title":227,"subtitle":369,"lang":16,"tags":370,"type":61,"slug":366,"createdAt":372,"updatedAt":373},"Ou le travail gratuit.",[371,140],"Graphisme",["Date","2017-05-27T07:47:36.000Z"],["Date","2022-12-27T15:36:06.000Z"],"## Gratuiste, qu’est-ce que c’est ?\n\nDans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc. \nDe plus en plus, la communauté s’élève contre ces pratiques et les [dénonce.](https://twitter.com/PayeTonAffiche)\n\n> “ On n’est pas des gratuistes ! ”\n\nComprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez [cette vidéo](https://youtu.be/essNmNOrQto) qui transpose ces pratiques à des métiers “ standards ” et [celle-ci](https://youtu.be/DsstOs-K7gk) qui explique en détails le processus actuel.\n\n## T’es débile du coup ?\n\nJ’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\n\nÉtant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre. \nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\n\n## Le concept\n\nJe compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux. \nCe type de prestation porte le nom de “ **pro bono publico** ” – “ **pour le bien public** ”.\n\nCette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\n\n> Graphiste pro bono, pourquoi pas ?\n\n## Quels genres de services ?\n\nEn toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\n\n### En résumé :\n\n- maquette de site web\n- intégration front-end (en dur ou via wordpress) du site\n- gestion de la mise en ligne du site\n- newsletter (design et/ou intégration)\n- flyers\n- autres petites demandes\n\nVous pouvez avoir un aperçu de mon travail [sur ce même site.](/) J’ai déjà eu l’occasion de travailler pour :\n\n- [Cygnal](/projets/cygnal)\n- [OpenMole](https://openmole.org/)\n- [Good-it](https://good-it.org)\n\n## Dans quelles conditions ?\n\n- l’association doit être active\n- elle doit porter des valeurs que je partage\n- elle doit pouvoir me montrer ses actions\n- elle ne doit pas avoir les moyens de se payer un graphiste\n\n## C’est un peu trop beau pour être vrai ton truc…\n\nIl faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\n\nSi vous êtes intéressés, [envoyez-moi un mail !](mailto:contac@nardu.in)\n\n## Qu’est-ce que t’y gagnes toi ?\n\nSimplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.","src/content/articles/fr/gratuiste.md","80c20493583a842c",{"html":378,"metadata":379},"\u003Ch2 id=\"gratuiste-quest-ce-que-cest\">Gratuiste, qu’est-ce que c’est ?\u003C/h2>\n\u003Cp>Dans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc.\u003Cbr>\nDe plus en plus, la communauté s’élève contre ces pratiques et les \u003Ca href=\"https://twitter.com/PayeTonAffiche\">dénonce.\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“ On n’est pas des gratuistes ! ”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Comprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez \u003Ca href=\"https://youtu.be/essNmNOrQto\">cette vidéo\u003C/a> qui transpose ces pratiques à des métiers “ standards ” et \u003Ca href=\"https://youtu.be/DsstOs-K7gk\">celle-ci\u003C/a> qui explique en détails le processus actuel.\u003C/p>\n\u003Ch2 id=\"tes-débile-du-coup\">T’es débile du coup ?\u003C/h2>\n\u003Cp>J’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\u003C/p>\n\u003Cp>Étant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre.\u003Cbr>\nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\u003C/p>\n\u003Ch2 id=\"le-concept\">Le concept\u003C/h2>\n\u003Cp>Je compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux.\u003Cbr>\nCe type de prestation porte le nom de “ \u003Cstrong>pro bono publico\u003C/strong> ” – “ \u003Cstrong>pour le bien public\u003C/strong> ”.\u003C/p>\n\u003Cp>Cette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Graphiste pro bono, pourquoi pas ?\u003C/p>\n\u003C/blockquote>\n\u003Ch2 id=\"quels-genres-de-services\">Quels genres de services ?\u003C/h2>\n\u003Cp>En toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\u003C/p>\n\u003Ch3 id=\"en-résumé\">En résumé :\u003C/h3>\n\u003Cul>\n\u003Cli>maquette de site web\u003C/li>\n\u003Cli>intégration front-end (en dur ou via wordpress) du site\u003C/li>\n\u003Cli>gestion de la mise en ligne du site\u003C/li>\n\u003Cli>newsletter (design et/ou intégration)\u003C/li>\n\u003Cli>flyers\u003C/li>\n\u003Cli>autres petites demandes\u003C/li>\n\u003C/ul>\n\u003Cp>Vous pouvez avoir un aperçu de mon travail \u003Ca href=\"/\">sur ce même site.\u003C/a> J’ai déjà eu l’occasion de travailler pour :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"/projets/cygnal\">Cygnal\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://openmole.org/\">OpenMole\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://good-it.org\">Good-it\u003C/a>\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"dans-quelles-conditions\">Dans quelles conditions ?\u003C/h2>\n\u003Cul>\n\u003Cli>l’association doit être active\u003C/li>\n\u003Cli>elle doit porter des valeurs que je partage\u003C/li>\n\u003Cli>elle doit pouvoir me montrer ses actions\u003C/li>\n\u003Cli>elle ne doit pas avoir les moyens de se payer un graphiste\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"cest-un-peu-trop-beau-pour-être-vrai-ton-truc\">C’est un peu trop beau pour être vrai ton truc…\u003C/h2>\n\u003Cp>Il faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\u003C/p>\n\u003Cp>Si vous êtes intéressés, \u003Ca href=\"mailto:contac@nardu.in\">envoyez-moi un mail !\u003C/a>\u003C/p>\n\u003Ch2 id=\"quest-ce-que-ty-gagnes-toi\">Qu’est-ce que t’y gagnes toi ?\u003C/h2>\n\u003Cp>Simplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.\u003C/p>",{"headings":380,"imagePaths":405,"frontmatter":406},[381,384,387,390,393,396,399,402],{"depth":150,"slug":382,"text":383},"gratuiste-quest-ce-que-cest","Gratuiste, qu’est-ce que c’est ?",{"depth":150,"slug":385,"text":386},"tes-débile-du-coup","T’es débile du coup ?",{"depth":150,"slug":388,"text":389},"le-concept","Le concept",{"depth":150,"slug":391,"text":392},"quels-genres-de-services","Quels genres de services ?",{"depth":154,"slug":394,"text":395},"en-résumé","En résumé :",{"depth":150,"slug":397,"text":398},"dans-quelles-conditions","Dans quelles conditions ?",{"depth":150,"slug":400,"text":401},"cest-un-peu-trop-beau-pour-être-vrai-ton-truc","C’est un peu trop beau pour être vrai ton truc…",{"depth":150,"slug":403,"text":404},"quest-ce-que-ty-gagnes-toi","Qu’est-ce que t’y gagnes toi ?",[],{"title":227,"subtitle":369,"lang":16,"slug":366,"excerpt":407,"tags":408,"type":61,"createdAt":238,"updatedAt":409},"J’ai cherché un moyen de mettre mes compétences au service d’autrui et je pense avoir trouvé: je vais travailler gratuitement pour des associations.",[371,140],"2022-12-27T15:36:06.000Z","video-compression",{"id":410,"data":412,"body":304,"filePath":417,"digest":418,"rendered":419},{"title":413,"subtitle":301,"lang":16,"tags":414,"type":61,"slug":410,"createdAt":415,"updatedAt":416,"draft":72},"Compression vidéo",[70],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"src/content/articles/fr/video-compression.md","2296c41874b23b3d",{"html":308,"metadata":420},{"headings":421,"imagePaths":422,"frontmatter":423},[],[],{"title":413,"subtitle":301,"lang":16,"draft":72,"slug":410,"excerpt":424,"tags":425,"type":61,"createdAt":426,"updatedAt":170},"Pas encore traduit",[70],"2021-05-05T09:00:00.000Z","fragments",["Map",429,430,440,441,451,452,462,463,473,474,484,485,502,503,517,518,570,571,634,635,696,697,713,714,748,749,782,783,806,807,848,849],"buttons",{"id":429,"data":431,"body":437,"filePath":438,"digest":439,"deferredRender":72},{"title":432,"subtitle":433,"lang":16,"tags":434,"type":427,"slug":429,"createdAt":436,"code":72,"draft":72},"Effets de survol de boutons","Simples mais efficaces.",[435],"CSS",["Date","2020-10-08T09:00:00.000Z"],"## Styles généraux\n\nTous les boutons présents utilisent ces styles comme base en guise de « reset » :\n\n> N'oubliez pas de préfixer si besoin !\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Ajout d'icône\n\n\u003Cbutton role='none' class='btn btn-icon'>\n\t\u003Cspan>Icône\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('./assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double volet\n\n\u003Cbutton role='none' class='btn btn-rideau'>\n\t\u003Cspan>Volet\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Dégradé animé\n\n\u003Cbutton role='none' class='btn btn-gradient'>\n\t\u003Cspan>Dégradé\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Échelle non desctructrice\n\n\u003Cbutton role='none' class='btn btn-scale'>\n\t\u003Cspan>Échelle\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/fr/buttons.mdx","f5d7b03520f96b04","image-full",{"id":440,"data":442,"body":448,"filePath":449,"digest":450,"deferredRender":72},{"title":443,"subtitle":444,"lang":16,"tags":445,"type":427,"slug":440,"createdAt":446,"updatedAt":447},"Image pleine largeur","Casser le conteneur.",[435],["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Image inline\n\nOn est parfois obligé d'utiliser des images dans des balises `img` plutôt que dans un `background` en css. Comment faire alors pour que l'image sorte de son conteneur pour en faire une bannière ? Exemple pratique à partir de ce même site.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_container_9e3939b3ae.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Contexte\n\nConsidérons le html suivant :\n\n```html\n\u003Csection class=\"container\">\n\t\u003Cdiv class=\"hero\">\n\t\t\u003Cimg class=\"hero__image\" src=\"hero.img\" />\n\t\u003C/div>\n\u003C/section>\n```\n\nEt le style suivant :\n\n```css\n.container {\n\tpadding: 0 14px;\n\tmargin-left: auto;\n\tmargin-right: auto;\n\tmax-width: 1040px;\n}\nimg {\n\tmax-width: 100%;\n\theight: auto;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_original_d49f0d11bf.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Déborder du conteneur\n\nAfin de faire prendre à l'image toute la largeur, on agit sur son conteneur :\n\n```css\n.hero {\n\tmargin-left: calc(50% - 50vw);\n\tposition: relative;\n\twidth: 100vw;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_full_2a902f9539.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Faire une bannière\n\nOn peut alors réduire la hauteur du conteneur pour obtenir une bannière plutôt que l'image entière et faire correspondre la hauteur de l'image à la hauteur du conteneur :\n\n```css\n.hero {\n\theight: 200px;\n}\n.hero__image {\n\theight: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_height_81b4ce969a.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nIl faut ensuite forcer l'image à prendre toute la largeur du conteneur :\n\n```css\n.hero__image {\n\twidth: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_deformed_479046d2cb.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nPas top…\n\n### J'ai cassé l'image…\n\n**ENFIN** le code magique pour redonner son ratio à l'image sans la déformer :\n\n```css\n.hero__image {\n\tobject-fit: cover;\n\tobject-position: center; /* à positionner comme on veut */\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_6c164e82b3.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nCette technique s'apparente à l'utilisation d'une image de background mais en dur 😁\n\n## TL;DR\n\nLe code complet :\n\n```css\n.hero {\n\tmargin-left: calc(50% - 50vw);\n\tposition: relative;\n\twidth: 100vw;\n\theight: 200px;\n}\n.hero__image {\n\twidth: 100%;\n\theight: 100%;\n\t-o-object-fit: cover;\n\tobject-fit: cover;\n\t-o-object-position: center;\n\tobject-position: center;\n}\n```","src/content/fragments/fr/image-full.mdx","91ebd97eef5cb8a4","super-cookies",{"id":451,"data":453,"body":459,"filePath":460,"digest":461,"deferredRender":72},{"title":454,"subtitle":455,"lang":16,"tags":456,"type":427,"slug":451,"createdAt":458},"Les meilleurs cookies","Des gâteaux sans consentement.",[457],"cuisine",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Version végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 3/4 de l'aquafaba de 400g de pois chiche (l'eau des pois chiche)\n- 125 grammes d'huile de noix de coco\n- 2 cuillères à café de sirop d'érable\n- 1 plaquette de chocolat (noir) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre si besoin l'huile de noix de coco à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (huile, aquafaba, sirop d'érable)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Version non végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 1 œuf\n- 125 grammes de beurre fondu\n- 2 cuillères à café de miel\n- 1 plaquette de chocolat (noir/blanc/les deux) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre le beurre à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (beurre fondu, œuf, miel)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Notes\n\nLe chocolat peut-être remplacé par n'importe quoi comme des noix, des raisins secs, des légos… (mangez pas des légos soyez sérieux).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Tous les ingrédients mélangés forment une pâte marron.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Les cookies cuits sont bombés et très moelleux.'\n/>","src/content/fragments/fr/super-cookies.mdx","f7a802e0b68cb04a","en-image-full",{"id":462,"data":464,"body":470,"filePath":471,"digest":472,"deferredRender":72},{"title":465,"subtitle":209,"lang":68,"tags":466,"type":467,"slug":462,"createdAt":468,"updatedAt":469,"draft":72},"Full width image",[435],"snippets",["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"[Go back to available snippets](/en/snippets)","src/content/fragments/en/image-full.mdx","2e3dddf593f6d72f","en-super-cookies",{"id":473,"data":475,"body":481,"filePath":482,"digest":483,"deferredRender":72},{"title":476,"subtitle":477,"lang":68,"tags":478,"type":467,"slug":473,"createdAt":480},"The best cookies","Consentless biscuits.",[479],"food",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 tablespoon of baking powder\n- 3/4 of aquafaba from 400g of chickpea (chickpea water)\n- 125 grams of coconut oil\n- 2 teaspoons of maple syrup\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- if necessary, melt the coconut oil over low heat\n- meanwhile, mix all the dry ingredients\n- add all liquid ingredients (oil, aquafaba, maple syrup)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Non vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 table spoon of baking powder\n- 1 egg\n- 125 grams of melted butter\n- 2 teaspoons of honey\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- melt butter over low heat\n- meanwhile, mix all dry ingredients\n- add all liquid ingredients (melted butter, egg, honey)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Notes\n\nChocolate can be replaced by anything like nuts, raisins, legos... (don't eat legos be reasonable).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='All ingredients mixed together to form a brown paste.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='The cookies are round and soft after baking.'\n/>","src/content/fragments/en/super-cookies.mdx","b0c67adad40c177c","array-vs-array",{"id":484,"data":486,"body":492,"filePath":493,"digest":494,"rendered":495},{"title":487,"subtitle":488,"lang":16,"tags":489,"type":427,"slug":484,"createdAt":491,"draft":72},"Filtrer un array avec un autre array","En cours de traduction.",[490],"nuxt.js",["Date","2022-06-08T14:24:06.000Z"],"[Voir les fragments disponibles](/fragments)","src/content/fragments/fr/array-vs-array.md","7321d444177c3841",{"html":496,"metadata":497},"\u003Cp>\u003Ca href=\"/fragments\">Voir les fragments disponibles\u003C/a>\u003C/p>",{"headings":498,"imagePaths":499,"frontmatter":500},[],[],{"title":487,"subtitle":488,"lang":16,"draft":72,"slug":484,"createdAt":170,"excerpt":488,"tags":501,"type":427},[490],"toulouse-fun",{"id":502,"data":504,"body":492,"filePath":509,"digest":510,"rendered":511},{"title":505,"subtitle":488,"lang":16,"tags":506,"type":427,"slug":502,"createdAt":508,"draft":72},"Toulouse yourself",[507],"lifestyle",["Date","2022-06-22T15:34:45.000Z"],"src/content/fragments/fr/toulouse-fun.md","a0c25b438b34c05e",{"html":496,"metadata":512},{"headings":513,"imagePaths":514,"frontmatter":515},[],[],{"title":505,"subtitle":488,"lang":16,"draft":72,"slug":502,"createdAt":223,"excerpt":488,"tags":516,"type":427},[507],"en-toulouse-fun",{"id":517,"data":519,"body":523,"filePath":524,"digest":525,"rendered":526},{"title":505,"subtitle":520,"lang":68,"tags":521,"type":467,"slug":517,"createdAt":522},"Only the bestest",[507],["Date","2022-06-22T15:34:45.000Z"],"Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite. \n**It's always a good idea to make a reservation!**\n\n## Restaurants\n\n### French cuisine\n\n- [Solides](https://www.solides.fr/) — semi-gastronomic\n- [Les impulsifs](https://les-impulsifs-toulouse.eatbu.com/?lang=en) — semi-gastronomic\n- [Sixta](https://sixta-toulouse.fr/) — vege/vegan/gluten friendly\n- [Attila](https://attila.site-solocal.com/) — great **fish restaurant,** just above the Victor Hugo market\n- [Chez Emile](https://www.restaurant-emile.com/) - best [cassoulet](https://en.wikipedia.org/wiki/Cassoulet) in town (or so I'm told)\n\n### Korean\n\n- [Le ptit Louis](https://leptitlouis.fr/) — best of its kind, **only for lunch**\n- [Kongbap](https://kong-bap.com/) — street-food like\n\n### Japanese\n\n- [Iori](https://www.iori.fr/) — best ramen\n- [Japoyaki](https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402) — best sushi/sashimis\n\n## Drinks and snacks\n\n### Bars\n\n- [Le Bièrographe](https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327) — all time favourite, **check out the typical toulouse basement**\n- [A Taula](https://www.facebook.com/ataulatolosa/) — all time favourite in summer, **amazing terrace,** also: great tapas\n- [The Hopscotch Pub](https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385) — good beers, good whiskies, good cocktials, good food\n\n### Cafés & tea rooms\n\n- [Bapz](https://www.bapz.fr/contact) — Excellent pastries / hot beverages\n- [Ô thé divin](https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/) — nice lunch options\n- [Les Rêveries d’Hercule](https://www.lesreveriesdhercule.com/) — Pottery Café, relaxing activity (ceramics need to be baked, there'll be a delay to get them back)\n- Bonus: the best bakeries in [Carmes](https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872) and [Saint-Aubin](https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694) — croissants, baguettes **traditions**, chocolatines and more\n\n### Wine shops\n\n- [l'envie du sud](https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930) — amazing selection of wines and other spirits, excellent advice from the staff\n- [enoteca](https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952) — smaller selection but more beers and great advice from the staff as well\n\n## Other delights\n\n### Ice creams\n\n- [Forno gusto](https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450) — only in the summer\n- [Moustache](https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540) — lots of flavours\n\n### Cheese shop\n\n- [Xavier](https://xavier.fr/) — one of the **best of the country**, two shops in Toulouse, including one at Victor Hugo market\n- [Massembea](https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490) — a serious contender in Toulouse (weird hours)\n\n### Delicatessen\n\n- [Café Bacquié](http://cafe-bacquie.com/) — stock up on fine foods, coffees, teas and other great quality products","src/content/fragments/en/toulouse-fun.md","370491cc68079e8c",{"html":527,"metadata":528},"\u003Cp>Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite.\u003Cbr>\n\u003Cstrong>It’s always a good idea to make a reservation!\u003C/strong>\u003C/p>\n\u003Ch2 id=\"restaurants\">Restaurants\u003C/h2>\n\u003Ch3 id=\"french-cuisine\">French cuisine\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.solides.fr/\">Solides\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://les-impulsifs-toulouse.eatbu.com/?lang=en\">Les impulsifs\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://sixta-toulouse.fr/\">Sixta\u003C/a> — vege/vegan/gluten friendly\u003C/li>\n\u003Cli>\u003Ca href=\"https://attila.site-solocal.com/\">Attila\u003C/a> — great \u003Cstrong>fish restaurant,\u003C/strong> just above the Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.restaurant-emile.com/\">Chez Emile\u003C/a> - best \u003Ca href=\"https://en.wikipedia.org/wiki/Cassoulet\">cassoulet\u003C/a> in town (or so I’m told)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"korean\">Korean\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://leptitlouis.fr/\">Le ptit Louis\u003C/a> — best of its kind, \u003Cstrong>only for lunch\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://kong-bap.com/\">Kongbap\u003C/a> — street-food like\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"japanese\">Japanese\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.iori.fr/\">Iori\u003C/a> — best ramen\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402\">Japoyaki\u003C/a> — best sushi/sashimis\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"drinks-and-snacks\">Drinks and snacks\u003C/h2>\n\u003Ch3 id=\"bars\">Bars\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327\">Le Bièrographe\u003C/a> — all time favourite, \u003Cstrong>check out the typical toulouse basement\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.facebook.com/ataulatolosa/\">A Taula\u003C/a> — all time favourite in summer, \u003Cstrong>amazing terrace,\u003C/strong> also: great tapas\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385\">The Hopscotch Pub\u003C/a> — good beers, good whiskies, good cocktials, good food\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cafés--tea-rooms\">Cafés & tea rooms\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.bapz.fr/contact\">Bapz\u003C/a> — Excellent pastries / hot beverages\u003C/li>\n\u003Cli>\u003Ca href=\"https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/\">Ô thé divin\u003C/a> — nice lunch options\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lesreveriesdhercule.com/\">Les Rêveries d’Hercule\u003C/a> — Pottery Café, relaxing activity (ceramics need to be baked, there’ll be a delay to get them back)\u003C/li>\n\u003Cli>Bonus: the best bakeries in \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872\">Carmes\u003C/a> and \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694\">Saint-Aubin\u003C/a> — croissants, baguettes \u003Cstrong>traditions\u003C/strong>, chocolatines and more\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"wine-shops\">Wine shops\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930\">l’envie du sud\u003C/a> — amazing selection of wines and other spirits, excellent advice from the staff\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952\">enoteca\u003C/a> — smaller selection but more beers and great advice from the staff as well\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"other-delights\">Other delights\u003C/h2>\n\u003Ch3 id=\"ice-creams\">Ice creams\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450\">Forno gusto\u003C/a> — only in the summer\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540\">Moustache\u003C/a> — lots of flavours\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cheese-shop\">Cheese shop\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://xavier.fr/\">Xavier\u003C/a> — one of the \u003Cstrong>best of the country\u003C/strong>, two shops in Toulouse, including one at Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490\">Massembea\u003C/a> — a serious contender in Toulouse (weird hours)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"delicatessen\">Delicatessen\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"http://cafe-bacquie.com/\">Café Bacquié\u003C/a> — stock up on fine foods, coffees, teas and other great quality products\u003C/li>\n\u003C/ul>",{"headings":529,"imagePaths":566,"frontmatter":567},[530,533,536,539,542,545,548,551,554,557,560,563],{"depth":150,"slug":531,"text":532},"restaurants","Restaurants",{"depth":154,"slug":534,"text":535},"french-cuisine","French cuisine",{"depth":154,"slug":537,"text":538},"korean","Korean",{"depth":154,"slug":540,"text":541},"japanese","Japanese",{"depth":150,"slug":543,"text":544},"drinks-and-snacks","Drinks and snacks",{"depth":154,"slug":546,"text":547},"bars","Bars",{"depth":154,"slug":549,"text":550},"cafés--tea-rooms","Cafés & tea rooms",{"depth":154,"slug":552,"text":553},"wine-shops","Wine shops",{"depth":150,"slug":555,"text":556},"other-delights","Other delights",{"depth":154,"slug":558,"text":559},"ice-creams","Ice creams",{"depth":154,"slug":561,"text":562},"cheese-shop","Cheese shop",{"depth":154,"slug":564,"text":565},"delicatessen","Delicatessen",[],{"title":505,"subtitle":520,"lang":68,"slug":517,"excerpt":568,"tags":569,"type":467,"createdAt":223},"Gonna have to trust me on this ¯\\_(ツ)_/¯",[507],"acme-sh-tls-cert",{"id":570,"data":572,"body":578,"filePath":579,"digest":580,"rendered":581},{"title":573,"subtitle":574,"lang":16,"tags":575,"type":427,"slug":570,"createdAt":577},"Certificates TLS robustes avec acme.sh","384-bit de https",[576],"sécurité",["Date","2022-06-08T14:24:06.000Z"],"## Attention\n\nJe ne suis pas du tout un expert en sécurité. J'aime juste les trucs nouveaux et stylés des internets. \nC'est pourquoi j'ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J'ai maintenant un joli 100/100 sur [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nVous pouvez en apprendre (beaucoup) plus [ici](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) et sur les liens cités (en anglais).\n\n## Prérequis\n\n### Installer acme.sh\n\nPour des raisons de simplicité et d'automatisation, j'utilise [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changer l'authorité par défaut\n\nPar défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let's Encrypt car, d'après acme.sh, ils sont les seuls à proposer des certificats ECC.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Utiliser l'api DNS\n\nSi vous en avez la possibilité, la façon la plus simple de générer un certificat est via l'api de votre fournisseur DNS. acme.sh supporte [énormément](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) de fournisseurs DNS.\n\n### Definir la clé api\n\nSuivez la [documentation](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) pour votre fournisseur DNS, généralement:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Émettre le certificat\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Utiliser le mode standalone\n\nSi vous n'avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s'occupe de toutes les vérifications.\n\nLe port `80` doit être disponible.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Exemples\n\n### Multi domaines standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domaine DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Étapes supplémentaires\n\nLe certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\n\n### Version TLS\n\nLimiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu [la différence de compatibilité de 5%](https://caniuse.com/?search=tls%201.) avec 1.2).\n\n### HSTS\n\nUtiliser le header [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/).\n\n```\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Suite cryptographique\n\nUtiliser une suite cryptographique récente et robuste. C'est ici que mes connaissances deviennent limitées… J'ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\n\nJ'avais basé ma première suite sur [cette liste](https://tls.imirhil.fr/ciphers), en la comparant avec celle de la compatibilité (d'anciens ?) [navigateurs](https://tls.imirhil.fr/suite).\n\nJ'ai ensuite demandé à [Aeris](https://twitter.com/aeris22), le créateur de [tls.imirhil.fr](https://tls.imirhil.fr), ses conseils sur cette suite. Il m'a recommandé d'utiliser :\n\n```\nECDHE+AES:ECDHE+CHACHA20\n```\n\nAfin d'atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\n\n```\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/fr/acme-sh-tls-cert.md","82e6d91747c28ea5",{"html":582,"metadata":583},"\u003Ch2 id=\"attention\">Attention\u003C/h2>\n\u003Cp>Je ne suis pas du tout un expert en sécurité. J’aime juste les trucs nouveaux et stylés des internets.\u003Cbr>\nC’est pourquoi j’ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J’ai maintenant un joli 100/100 sur \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>Vous pouvez en apprendre (beaucoup) plus \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">ici\u003C/a> et sur les liens cités (en anglais).\u003C/p>\n\u003Ch2 id=\"prérequis\">Prérequis\u003C/h2>\n\u003Ch3 id=\"installer-acmesh\">Installer acme.sh\u003C/h3>\n\u003Cp>Pour des raisons de simplicité et d’automatisation, j’utilise \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\"># pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">curl\u003C/span>\u003Cspan style=\"color:#98C379\"> https://get.acme.sh\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> | \u003C/span>\u003Cspan style=\"color:#61AFEF\">sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> -s\u003C/span>\u003Cspan style=\"color:#98C379\"> email=mail@domain.tld\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"changer-lauthorité-par-défaut\">Changer l’authorité par défaut\u003C/h3>\n\u003Cp>Par défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let’s Encrypt car, d’après acme.sh, ils sont les seuls à proposer des certificats ECC.\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --set-default-ca\u003C/span>\u003Cspan style=\"color:#D19A66\"> --server\u003C/span>\u003Cspan style=\"color:#98C379\"> letsencrypt\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"utiliser-lapi-dns\">Utiliser l’api DNS\u003C/h2>\n\u003Cp>Si vous en avez la possibilité, la façon la plus simple de générer un certificat est via l’api de votre fournisseur DNS. acme.sh supporte \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">énormément\u003C/a> de fournisseurs DNS.\u003C/p>\n\u003Ch3 id=\"definir-la-clé-api\">Definir la clé api\u003C/h3>\n\u003Cp>Suivez la \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">documentation\u003C/a> pour votre fournisseur DNS, généralement:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">export\u003C/span>\u003Cspan style=\"color:#E06C75\"> PROVIDER_Key\u003C/span>\u003Cspan style=\"color:#56B6C2\">=\u003C/span>\u003Cspan style=\"color:#98C379\">\"YOUR_API_KEY\"\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"émettre-le-certificat\">Émettre le certificat\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> --dns\u003C/span>\u003Cspan style=\"color:#98C379\"> dns_provider\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"utiliser-le-mode-standalone\">Utiliser le mode standalone\u003C/h2>\n\u003Cp>Si vous n’avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s’occupe de toutes les vérifications.\u003C/p>\n\u003Cp>Le port \u003Ccode>80\u003C/code> doit être disponible.\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> --standalone\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"exemples\">Exemples\u003C/h2>\n\u003Ch3 id=\"multi-domaines-standalone\">Multi domaines standalone\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> --standalone\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> www.domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> subdomain.domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"wildcard-domaine-dns\">Wildcard domaine DNS\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> '*.domain.tld'\u003C/span>\u003Cspan style=\"color:#D19A66\"> --dns\u003C/span>\u003Cspan style=\"color:#98C379\"> dns_provider\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"étapes-supplémentaires\">Étapes supplémentaires\u003C/h2>\n\u003Cp>Le certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\u003C/p>\n\u003Ch3 id=\"version-tls\">Version TLS\u003C/h3>\n\u003Cp>Limiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu \u003Ca href=\"https://caniuse.com/?search=tls%201.\">la différence de compatibilité de 5%\u003C/a> avec 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Utiliser le header \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a>.\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>Strict-Transport-Security: max-age=31536000; includeSubDomains\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"suite-cryptographique\">Suite cryptographique\u003C/h3>\n\u003Cp>Utiliser une suite cryptographique récente et robuste. C’est ici que mes connaissances deviennent limitées… J’ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\u003C/p>\n\u003Cp>J’avais basé ma première suite sur \u003Ca href=\"https://tls.imirhil.fr/ciphers\">cette liste\u003C/a>, en la comparant avec celle de la compatibilité (d’anciens ?) \u003Ca href=\"https://tls.imirhil.fr/suite\">navigateurs\u003C/a>.\u003C/p>\n\u003Cp>J’ai ensuite demandé à \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, le créateur de \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, ses conseils sur cette suite. Il m’a recommandé d’utiliser :\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Afin d’atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES256:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":584,"imagePaths":630,"frontmatter":631},[585,588,591,594,597,600,603,606,609,612,615,618,621,624,627],{"depth":150,"slug":586,"text":587},"attention","Attention",{"depth":150,"slug":589,"text":590},"prérequis","Prérequis",{"depth":154,"slug":592,"text":593},"installer-acmesh","Installer acme.sh",{"depth":154,"slug":595,"text":596},"changer-lauthorité-par-défaut","Changer l’authorité par défaut",{"depth":150,"slug":598,"text":599},"utiliser-lapi-dns","Utiliser l’api DNS",{"depth":154,"slug":601,"text":602},"definir-la-clé-api","Definir la clé api",{"depth":154,"slug":604,"text":605},"émettre-le-certificat","Émettre le certificat",{"depth":150,"slug":607,"text":608},"utiliser-le-mode-standalone","Utiliser le mode standalone",{"depth":150,"slug":610,"text":611},"exemples","Exemples",{"depth":154,"slug":613,"text":614},"multi-domaines-standalone","Multi domaines standalone",{"depth":154,"slug":616,"text":617},"wildcard-domaine-dns","Wildcard domaine DNS",{"depth":150,"slug":619,"text":620},"étapes-supplémentaires","Étapes supplémentaires",{"depth":154,"slug":622,"text":623},"version-tls","Version TLS",{"depth":154,"slug":625,"text":626},"hsts","HSTS",{"depth":154,"slug":628,"text":629},"suite-cryptographique","Suite cryptographique",[],{"title":573,"subtitle":574,"lang":16,"slug":570,"createdAt":170,"excerpt":632,"tags":633,"type":427},"La sécurité avec des courbes.",[576],"en-acme-sh-tls-cert",{"id":634,"data":636,"body":642,"filePath":643,"digest":644,"rendered":645},{"title":637,"subtitle":638,"lang":68,"tags":639,"type":467,"slug":634,"createdAt":641},"Strong TLS certificates with acme.sh","384-bit of https",[640],"security",["Date","2022-06-08T14:24:06.000Z"],"## Disclaimer\n\nI'm, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs. \nThis is why I've switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nYou can learn (far) more by reading [this topic](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) and its linked resources.\n\n## Requirements\n\n### Installing acme.sh\n\nFor automation and ease of use purposes, I'm using [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# for using standalone mode, you might have to install as sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changing default authority\n\nBy default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let's Encrypt because according to acme.sh, they're the only ones offering ECC capabilities.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Using your DNS api\n\nIf available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports [a lot](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) of DNS providers.\n\n### Define an api key\n\nFollow the [docs](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) for your DNS provider, usually:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Issue the cert\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Using standalone mode\n\nIf you don't have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\n\nPort `80` must be free.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Examples\n\n### Multi domains standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domain DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Next steps\n\nThe ECC certificate alone will not grant you a high/perfect score.\n\n### TLS version\n\nLimit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a [5% compatibility gap](https://caniuse.com/?search=tls%201.) with 1.2).\n\n### HSTS\n\nUse the [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/) header.\n\n```\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Cipher suite\n\nUse recent and strong ciphers. This is where my knowledge hits its limit… I'm having a really hard time understanding what to use and why.\n\nI've based my initial choices of ciphers on [this list](https://tls.imirhil.fr/ciphers), cross referencing it with (older?) [browser compatibility](https://tls.imirhil.fr/suite).\n\nI then asked [Aeris](https://twitter.com/aeris22), the creator of [tls.imirhil.fr](https://tls.imirhil.fr), about it and he advised me to use the following:\n\n```\nECDHE+AES:ECDHE+CHACHA20\n```\n\nIn order to achieve a perfect score, we can be a little more restrictive with:\n\n```\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/en/acme-sh-tls-cert.md","41577e8aee884f85",{"html":646,"metadata":647},"\u003Ch2 id=\"disclaimer\">Disclaimer\u003C/h2>\n\u003Cp>I’m, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs.\u003Cbr>\nThis is why I’ve switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>You can learn (far) more by reading \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">this topic\u003C/a> and its linked resources.\u003C/p>\n\u003Ch2 id=\"requirements\">Requirements\u003C/h2>\n\u003Ch3 id=\"installing-acmesh\">Installing acme.sh\u003C/h3>\n\u003Cp>For automation and ease of use purposes, I’m using \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\"># for using standalone mode, you might have to install as sudo\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">curl\u003C/span>\u003Cspan style=\"color:#98C379\"> https://get.acme.sh\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> | \u003C/span>\u003Cspan style=\"color:#61AFEF\">sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> -s\u003C/span>\u003Cspan style=\"color:#98C379\"> email=mail@domain.tld\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"changing-default-authority\">Changing default authority\u003C/h3>\n\u003Cp>By default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let’s Encrypt because according to acme.sh, they’re the only ones offering ECC capabilities.\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --set-default-ca\u003C/span>\u003Cspan style=\"color:#D19A66\"> --server\u003C/span>\u003Cspan style=\"color:#98C379\"> letsencrypt\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"using-your-dns-api\">Using your DNS api\u003C/h2>\n\u003Cp>If available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">a lot\u003C/a> of DNS providers.\u003C/p>\n\u003Ch3 id=\"define-an-api-key\">Define an api key\u003C/h3>\n\u003Cp>Follow the \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">docs\u003C/a> for your DNS provider, usually:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">export\u003C/span>\u003Cspan style=\"color:#E06C75\"> PROVIDER_Key\u003C/span>\u003Cspan style=\"color:#56B6C2\">=\u003C/span>\u003Cspan style=\"color:#98C379\">\"YOUR_API_KEY\"\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"issue-the-cert\">Issue the cert\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> --dns\u003C/span>\u003Cspan style=\"color:#98C379\"> dns_provider\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"using-standalone-mode\">Using standalone mode\u003C/h2>\n\u003Cp>If you don’t have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\u003C/p>\n\u003Cp>Port \u003Ccode>80\u003C/code> must be free.\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> --standalone\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"examples\">Examples\u003C/h2>\n\u003Ch3 id=\"multi-domains-standalone\">Multi domains standalone\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> --standalone\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> www.domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> subdomain.domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"wildcard-domain-dns\">Wildcard domain DNS\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"color:#D19A66\"> --issue\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> domain.tld\u003C/span>\u003Cspan style=\"color:#D19A66\"> -d\u003C/span>\u003Cspan style=\"color:#98C379\"> '*.domain.tld'\u003C/span>\u003Cspan style=\"color:#D19A66\"> --dns\u003C/span>\u003Cspan style=\"color:#98C379\"> dns_provider\u003C/span>\u003Cspan style=\"color:#D19A66\"> --keylength\u003C/span>\u003Cspan style=\"color:#98C379\"> ec-384\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"next-steps\">Next steps\u003C/h2>\n\u003Cp>The ECC certificate alone will not grant you a high/perfect score.\u003C/p>\n\u003Ch3 id=\"tls-version\">TLS version\u003C/h3>\n\u003Cp>Limit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a \u003Ca href=\"https://caniuse.com/?search=tls%201.\">5% compatibility gap\u003C/a> with 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Use the \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a> header.\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>Strict-Transport-Security: max-age=31536000; includeSubDomains\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"cipher-suite\">Cipher suite\u003C/h3>\n\u003Cp>Use recent and strong ciphers. This is where my knowledge hits its limit… I’m having a really hard time understanding what to use and why.\u003C/p>\n\u003Cp>I’ve based my initial choices of ciphers on \u003Ca href=\"https://tls.imirhil.fr/ciphers\">this list\u003C/a>, cross referencing it with (older?) \u003Ca href=\"https://tls.imirhil.fr/suite\">browser compatibility\u003C/a>.\u003C/p>\n\u003Cp>I then asked \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, the creator of \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, about it and he advised me to use the following:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>In order to achieve a perfect score, we can be a little more restrictive with:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>ECDHE+AES256:ECDHE+CHACHA20\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":648,"imagePaths":692,"frontmatter":693},[649,652,655,658,661,664,667,670,673,676,679,682,685,688,689],{"depth":150,"slug":650,"text":651},"disclaimer","Disclaimer",{"depth":150,"slug":653,"text":654},"requirements","Requirements",{"depth":154,"slug":656,"text":657},"installing-acmesh","Installing acme.sh",{"depth":154,"slug":659,"text":660},"changing-default-authority","Changing default authority",{"depth":150,"slug":662,"text":663},"using-your-dns-api","Using your DNS api",{"depth":154,"slug":665,"text":666},"define-an-api-key","Define an api key",{"depth":154,"slug":668,"text":669},"issue-the-cert","Issue the cert",{"depth":150,"slug":671,"text":672},"using-standalone-mode","Using standalone mode",{"depth":150,"slug":674,"text":675},"examples","Examples",{"depth":154,"slug":677,"text":678},"multi-domains-standalone","Multi domains standalone",{"depth":154,"slug":680,"text":681},"wildcard-domain-dns","Wildcard domain DNS",{"depth":150,"slug":683,"text":684},"next-steps","Next steps",{"depth":154,"slug":686,"text":687},"tls-version","TLS version",{"depth":154,"slug":625,"text":626},{"depth":154,"slug":690,"text":691},"cipher-suite","Cipher suite",[],{"title":637,"subtitle":638,"lang":68,"slug":634,"createdAt":170,"excerpt":694,"tags":695,"type":467},"Real cert have curves.",[640],"en-visited-links",{"id":696,"data":698,"body":470,"filePath":702,"digest":703,"rendered":704},{"title":699,"subtitle":209,"lang":68,"tags":700,"type":467,"slug":696,"createdAt":701,"draft":72},"Visited links and visuel aid",[18],["Date","2023-06-06T18:34:00.000Z"],"src/content/fragments/en/visited-links.md","cb7c11c12c25067e",{"html":705,"metadata":706},"\u003Cp>\u003Ca href=\"/en/snippets\">Go back to available snippets\u003C/a>\u003C/p>",{"headings":707,"imagePaths":708,"frontmatter":709},[],[],{"title":699,"subtitle":209,"lang":68,"draft":72,"slug":696,"excerpt":710,"tags":711,"type":467,"createdAt":712},"Petit hack CSS",[18],"2023-06-06T18:34:00.000Z","visited-links",{"id":713,"data":715,"body":721,"filePath":722,"digest":723,"rendered":724},{"title":716,"subtitle":717,"lang":16,"tags":718,"type":467,"slug":713,"createdAt":719,"draft":720},"Liens visités et indication visuelle","Comment différencier les liens déjà cliqués",[18],["Date","2023-06-06T18:34:00.000Z"],false,"## La théorie\n\nIl est possible sur le web d'appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu'un lien visité est violet.\n\nGénéralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L'information qu'un lien a déjà été visité ne semble pas indispensable à la navigation. C'est sûrement vrai, mais personnellement, je suis assez content d'avoir un rappel des pages que j'ai déjà consultées lorsque je navigue.\n\nUne information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J'ai alors cherché un moyen d'ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n'est certainement pas idéale, elle se rapproche plus d'une expérience, à priori inoffensive pour l'internaute.\n\n## La spécification\n\nQuand je me suis intéressé à ce qu'il était possible de faire avec les liens déjà visités, j'ai découvert qu'extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu'il était possible de récupérer l'historique de navigation d'un utilisateur grâce aux styles des liens visités. Le sélecteur `:visited` a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. [Plus d'informations dans cet article.](https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector)\n\n## La pratique\n\nQue faire alors, en terme de style, quand on ne peut changer que des couleurs ?\n\nD'après MDN, les propriétés suivantes sont modifiables :\n\n- `color`\n- `background-color`\n- `border-color` (et les propriétés détaillées associées),\n- `column-rule-color`\n- `outline-color`\n- `text-decoration-color`\n- `text-emphasis-color`\n- Les composantes de couleur liées aux attributs SVG `fill` et `stroke`.\n\nChanger la couleur d'un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\n\nEn revanche, il est possible de \" masquer \" un élément en modifiant sa couleur pour qu'elle corresponde à la couleur du fond de la page ou de l'élément parent. On pourrait ainsi imaginer masquer une `border` ou un `outline`.\n\nJ'ai personnellement choisi de faire différemment. J'ai décidé d'utiliser un pseudo-élément `::before` sur l'état non visité du lien puis de le masquer quand celui-ci devient visité.\n\n### Le code\n\n```css {1,4-6}\na {\n\tposition: relative;\n\ttext-decoration: none;\n}\na::before {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 0;\n\tinline-size: 2px;\n\tblock-size: 2px;\n\tborder-radius: 4px;\n\ttransform: translate(-6px, 0);\n\tbackground-color: grey;\n}\na:visited::before {\n\tbackground-color: white;\n}\n```\n\nCes règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\n\n### Accessibilité\n\nOn pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété `content` mais les lecteurs d'écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d'écrans annoncent déjà si un lien est visité avant de lire son intitulé.\n\n## Aller plus loin\n\nAfin de pousser l'expérience un peu plus loin, j'ai tenté d'utiliser des éléments plus explicites pour signifier l'état visité du lien. Bien qu'encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\n\nL'idée est d'avoir un `::before` et un `::after`, chacun contenant une icône en base 64 blanche en tant qu'image de fond. Quand le lien est non visité, le `::before` contient un fond coloré qui fait apparaître l'icône. Quand le lien passe en visité, le fond du `::before` devient blanc et celui du `::after` devient coloré, ce qui masque la première icône et affiche la deuxième.\n\nIl est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l'une sur l'autre.\n\n[Voir la démo sur codepen.](https://codepen.io/narduin/pen/VwVwmrO)","src/content/fragments/fr/visited-links.md","8398f96220bc4ff2",{"html":725,"metadata":726},"\u003Ch2 id=\"la-théorie\">La théorie\u003C/h2>\n\u003Cp>Il est possible sur le web d’appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu’un lien visité est violet.\u003C/p>\n\u003Cp>Généralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L’information qu’un lien a déjà été visité ne semble pas indispensable à la navigation. C’est sûrement vrai, mais personnellement, je suis assez content d’avoir un rappel des pages que j’ai déjà consultées lorsque je navigue.\u003C/p>\n\u003Cp>Une information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J’ai alors cherché un moyen d’ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n’est certainement pas idéale, elle se rapproche plus d’une expérience, à priori inoffensive pour l’internaute.\u003C/p>\n\u003Ch2 id=\"la-spécification\">La spécification\u003C/h2>\n\u003Cp>Quand je me suis intéressé à ce qu’il était possible de faire avec les liens déjà visités, j’ai découvert qu’extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu’il était possible de récupérer l’historique de navigation d’un utilisateur grâce aux styles des liens visités. Le sélecteur \u003Ccode>:visited\u003C/code> a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector\">Plus d’informations dans cet article.\u003C/a>\u003C/p>\n\u003Ch2 id=\"la-pratique\">La pratique\u003C/h2>\n\u003Cp>Que faire alors, en terme de style, quand on ne peut changer que des couleurs ?\u003C/p>\n\u003Cp>D’après MDN, les propriétés suivantes sont modifiables :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>background-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>border-color\u003C/code> (et les propriétés détaillées associées),\u003C/li>\n\u003Cli>\u003Ccode>column-rule-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>outline-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-decoration-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-emphasis-color\u003C/code>\u003C/li>\n\u003Cli>Les composantes de couleur liées aux attributs SVG \u003Ccode>fill\u003C/code> et \u003Ccode>stroke\u003C/code>.\u003C/li>\n\u003C/ul>\n\u003Cp>Changer la couleur d’un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\u003C/p>\n\u003Cp>En revanche, il est possible de ” masquer ” un élément en modifiant sa couleur pour qu’elle corresponde à la couleur du fond de la page ou de l’élément parent. On pourrait ainsi imaginer masquer une \u003Ccode>border\u003C/code> ou un \u003Ccode>outline\u003C/code>.\u003C/p>\n\u003Cp>J’ai personnellement choisi de faire différemment. J’ai décidé d’utiliser un pseudo-élément \u003Ccode>::before\u003C/code> sur l’état non visité du lien puis de le masquer quand celui-ci devient visité.\u003C/p>\n\u003Ch3 id=\"le-code\">Le code\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line highlighted\">\u003Cspan style=\"color:#E06C75\">a\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tposition: \u003C/span>\u003Cspan style=\"color:#D19A66\">relative\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttext-decoration: \u003C/span>\u003Cspan style=\"color:#D19A66\">none\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line highlighted\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line highlighted\">\u003Cspan style=\"color:#E06C75\">a\u003C/span>\u003Cspan style=\"color:#56B6C2\">::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line highlighted\">\u003Cspan style=\"color:#ABB2BF\">\tcontent: \u003C/span>\u003Cspan style=\"color:#98C379\">''\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tposition: \u003C/span>\u003Cspan style=\"color:#D19A66\">absolute\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttop: \u003C/span>\u003Cspan style=\"color:#D19A66\">50\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tleft: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tinline-size: \u003C/span>\u003Cspan style=\"color:#D19A66\">2\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tblock-size: \u003C/span>\u003Cspan style=\"color:#D19A66\">2\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tborder-radius: \u003C/span>\u003Cspan style=\"color:#D19A66\">4\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransform: \u003C/span>\u003Cspan style=\"color:#56B6C2\">translate\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">-6\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-color: grey;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">a\u003C/span>\u003Cspan style=\"color:#56B6C2\">:visited::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-color: \u003C/span>\u003Cspan style=\"color:#D19A66\">white\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Ces règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\u003C/p>\n\u003Ch3 id=\"accessibilité\">Accessibilité\u003C/h3>\n\u003Cp>On pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété \u003Ccode>content\u003C/code> mais les lecteurs d’écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d’écrans annoncent déjà si un lien est visité avant de lire son intitulé.\u003C/p>\n\u003Ch2 id=\"aller-plus-loin\">Aller plus loin\u003C/h2>\n\u003Cp>Afin de pousser l’expérience un peu plus loin, j’ai tenté d’utiliser des éléments plus explicites pour signifier l’état visité du lien. Bien qu’encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\u003C/p>\n\u003Cp>L’idée est d’avoir un \u003Ccode>::before\u003C/code> et un \u003Ccode>::after\u003C/code>, chacun contenant une icône en base 64 blanche en tant qu’image de fond. Quand le lien est non visité, le \u003Ccode>::before\u003C/code> contient un fond coloré qui fait apparaître l’icône. Quand le lien passe en visité, le fond du \u003Ccode>::before\u003C/code> devient blanc et celui du \u003Ccode>::after\u003C/code> devient coloré, ce qui masque la première icône et affiche la deuxième.\u003C/p>\n\u003Cp>Il est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l’une sur l’autre.\u003C/p>\n\u003Cp>\u003Ca href=\"https://codepen.io/narduin/pen/VwVwmrO\">Voir la démo sur codepen.\u003C/a>\u003C/p>",{"headings":727,"imagePaths":745,"frontmatter":746},[728,731,734,737,740,742],{"depth":150,"slug":729,"text":730},"la-théorie","La théorie",{"depth":150,"slug":732,"text":733},"la-spécification","La spécification",{"depth":150,"slug":735,"text":736},"la-pratique","La pratique",{"depth":154,"slug":738,"text":739},"le-code","Le code",{"depth":154,"slug":32,"text":741},"Accessibilité",{"depth":150,"slug":743,"text":744},"aller-plus-loin","Aller plus loin",[],{"title":716,"subtitle":717,"lang":16,"draft":720,"slug":713,"excerpt":710,"tags":747,"type":467,"createdAt":712},[18],"en-buttons",{"id":748,"data":750,"body":755,"filePath":756,"digest":757,"rendered":758},{"title":751,"subtitle":752,"lang":68,"tags":753,"type":467,"slug":748,"createdAt":754,"code":72,"draft":72},"Buttons hover","Simple, but nice.",[435],["Date","2020-10-08T09:00:00.000Z"],"## General rules\n\nAll the buttons use these styles as a “reset”:\n\n> Don't forget to prefix if necessary!\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Add an icon\n\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('~assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double shutter down\n\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Animated gradient\n\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Non destructive scale\n\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/en/buttons.md","ea9a5513a5a4cef4",{"html":759,"metadata":760},"\u003Ch2 id=\"general-rules\">General rules\u003C/h2>\n\u003Cp>All the buttons use these styles as a “reset”:\u003C/p>\n\u003Cblockquote>\n\u003Cp>Don’t forget to prefix if necessary!\u003C/p>\n\u003C/blockquote>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tmargin: \u003C/span>\u003Cspan style=\"color:#D19A66\">20\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#D19A66\"> 0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tpadding: \u003C/span>\u003Cspan style=\"color:#D19A66\">12\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#D19A66\"> 26\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tposition: \u003C/span>\u003Cspan style=\"color:#D19A66\">relative\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tdisplay: \u003C/span>\u003Cspan style=\"color:#D19A66\">inline-block\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\toverflow: \u003C/span>\u003Cspan style=\"color:#D19A66\">hidden\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tfont-size: \u003C/span>\u003Cspan style=\"color:#D19A66\">20\u003C/span>\u003Cspan style=\"color:#E06C75\">rem\u003C/span>\u003Cspan style=\"color:#ABB2BF\">; \u003C/span>\u003Cspan style=\"color:#7F848E;font-style:italic\">/* 20px */\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tline-height: \u003C/span>\u003Cspan style=\"color:#D19A66\">1.6\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttext-align: \u003C/span>\u003Cspan style=\"color:#D19A66\">center\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttext-decoration: \u003C/span>\u003Cspan style=\"color:#D19A66\">none\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tfont-weight: \u003C/span>\u003Cspan style=\"color:#D19A66\">bold\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcursor: \u003C/span>\u003Cspan style=\"color:#D19A66\">pointer\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tborder: \u003C/span>\u003Cspan style=\"color:#D19A66\">none\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tborder-radius: \u003C/span>\u003Cspan style=\"color:#D19A66\">2\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#56B6C2\">\t-moz-appearance\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#D19A66\">none\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#56B6C2\">\t-webkit-appearance\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#D19A66\">none\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcolor: \u003C/span>\u003Cspan style=\"color:#D19A66\">white\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-color: hotpink;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition: background-color \u003C/span>\u003Cspan style=\"color:#D19A66\">0.3\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#D19A66\"> ease\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"add-an-icon\">Add an icon\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-color: hotpink;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#56B6C2\">::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcontent: \u003C/span>\u003Cspan style=\"color:#56B6C2\">url\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#98C379\">'~assets/svg/arrow-right-white.svg'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tposition: \u003C/span>\u003Cspan style=\"color:#D19A66\">absolute\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\twidth: \u003C/span>\u003Cspan style=\"color:#D19A66\">20\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttop: \u003C/span>\u003Cspan style=\"color:#D19A66\">50\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tright: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransform: \u003C/span>\u003Cspan style=\"color:#56B6C2\">translate\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">40\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">-50\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition: transform \u003C/span>\u003Cspan style=\"color:#D19A66\">ease\u003C/span>\u003Cspan style=\"color:#D19A66\"> 0.3\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-color: darkorchid;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransform: \u003C/span>\u003Cspan style=\"color:#56B6C2\">translate\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">-10\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">-50\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> >\u003C/span>\u003Cspan style=\"color:#E06C75\"> span\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tdisplay: \u003C/span>\u003Cspan style=\"color:#D19A66\">inline-block\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\twidth: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\theight: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition: transform \u003C/span>\u003Cspan style=\"color:#D19A66\">0.3\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#D19A66\"> ease\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> >\u003C/span>\u003Cspan style=\"color:#E06C75\"> span\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> >\u003C/span>\u003Cspan style=\"color:#E06C75\"> span\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransform: \u003C/span>\u003Cspan style=\"color:#56B6C2\">translateX\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">-10\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"double-shutter-down\">Double shutter down\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tborder: \u003C/span>\u003Cspan style=\"color:#D19A66\">2\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#D19A66\"> solid\u003C/span>\u003Cspan style=\"color:#D19A66\"> #10113a\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcolor: \u003C/span>\u003Cspan style=\"color:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-color: \u003C/span>\u003Cspan style=\"color:#D19A66\">transparent\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition: \u003C/span>\u003Cspan style=\"color:#D19A66\">color\u003C/span>\u003Cspan style=\"color:#D19A66\"> 0.3\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#D19A66\"> ease\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcolor: \u003C/span>\u003Cspan style=\"color:#D19A66\">white\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground: hotpink;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground: darkorchid;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcontent: \u003C/span>\u003Cspan style=\"color:#98C379\">''\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tposition: \u003C/span>\u003Cspan style=\"color:#D19A66\">absolute\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\theight: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\twidth: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbottom: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tleft: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tz-index: \u003C/span>\u003Cspan style=\"color:#D19A66\">-1\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition: transform \u003C/span>\u003Cspan style=\"color:#D19A66\">0.3\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition-timing-function: \u003C/span>\u003Cspan style=\"color:#D19A66\">ease\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition-timing-function: \u003C/span>\u003Cspan style=\"color:#56B6C2\">cubic-bezier\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">0.75\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">0.125\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">1\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus::before\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransform: \u003C/span>\u003Cspan style=\"color:#56B6C2\">translateY\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition-delay: \u003C/span>\u003Cspan style=\"color:#D19A66\">0.175\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"animated-gradient\">Animated gradient\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground: \u003C/span>\u003Cspan style=\"color:#56B6C2\">linear-gradient\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">-45\u003C/span>\u003Cspan style=\"color:#E06C75\">deg\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">#ee7752\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">#e73c7e\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">#23a6d5\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#D19A66\">#23d5ab\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-size: \u003C/span>\u003Cspan style=\"color:#D19A66\">400\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#D19A66\"> 400\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-position: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#D19A66\"> 50\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tanimation: GradientReverse \u003C/span>\u003Cspan style=\"color:#D19A66\">0.5\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#D19A66\"> ease\u003C/span>\u003Cspan style=\"color:#D19A66\"> 1\u003C/span>\u003Cspan style=\"color:#D19A66\"> normal\u003C/span>\u003Cspan style=\"color:#D19A66\"> forwards\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tanimation: Gradient \u003C/span>\u003Cspan style=\"color:#D19A66\">0.5\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#D19A66\"> ease\u003C/span>\u003Cspan style=\"color:#D19A66\"> 1\u003C/span>\u003Cspan style=\"color:#D19A66\"> normal\u003C/span>\u003Cspan style=\"color:#D19A66\"> forwards\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">@keyframes\u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\"> Gradient\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t0% {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t\tbackground-position: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#D19A66\"> 50\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t100% {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t\tbackground-position: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#D19A66\"> 100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">@keyframes\u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\"> GradientReverse\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t0% {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t\tbackground-position: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#D19A66\"> 100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t100% {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t\tbackground-position: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#D19A66\"> 50\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"non-destructive-scale\">Non destructive scale\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\toverflow: \u003C/span>\u003Cspan style=\"color:#D19A66\">visible\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcolor: \u003C/span>\u003Cspan style=\"color:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbackground-color: \u003C/span>\u003Cspan style=\"color:#D19A66\">transparent\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"color:#56B6C2\">::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tcontent: \u003C/span>\u003Cspan style=\"color:#98C379\">''\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tposition: \u003C/span>\u003Cspan style=\"color:#D19A66\">absolute\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttop: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tleft: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tbottom: \u003C/span>\u003Cspan style=\"color:#D19A66\">0\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\twidth: \u003C/span>\u003Cspan style=\"color:#D19A66\">100\u003C/span>\u003Cspan style=\"color:#E06C75\">%\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tborder: \u003C/span>\u003Cspan style=\"color:#D19A66\">2\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#D19A66\"> solid\u003C/span>\u003Cspan style=\"color:#D19A66\"> #10113a\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\tborder-radius: \u003C/span>\u003Cspan style=\"color:#D19A66\">2\u003C/span>\u003Cspan style=\"color:#E06C75\">px\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransition: transform \u003C/span>\u003Cspan style=\"color:#D19A66\">0.3\u003C/span>\u003Cspan style=\"color:#E06C75\">s\u003C/span>\u003Cspan style=\"color:#D19A66\"> ease\u003C/span>\u003Cspan style=\"color:#ABB2BF\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"color:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"color:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\ttransform: \u003C/span>\u003Cspan style=\"color:#56B6C2\">scale\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#D19A66\">1.1\u003C/span>\u003Cspan style=\"color:#ABB2BF\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":761,"imagePaths":777,"frontmatter":778},[762,765,768,771,774],{"depth":150,"slug":763,"text":764},"general-rules","General rules",{"depth":150,"slug":766,"text":767},"add-an-icon","Add an icon",{"depth":150,"slug":769,"text":770},"double-shutter-down","Double shutter down",{"depth":150,"slug":772,"text":773},"animated-gradient","Animated gradient",{"depth":150,"slug":775,"text":776},"non-destructive-scale","Non destructive scale",[],{"title":751,"subtitle":752,"lang":68,"slug":748,"draft":72,"excerpt":779,"tags":780,"code":72,"type":467,"createdAt":781},"Easy to grab and use hover effects.",[435],"2020-10-08T09:00:00.000Z","en-array-vs-array",{"id":782,"data":784,"body":789,"filePath":790,"digest":791,"rendered":792},{"title":785,"subtitle":786,"lang":68,"tags":787,"type":467,"slug":782,"createdAt":788},"Filter an array against another array","Array vs Array.",[490],["Date","2022-06-08T14:24:06.000Z"],"## Context\n\nFor a project, I had to come up with a way to filter an array of objects based on another array of strings.\n\nIn other words, I needed to include every object which `user` property was found in the second array.\n\nHere is an example:\n\n```javascript\nconst skills = [\n\t{\n\t\tname: 'Be awesome',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Great jokes',\n\t\tuser: 'Jacques'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Beatriz'\n\t}\n]\n\nconst selectedUsers = ['Jean', 'Beatriz']\n```\n\nI thought it would be pretty easy but I guess I'm not familiar enough with javascript 😬\n\n## My solution\n\nAfter a bit of thinking, I came up with the following statement:\n\n> I need to filter the skills based on which users are selected. So I need to loop over the `selectedUsers` array and filter the skills according to their `user` value.\n\nAfter a bit more trials and errors, this is the code I ended up using in a `computed property`:\n\n```javascript\n// index.vue\nconst filteredSkills = selectedUsers.map((user) => {\n\treturn skills.filter((skill) => {\n\t\treturn skill.user === user\n\t})\n})\n```\n\nI used `map()` in order to loop on the second array and used its string value to only include the corresponding skills with `filter()`.\n\nI'm pretty sure there is a better way to do it though…","src/content/fragments/en/array-vs-array.md","c63ba57b1049cf4c",{"html":793,"metadata":794},"\u003Ch2 id=\"context\">Context\u003C/h2>\n\u003Cp>For a project, I had to come up with a way to filter an array of objects based on another array of strings.\u003C/p>\n\u003Cp>In other words, I needed to include every object which \u003Ccode>user\u003C/code> property was found in the second array.\u003C/p>\n\u003Cp>Here is an example:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">const\u003C/span>\u003Cspan style=\"color:#E5C07B\"> skills\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tname\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Be awesome'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tuser\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Jean'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tname\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Great jokes'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tuser\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Jacques'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tname\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tuser\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Jean'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tname\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tuser\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Beatriz'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">const\u003C/span>\u003Cspan style=\"color:#E5C07B\"> selectedUsers\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> [\u003C/span>\u003Cspan style=\"color:#98C379\">'Jean'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#98C379\">'Beatriz'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">]\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>I thought it would be pretty easy but I guess I’m not familiar enough with javascript 😬\u003C/p>\n\u003Ch2 id=\"my-solution\">My solution\u003C/h2>\n\u003Cp>After a bit of thinking, I came up with the following statement:\u003C/p>\n\u003Cblockquote>\n\u003Cp>I need to filter the skills based on which users are selected. So I need to loop over the \u003Ccode>selectedUsers\u003C/code> array and filter the skills according to their \u003Ccode>user\u003C/code> value.\u003C/p>\n\u003C/blockquote>\n\u003Cp>After a bit more trials and errors, this is the code I ended up using in a \u003Ccode>computed property\u003C/code>:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">const\u003C/span>\u003Cspan style=\"color:#E5C07B\"> filteredSkills\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#E5C07B\"> selectedUsers\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">map\u003C/span>\u003Cspan style=\"color:#ABB2BF\">((\u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\">user\u003C/span>\u003Cspan style=\"color:#ABB2BF\">) \u003C/span>\u003Cspan style=\"color:#C678DD\">=>\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">\treturn\u003C/span>\u003Cspan style=\"color:#E5C07B\"> skills\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">filter\u003C/span>\u003Cspan style=\"color:#ABB2BF\">((\u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\">skill\u003C/span>\u003Cspan style=\"color:#ABB2BF\">) \u003C/span>\u003Cspan style=\"color:#C678DD\">=>\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">\t\treturn\u003C/span>\u003Cspan style=\"color:#E5C07B\"> skill\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E06C75\">user\u003C/span>\u003Cspan style=\"color:#56B6C2\"> ===\u003C/span>\u003Cspan style=\"color:#E06C75\"> user\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t})\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">})\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>I used \u003Ccode>map()\u003C/code> in order to loop on the second array and used its string value to only include the corresponding skills with \u003Ccode>filter()\u003C/code>.\u003C/p>\n\u003Cp>I’m pretty sure there is a better way to do it though…\u003C/p>",{"headings":795,"imagePaths":802,"frontmatter":803},[796,799],{"depth":150,"slug":797,"text":798},"context","Context",{"depth":150,"slug":800,"text":801},"my-solution","My solution",[],{"title":785,"subtitle":786,"lang":68,"slug":782,"createdAt":170,"excerpt":804,"tags":805,"type":467},"My peak javascript",[490],"nuxt-graphql-static",{"id":806,"data":808,"body":814,"filePath":815,"digest":816,"rendered":817},{"title":809,"subtitle":810,"lang":16,"tags":811,"type":427,"slug":806,"createdAt":812,"updatedAt":813},"Site statique et requêtes GraphQL avec Nuxt.js","Le client graphql est roi.",[490],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## Le problème\n\nJe me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (nouvel onglet)').\nAprès quelques recherches, voici [le bug constaté par quelqu'un d'autre](https://github.com/nuxt-community/apollo-module/issues/339 'Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)') sur github.\n\nIl semblerait que le module en l'état ne gère pas correctement la génération statique avec `nuxt generate`.\n\nJe trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les `\u003Cnuxt-link>` ne fonctionnait pas.\n\n## La solution 🙌\n\nHeureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\n\n[Nuxt graphql request à la rescousse !](https://github.com/gomah/nuxt-graphql-request 'Dépôt github du module (nouvel onglet)')\n\n### La conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### La requête\n\nLa meilleure méthode à ce jour est d'utiliser `asyncData` dans les pages et `fetch` dans les composants. Utiliser `fetch` dans les pages ne fonctionne pas bien du tout avec `nuxt generate`.\n\nJ'installe également le paquet `graphql-tag` (uniquement en `devDependencies`) afin de pouvoir importer directement des fichiers `.gql`\n\nExemple de fichier :\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Dans une page\n\n```javascript\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n async asyncData({ $graphql }) {\n const data = await $graphql.default.request(homepageQuery)\n return { data }\n },\n}\n\u003C/script>\n```\n\n#### Dans un composant\n\nIl est plus prudent d'attendre que `fetch` ait reçu une réponse avant d'afficher quoi que ce soit. On peut utiliser `$fetchState` afin d'être tranquille ([documentation](https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation sur la méthode fetch (nouvel onglet)')).\n\n```javascript\n// Header.vue\n\u003Ctemplate>\n \u003Cheader v-if=\"!$fetchState.pending\">\n …\n \u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n data() {\n return {\n data: {},\n }\n },\n async fetch() {\n try {\n const data = await this.$graphql.default.request(headerQuery)\n this.data = data\n } catch (error) {\n console.error(JSON.stringify(error, undefined, 2))\n }\n },\n}\n\u003C/script>\n```\n\n### Les options\n\nPour passer des options à la requête, par exemple pour une version multilingue avec [nuxt/i18n](https://i18n.nuxtjs.org/ 'Documentation de nuxt i18n (nouvel onglet)') et/ou un paramètre d'url dans le cadre d'une page dynamique :\n\n```javascript\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n async asyncData({ $graphql, app, params }) {\n const locale = app.i18n.localeProperties.iso\n const data = await $graphql.default.request(articleQuery, {\n code: locale,\n slug: params.slug,\n })\n return { data }\n },\n}\n\u003C/script>\n```","src/content/fragments/fr/nuxt-graphql-static.md","73b6cc6b4fed04f5",{"html":818,"metadata":819},"\u003Ch2 id=\"le-problème\">Le problème\u003C/h2>\n\u003Cp>Je me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (nouvel onglet)\">nuxt apollo\u003C/a>.\nAprès quelques recherches, voici \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)\">le bug constaté par quelqu’un d’autre\u003C/a> sur github.\u003C/p>\n\u003Cp>Il semblerait que le module en l’état ne gère pas correctement la génération statique avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>Je trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les \u003Ccode><nuxt-link>\u003C/code> ne fonctionnait pas.\u003C/p>\n\u003Ch2 id=\"la-solution\">La solution 🙌\u003C/h2>\n\u003Cp>Heureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\" title=\"Dépôt github du module (nouvel onglet)\">Nuxt graphql request à la rescousse !\u003C/a>\u003C/p>\n\u003Ch3 id=\"la-conf\">La conf\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// nuxt.config.js\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">buildModules\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#98C379\"> 'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> clients\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\"> default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> endpoint\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> options\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> headers\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> authorization\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">},\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"la-requête\">La requête\u003C/h3>\n\u003Cp>La meilleure méthode à ce jour est d’utiliser \u003Ccode>asyncData\u003C/code> dans les pages et \u003Ccode>fetch\u003C/code> dans les composants. Utiliser \u003Ccode>fetch\u003C/code> dans les pages ne fonctionne pas bien du tout avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>J’installe également le paquet \u003Ccode>graphql-tag\u003C/code> (uniquement en \u003Ccode>devDependencies\u003C/code>) afin de pouvoir importer directement des fichiers \u003Ccode>.gql\u003C/code>\u003C/p>\n\u003Cp>Exemple de fichier :\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"graphql\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\"># homepage.gql\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">query\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\thomepage\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\ttitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tsubtitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\thero\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\t\tid\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\t\talt\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"dans-une-page\">Dans une page\u003C/h4>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">import homepageQuery from '~/graphql/queries/singles/homepage'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">export default \u003C/span>\u003Cspan style=\"color:#C678DD\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> async\u003C/span>\u003Cspan style=\"color:#61AFEF\"> asyncData\u003C/span>\u003Cspan style=\"color:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"color:#E06C75\">$graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> const \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#C678DD\"> await\u003C/span>\u003Cspan style=\"color:#E5C07B\"> $graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">request\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#E06C75\">homepageQuery\u003C/span>\u003Cspan style=\"color:#ABB2BF\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> return { \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"dans-un-composant\">Dans un composant\u003C/h4>\n\u003Cp>Il est plus prudent d’attendre que \u003Ccode>fetch\u003C/code> ait reçu une réponse avant d’afficher quoi que ce soit. On peut utiliser \u003Ccode>$fetchState\u003C/code> afin d’être tranquille (\u003Ca href=\"https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation sur la méthode fetch (nouvel onglet)\">documentation\u003C/a>).\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// Header.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">template\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> <\u003C/span>\u003Cspan style=\"color:#E06C75\">header\u003C/span>\u003Cspan style=\"color:#D19A66;font-style:italic\"> v-if\u003C/span>\u003Cspan style=\"color:#56B6C2\">=\u003C/span>\u003Cspan style=\"color:#98C379\">\"!$fetchState.pending\"\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> …\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> </\u003C/span>\u003Cspan style=\"color:#E06C75\">header\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">template\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">import headerQuery from '~/graphql/queries/singles/header'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">export default \u003C/span>\u003Cspan style=\"color:#C678DD\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\"> data\u003C/span>\u003Cspan style=\"color:#ABB2BF\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> return {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> data\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> async\u003C/span>\u003Cspan style=\"color:#61AFEF\"> fetch\u003C/span>\u003Cspan style=\"color:#ABB2BF\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> try {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\"> const\u003C/span>\u003Cspan style=\"color:#E5C07B\"> data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#C678DD\"> await\u003C/span>\u003Cspan style=\"color:#E5C07B\"> this\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">request\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#E06C75\">headerQuery\u003C/span>\u003Cspan style=\"color:#ABB2BF\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E5C07B\"> this\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#E06C75\"> data\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> } catch (error) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> console.\u003C/span>\u003Cspan style=\"color:#61AFEF\">error\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(JSON.stringify(\u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\">error\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\">undefined\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, 2))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\"> }\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"les-options\">Les options\u003C/h3>\n\u003Cp>Pour passer des options à la requête, par exemple pour une version multilingue avec \u003Ca href=\"https://i18n.nuxtjs.org/\" title=\"Documentation de nuxt i18n (nouvel onglet)\">nuxt/i18n\u003C/a> et/ou un paramètre d’url dans le cadre d’une page dynamique :\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// _slug.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">import articleQuery from '~/graphql/queries/articles'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">export default \u003C/span>\u003Cspan style=\"color:#C678DD\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> async\u003C/span>\u003Cspan style=\"color:#61AFEF\"> asyncData\u003C/span>\u003Cspan style=\"color:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"color:#E06C75\">$graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#E06C75\">app\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#E06C75\">params\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> const \u003C/span>\u003Cspan style=\"color:#E06C75\">locale\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#E5C07B\"> app\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">i18n\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">localeProperties\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E06C75\">iso\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> const \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#C678DD\"> await\u003C/span>\u003Cspan style=\"color:#E5C07B\"> $graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">request\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#E06C75\">articleQuery\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> code\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#E06C75\">locale\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> slug\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#E5C07B\">params\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E06C75\">slug\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> })\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> return { \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":820,"imagePaths":843,"frontmatter":844},[821,824,827,830,833,837,840],{"depth":150,"slug":822,"text":823},"le-problème","Le problème",{"depth":150,"slug":825,"text":826},"la-solution","La solution 🙌",{"depth":154,"slug":828,"text":829},"la-conf","La conf",{"depth":154,"slug":831,"text":832},"la-requête","La requête",{"depth":834,"slug":835,"text":836},4,"dans-une-page","Dans une page",{"depth":834,"slug":838,"text":839},"dans-un-composant","Dans un composant",{"depth":154,"slug":841,"text":842},"les-options","Les options",[],{"title":809,"subtitle":810,"lang":16,"slug":806,"createdAt":170,"updatedAt":845,"excerpt":846,"tags":847,"type":427},"2022-09-08T13:43:33.000Z","Quand le module gql le plus utilisé ne fonctionne pas…",[490],"en-nuxt-graphql-static",{"id":848,"data":850,"body":856,"filePath":857,"digest":858,"rendered":859},{"title":851,"subtitle":852,"lang":68,"tags":853,"type":467,"slug":848,"createdAt":854,"updatedAt":855},"Static website and GraphQL queries with Nuxt.js","Graphql client is king.",[490],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## The problem\n\nI encountered a nasty bug while using static generation with Nuxt and [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (new tab)') client.\nI found [the issue](https://github.com/nuxt-community/apollo-module/issues/339 'Github issue on nuxt/apollo repository (new tab)') already reported on github.\n\nIt seems the module doesn't handle static generation correctly with `nuxt generate`.\n\nI could find request to my local API url after the static generation. Moreover, it also seemed like `\u003Cnuxt-link>` navigation was broken.\n\n## The solution 🙌\n\nFortunately, there is another Nuxt module that handles GraphQL requests!\n\n[Nuxt graphql request to the rescue!](https://github.com/gomah/nuxt-graphql-request)\n\n### The conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### The request\n\nThe best approach so far is to use `asyncData` in pages and `fetch` in components. Using `fetch` in pages does not work well at all with `nuxt generate`.\n\nI also install the `graphql-tag` package (only in `devDependencies`) to be able to import directly `.gql` files.\n\nQuery example:\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Inside a page\n\n```javascript\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n async asyncData({ $graphql }) {\n const data = await $graphql.default.request(homepageQuery)\n return { data }\n },\n}\n\u003C/script>\n```\n\n#### Inside a component\n\nIt is safer to wait until `fetch` has received a response before displaying anything. You can use `$fetchState` to be sure ([documentation](https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation on the fetch hook (new tab)')).\n\n```javascript\n// Header.vue\n\u003Ctemplate>\n \u003Cheader v-if=\"!$fetchState.pending\">\n …\n \u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n data() {\n return {\n data: {},\n }\n },\n async fetch() {\n try {\n const data = await this.$graphql.default.request(headerQuery)\n this.data = data\n } catch (error) {\n console.error(JSON.stringify(error, undefined, 2))\n }\n },\n}\n\u003C/script>\n```\n\n### Options\n\nTo pass options to the request, for example for a multilingual version with [nuxt/i18n](https://i18n.nuxtjs.org/) and/or a url parameter in a dynamic page:\n\n```javascript\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n async asyncData({ $graphql, app, params }) {\n const locale = app.i18n.localeProperties.iso\n const data = await $graphql.default.request(articleQuery, {\n code: locale,\n slug: params.slug,\n })\n return { data }\n },\n}\n\u003C/script>\n```","src/content/fragments/en/nuxt-graphql-static.md","181e8091294eb858",{"html":860,"metadata":861},"\u003Ch2 id=\"the-problem\">The problem\u003C/h2>\n\u003Cp>I encountered a nasty bug while using static generation with Nuxt and \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (new tab)\">nuxt apollo\u003C/a> client.\nI found \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Github issue on nuxt/apollo repository (new tab)\">the issue\u003C/a> already reported on github.\u003C/p>\n\u003Cp>It seems the module doesn’t handle static generation correctly with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I could find request to my local API url after the static generation. Moreover, it also seemed like \u003Ccode><nuxt-link>\u003C/code> navigation was broken.\u003C/p>\n\u003Ch2 id=\"the-solution\">The solution 🙌\u003C/h2>\n\u003Cp>Fortunately, there is another Nuxt module that handles GraphQL requests!\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\">Nuxt graphql request to the rescue!\u003C/a>\u003C/p>\n\u003Ch3 id=\"the-conf\">The conf\u003C/h3>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// nuxt.config.js\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">buildModules\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#98C379\"> 'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> clients\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\"> default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> endpoint\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> options\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> headers\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> authorization\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#98C379\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">},\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"the-request\">The request\u003C/h3>\n\u003Cp>The best approach so far is to use \u003Ccode>asyncData\u003C/code> in pages and \u003Ccode>fetch\u003C/code> in components. Using \u003Ccode>fetch\u003C/code> in pages does not work well at all with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I also install the \u003Ccode>graphql-tag\u003C/code> package (only in \u003Ccode>devDependencies\u003C/code>) to be able to import directly \u003Ccode>.gql\u003C/code> files.\u003C/p>\n\u003Cp>Query example:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"graphql\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\"># homepage.gql\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">query\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\thomepage\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\ttitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\tsubtitle\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\thero\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\t\tid\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\">\t\t\talt\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">\t}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"inside-a-page\">Inside a page\u003C/h4>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// index.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">import homepageQuery from '~/graphql/queries/singles/homepage'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">export default \u003C/span>\u003Cspan style=\"color:#C678DD\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> async\u003C/span>\u003Cspan style=\"color:#61AFEF\"> asyncData\u003C/span>\u003Cspan style=\"color:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"color:#E06C75\">$graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> const \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#C678DD\"> await\u003C/span>\u003Cspan style=\"color:#E5C07B\"> $graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">request\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#E06C75\">homepageQuery\u003C/span>\u003Cspan style=\"color:#ABB2BF\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> return { \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch4 id=\"inside-a-component\">Inside a component\u003C/h4>\n\u003Cp>It is safer to wait until \u003Ccode>fetch\u003C/code> has received a response before displaying anything. You can use \u003Ccode>$fetchState\u003C/code> to be sure (\u003Ca href=\"https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation on the fetch hook (new tab)\">documentation\u003C/a>).\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// Header.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">template\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> <\u003C/span>\u003Cspan style=\"color:#E06C75\">header\u003C/span>\u003Cspan style=\"color:#D19A66;font-style:italic\"> v-if\u003C/span>\u003Cspan style=\"color:#56B6C2\">=\u003C/span>\u003Cspan style=\"color:#98C379\">\"!$fetchState.pending\"\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> …\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> </\u003C/span>\u003Cspan style=\"color:#E06C75\">header\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">template\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">import headerQuery from '~/graphql/queries/singles/header'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">export default \u003C/span>\u003Cspan style=\"color:#C678DD\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#61AFEF\"> data\u003C/span>\u003Cspan style=\"color:#ABB2BF\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> return {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> data\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: {},\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> async\u003C/span>\u003Cspan style=\"color:#61AFEF\"> fetch\u003C/span>\u003Cspan style=\"color:#ABB2BF\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> try {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\"> const\u003C/span>\u003Cspan style=\"color:#E5C07B\"> data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#C678DD\"> await\u003C/span>\u003Cspan style=\"color:#E5C07B\"> this\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">request\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#E06C75\">headerQuery\u003C/span>\u003Cspan style=\"color:#ABB2BF\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E5C07B\"> this\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#E06C75\"> data\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> } catch (error) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> console.\u003C/span>\u003Cspan style=\"color:#61AFEF\">error\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(JSON.stringify(\u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\">error\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#E06C75;font-style:italic\">undefined\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, 2))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\"> }\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"options\">Options\u003C/h3>\n\u003Cp>To pass options to the request, for example for a multilingual version with \u003Ca href=\"https://i18n.nuxtjs.org/\">nuxt/i18n\u003C/a> and/or a url parameter in a dynamic page:\u003C/p>\n\u003Cpre class=\"astro-code one-dark-pro\" style=\"background-color:#282c34;color:#abb2bf; overflow-x: auto;\" tabindex=\"0\" data-language=\"javascript\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#7F848E;font-style:italic\">// _slug.vue\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"><\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">import articleQuery from '~/graphql/queries/articles'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\">export default \u003C/span>\u003Cspan style=\"color:#C678DD\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> async\u003C/span>\u003Cspan style=\"color:#61AFEF\"> asyncData\u003C/span>\u003Cspan style=\"color:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"color:#E06C75\">$graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#E06C75\">app\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, \u003C/span>\u003Cspan style=\"color:#E06C75\">params\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> const \u003C/span>\u003Cspan style=\"color:#E06C75\">locale\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#E5C07B\"> app\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">i18n\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">localeProperties\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E06C75\">iso\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> const \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#56B6C2\"> =\u003C/span>\u003Cspan style=\"color:#C678DD\"> await\u003C/span>\u003Cspan style=\"color:#E5C07B\"> $graphql\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E5C07B\">default\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#61AFEF\">request\u003C/span>\u003Cspan style=\"color:#ABB2BF\">(\u003C/span>\u003Cspan style=\"color:#E06C75\">articleQuery\u003C/span>\u003Cspan style=\"color:#ABB2BF\">, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> code\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#E06C75\">locale\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E06C75\"> slug\u003C/span>\u003Cspan style=\"color:#ABB2BF\">: \u003C/span>\u003Cspan style=\"color:#E5C07B\">params\u003C/span>\u003Cspan style=\"color:#ABB2BF\">.\u003C/span>\u003Cspan style=\"color:#E06C75\">slug\u003C/span>\u003Cspan style=\"color:#ABB2BF\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> })\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> return { \u003C/span>\u003Cspan style=\"color:#E06C75\">data\u003C/span>\u003Cspan style=\"color:#ABB2BF\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#C678DD\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#ABB2BF\"></\u003C/span>\u003Cspan style=\"color:#E06C75\">script\u003C/span>\u003Cspan style=\"color:#ABB2BF\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>",{"headings":862,"imagePaths":884,"frontmatter":885},[863,866,869,872,875,878,881],{"depth":150,"slug":864,"text":865},"the-problem","The problem",{"depth":150,"slug":867,"text":868},"the-solution","The solution 🙌",{"depth":154,"slug":870,"text":871},"the-conf","The conf",{"depth":154,"slug":873,"text":874},"the-request","The request",{"depth":834,"slug":876,"text":877},"inside-a-page","Inside a page",{"depth":834,"slug":879,"text":880},"inside-a-component","Inside a component",{"depth":154,"slug":882,"text":883},"options","Options",[],{"title":851,"subtitle":852,"lang":68,"slug":848,"createdAt":170,"updatedAt":845,"excerpt":886,"tags":887,"type":467},"When the most used gql module doesn't work…",[490],"veille",["Map",269,890],{"id":269,"data":891,"body":893,"filePath":894,"digest":895,"rendered":896},{"lang":16,"title":269,"updatedAt":892},["Date","2023-04-20T17:12:06.000Z"],"- [mmm.page](https://build.mmm.page/) - Éditeur de sites web très simples, en glisser-déposer, pour n'importe quoi.\n- [Color.io](https://www.color.io/) - Éditeur photo en ligne.\n- [Addy's toolkit](https://toolkit.addy.codes/) - Outils et ressources pour les designers et développeurs sites web.\n- [L’accessibilité n’est pas une variable d’ajustement](https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/) — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n > L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\n- [3D en CSS (english)](https://garden.bradwoods.io/notes/css/3d) – Explications et exemples des propriétés 3D en CSS.\n- [Climat : Comment ne pas déprimer ?](https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html) – Podcast.\n- [Fable (english)](https://fable.app) – Application de motion design.\n- [Rive (english)](https://rive.app) – Application de motion design.\n- [Cake Desk](https://cakedesk.app/) – Application de facturation.\n- [Ombre fluide en CSS](https://shadows.brumm.af/) – Générateur.\n- [Smol CSS](https://smolcss.dev/) – Collection de fragments CSS.\n- [Ajustement optique](https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/) (english) – Aligner visuellement plutôt que techniquement.\n- [Datawrapper](https://blog.datawrapper.de/category/datavis-dos-and-donts/) (english) – Conseils pour montrer de la donnée.\n- [Assistivlabs](https://assistivlabs.com/) (english) – Service de test des technologies d'assistance (browserstack mais pour l'accessibilité).\n- [Les caractères fantaisistes et l'accessibilité](https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/) – Explications et exemples de l'enfer que sont les caractères Unicode pour les technologies d'assistance.\n- [Créer un champ `time` sur le web](https://adamsilver.io/blog/designing-a-time-input-backed-by-research/) (english) – Article.\n- [La cascade](https://la-cascade.io) – Collection d'articles sur le CSS.\n- [Tabby](https://tabby.sh) (english) – An alternative terminal app.\n- [Newglyph](https://newglyph.com/) – Fonderie indépendante.\n- [\u003Cspan lang=\"en\">Headless UI\u003C/span>](https://headlessui.com/vue/dialog) (english) – Librairie de composants vue et react.\n- [Vie privée sexy](https://privacy.sexy) (english) – Outils de confidentialité pour windows et macos.\n- [33 concepts JavaScript](https://github.com/leonardomso/33-js-concepts) (english) – Articles.\n- [Formbricks](https://formbricks.com/) (english) – Alternative open source à google form/typeform.\n- [Animations de chargement SVG](https://github.com/n3r4zzurr0/svg-spinners) – Collection.\n- [a11yphant](https://a11yphant.com/) (english) – Challenges de code pour apprendre l'accessibilité.\n- [CSS moderne](https://moderncss.dev/) (english) – Fragments CSS.\n- [Conteneur moderne en CSS](https://twitter.com/KevinJPowell/status/1501555193799925761) (english) – Tweet de Kevin Powell ❤️","src/data/veille/2023.md","1135beec386f207f",{"html":897,"metadata":898},"\u003Cul>\n\u003Cli>\u003Ca href=\"https://build.mmm.page/\">mmm.page\u003C/a> - Éditeur de sites web très simples, en glisser-déposer, pour n’importe quoi.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.color.io/\">Color.io\u003C/a> - Éditeur photo en ligne.\u003C/li>\n\u003Cli>\u003Ca href=\"https://toolkit.addy.codes/\">Addy’s toolkit\u003C/a> - Outils et ressources pour les designers et développeurs sites web.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/\">L’accessibilité n’est pas une variable d’ajustement\u003C/a> — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n\u003Cblockquote>\n\u003Cp>L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\u003C/p>\n\u003C/blockquote>\n\u003C/li>\n\u003Cli>\u003Ca href=\"https://garden.bradwoods.io/notes/css/3d\">3D en CSS (english)\u003C/a> – Explications et exemples des propriétés 3D en CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html\">Climat : Comment ne pas déprimer ?\u003C/a> – Podcast.\u003C/li>\n\u003Cli>\u003Ca href=\"https://fable.app\">Fable (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://rive.app\">Rive (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://cakedesk.app/\">Cake Desk\u003C/a> – Application de facturation.\u003C/li>\n\u003Cli>\u003Ca href=\"https://shadows.brumm.af/\">Ombre fluide en CSS\u003C/a> – Générateur.\u003C/li>\n\u003Cli>\u003Ca href=\"https://smolcss.dev/\">Smol CSS\u003C/a> – Collection de fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/\">Ajustement optique\u003C/a> (english) – Aligner visuellement plutôt que techniquement.\u003C/li>\n\u003Cli>\u003Ca href=\"https://blog.datawrapper.de/category/datavis-dos-and-donts/\">Datawrapper\u003C/a> (english) – Conseils pour montrer de la donnée.\u003C/li>\n\u003Cli>\u003Ca href=\"https://assistivlabs.com/\">Assistivlabs\u003C/a> (english) – Service de test des technologies d’assistance (browserstack mais pour l’accessibilité).\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/\">Les caractères fantaisistes et l’accessibilité\u003C/a> – Explications et exemples de l’enfer que sont les caractères Unicode pour les technologies d’assistance.\u003C/li>\n\u003Cli>\u003Ca href=\"https://adamsilver.io/blog/designing-a-time-input-backed-by-research/\">Créer un champ \u003Ccode>time\u003C/code> sur le web\u003C/a> (english) – Article.\u003C/li>\n\u003Cli>\u003Ca href=\"https://la-cascade.io\">La cascade\u003C/a> – Collection d’articles sur le CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://tabby.sh\">Tabby\u003C/a> (english) – An alternative terminal app.\u003C/li>\n\u003Cli>\u003Ca href=\"https://newglyph.com/\">Newglyph\u003C/a> – Fonderie indépendante.\u003C/li>\n\u003Cli>\u003Ca href=\"https://headlessui.com/vue/dialog\">\u003Cspan lang=\"en\">Headless UI\u003C/span>\u003C/a> (english) – Librairie de composants vue et react.\u003C/li>\n\u003Cli>\u003Ca href=\"https://privacy.sexy\">Vie privée sexy\u003C/a> (english) – Outils de confidentialité pour windows et macos.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/leonardomso/33-js-concepts\">33 concepts JavaScript\u003C/a> (english) – Articles.\u003C/li>\n\u003Cli>\u003Ca href=\"https://formbricks.com/\">Formbricks\u003C/a> (english) – Alternative open source à google form/typeform.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/n3r4zzurr0/svg-spinners\">Animations de chargement SVG\u003C/a> – Collection.\u003C/li>\n\u003Cli>\u003Ca href=\"https://a11yphant.com/\">a11yphant\u003C/a> (english) – Challenges de code pour apprendre l’accessibilité.\u003C/li>\n\u003Cli>\u003Ca href=\"https://moderncss.dev/\">CSS moderne\u003C/a> (english) – Fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/KevinJPowell/status/1501555193799925761\">Conteneur moderne en CSS\u003C/a> (english) – Tweet de Kevin Powell ❤️\u003C/li>\n\u003C/ul>",{"headings":899,"imagePaths":900,"frontmatter":901},[],[],{"lang":16,"title":269,"updatedAt":902},"2023-04-20T17:12:06.000Z","HPsections",["Map",905,906,926,927,943,944,960,961,985,986],"011-offre",{"id":905,"data":907,"body":914,"filePath":915,"digest":916,"rendered":917},{"type":908,"lang":16,"uid":909,"image":910,"order":911,"quickTitle":912,"quickImage":913,"reference":39},"section","offre","/assets/images/home/offre-1.1.svg",1.1,"Mes offres en freelance","/assets/images/home/icon-desktop.svg","## L'offre site web classique\n\nCette offre est destinée à un public souhaitant **se doter d'un site web**, sans forcément intégrer l'accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du [référentiel général d'amélioration de l'accessibilité](https://accessibilite.numerique.gouv.fr/) (\u003Cabbr>RGAA\u003C/abbr>).\n\nL'objectif principal de cette offre étant d'**établir une présence en ligne** pour le client. Que cette dernière ait un but informatif et/ou éditorial.\n\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->","src/data/HP/011-offre.md","290ecd1ed94a1087",{"html":918,"metadata":919},"\u003Ch2 id=\"loffre-site-web-classique\">L’offre site web classique\u003C/h2>\n\u003Cp>Cette offre est destinée à un public souhaitant \u003Cstrong>se doter d’un site web\u003C/strong>, sans forcément intégrer l’accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du \u003Ca href=\"https://accessibilite.numerique.gouv.fr/\">référentiel général d’amélioration de l’accessibilité\u003C/a> (\u003Cabbr>RGAA\u003C/abbr>).\u003C/p>\n\u003Cp>L’objectif principal de cette offre étant d’\u003Cstrong>établir une présence en ligne\u003C/strong> pour le client. Que cette dernière ait un but informatif et/ou éditorial.\u003C/p>\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->",{"headings":920,"imagePaths":924,"frontmatter":925},[921],{"depth":150,"slug":922,"text":923},"loffre-site-web-classique","L’offre site web classique",[],{"type":908,"uid":909,"lang":16,"image":910,"order":911,"quickTitle":912,"quickImage":913,"reference":39},"012-offre",{"id":926,"data":928,"body":931,"filePath":932,"digest":933,"rendered":934},{"type":908,"lang":16,"image":929,"order":930,"reference":50},"/assets/images/home/offre-1.2.svg",1.2,"## L'offre accessibilité avancée\n\nCette offre s'adresse plus spécifiquement aux entités pour lesquelles **l'accessibilité du site est un critère majeur.** Qu'il s'agisse d'une création ou d'une mise en conformité après un audit d'accessibilité.\n\nLorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\n\n- [Rose Primaire](https://roseprimaire.com/) pour le conseil et l'accompagnement du projet ;\n- [Sylvain Plantier](https://jedessinebien.com/) et/ou [Benoît Etchevery](http://ben-etche.com/) pour l'illustration et la direction artistique.\n\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->","src/data/HP/012-offre.md","2a3bf3411b3c171b",{"html":935,"metadata":936},"\u003Ch2 id=\"loffre-accessibilité-avancée\">L’offre accessibilité avancée\u003C/h2>\n\u003Cp>Cette offre s’adresse plus spécifiquement aux entités pour lesquelles \u003Cstrong>l’accessibilité du site est un critère majeur.\u003C/strong> Qu’il s’agisse d’une création ou d’une mise en conformité après un audit d’accessibilité.\u003C/p>\n\u003Cp>Lorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://roseprimaire.com/\">Rose Primaire\u003C/a> pour le conseil et l’accompagnement du projet ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://jedessinebien.com/\">Sylvain Plantier\u003C/a> et/ou \u003Ca href=\"http://ben-etche.com/\">Benoît Etchevery\u003C/a> pour l’illustration et la direction artistique.\u003C/li>\n\u003C/ul>\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->",{"headings":937,"imagePaths":941,"frontmatter":942},[938],{"depth":150,"slug":939,"text":940},"loffre-accessibilité-avancée","L’offre accessibilité avancée",[],{"type":908,"lang":16,"order":930,"image":929,"reference":50},"013-offre",{"id":943,"data":945,"body":948,"filePath":949,"digest":950,"rendered":951},{"type":908,"lang":16,"image":946,"order":947},"/assets/images/home/offre-1.3.svg",1.3,"## Et l'éco-conception alors ?\n\nJe ne conçois pas l'éco-conception comme une offre. C'est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l'éco-conception sans accessibilité, j'applique donc ces méthodologies quelque soit le projet !","src/data/HP/013-offre.md","03e37f364ac27cb4",{"html":952,"metadata":953},"\u003Ch2 id=\"et-léco-conception-alors\">Et l’éco-conception alors ?\u003C/h2>\n\u003Cp>Je ne conçois pas l’éco-conception comme une offre. C’est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l’éco-conception sans accessibilité, j’applique donc ces méthodologies quelque soit le projet !\u003C/p>",{"headings":954,"imagePaths":958,"frontmatter":959},[955],{"depth":150,"slug":956,"text":957},"et-léco-conception-alors","Et l’éco-conception alors ?",[],{"type":908,"lang":16,"order":947,"image":946},"020-methodo",{"id":960,"data":962,"body":967,"filePath":968,"digest":969,"rendered":970},{"type":908,"lang":16,"uid":963,"image":964,"order":150,"quickTitle":965,"quickImage":966},"methodology","/assets/images/home/methodo.svg","Ma méthodologie","/assets/images/home/icon-methodo.svg","## Méthodologie\n\n### Accessibilité par défaut\n\nEngagé pour un web plus accessible, je crée des **sites web** en m'appuyant sur le [référentiel général d'amélioration de l'accessibilité (RGAA)](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) ainsi que sur les bonnes pratiques [Opquast.](https://www.opquast.com/rendre-le-web-meilleur/)\n\n### Sobriété par choix\n\nJe privilégie le développement de **sites statiques** en adoptant une approche [d'éco-conception numérique.](https://eco-conception.designersethiques.org/guide/fr/) \nC'est-à-dire que le site est pensé pour n'embarquer que les fonctionnalités nécessaires à son utilisation.\n\nCette approche présente de **nombreux avantages :**\n\n- chargement rapide des pages ;\n- sécurité renforcée ;\n- coûts serveur réduits ;\n- maintenance facilitée.\n\nLorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l'interface. Cela permet de garantir que **le site reste en ligne** même si le CMS venait à ne plus fonctionner.","src/data/HP/020-methodo.md","75a09b4e0b1e926b",{"html":971,"metadata":972},"\u003Ch2 id=\"méthodologie\">Méthodologie\u003C/h2>\n\u003Ch3 id=\"accessibilité-par-défaut\">Accessibilité par défaut\u003C/h3>\n\u003Cp>Engagé pour un web plus accessible, je crée des \u003Cstrong>sites web\u003C/strong> en m’appuyant sur le \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité (RGAA)\u003C/a> ainsi que sur les bonnes pratiques \u003Ca href=\"https://www.opquast.com/rendre-le-web-meilleur/\">Opquast.\u003C/a>\u003C/p>\n\u003Ch3 id=\"sobriété-par-choix\">Sobriété par choix\u003C/h3>\n\u003Cp>Je privilégie le développement de \u003Cstrong>sites statiques\u003C/strong> en adoptant une approche \u003Ca href=\"https://eco-conception.designersethiques.org/guide/fr/\">d’éco-conception numérique.\u003C/a>\u003Cbr>\nC’est-à-dire que le site est pensé pour n’embarquer que les fonctionnalités nécessaires à son utilisation.\u003C/p>\n\u003Cp>Cette approche présente de \u003Cstrong>nombreux avantages :\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>chargement rapide des pages ;\u003C/li>\n\u003Cli>sécurité renforcée ;\u003C/li>\n\u003Cli>coûts serveur réduits ;\u003C/li>\n\u003Cli>maintenance facilitée.\u003C/li>\n\u003C/ul>\n\u003Cp>Lorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l’interface. Cela permet de garantir que \u003Cstrong>le site reste en ligne\u003C/strong> même si le CMS venait à ne plus fonctionner.\u003C/p>",{"headings":973,"imagePaths":983,"frontmatter":984},[974,977,980],{"depth":150,"slug":975,"text":976},"méthodologie","Méthodologie",{"depth":154,"slug":978,"text":979},"accessibilité-par-défaut","Accessibilité par défaut",{"depth":154,"slug":981,"text":982},"sobriété-par-choix","Sobriété par choix",[],{"type":908,"uid":963,"lang":16,"image":964,"order":150,"quickTitle":965,"quickImage":966},"030-about",{"id":985,"data":987,"body":992,"filePath":993,"digest":994,"rendered":995},{"type":908,"lang":16,"uid":988,"image":989,"order":154,"quickTitle":990,"quickImage":991},"about","/assets/images/home/about.svg","Moi","/assets/images/home/icon-heart.svg","## À propos\n\n### Formations personnelles\n\nAfin de solidifier mes compétences, j'ai suivi les formations et passé les certifications suivantes :\n\n- [Opquast](https://directory.opquast.com/fr/certificat/CTQSKP/) - Maîtrise de la qualité en projet web ;\n- Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\n\n### Formations des autres\n\nDepuis plusieurs années, j'interviens dans différents campus afin de dispenser des cours de développement web.\n\n### Temps libre\n\nJ’essaie de contribuer à des [projets open source](https://git.nardu.in/explore/repos) qui me tiennent à cœur et je m'engage localement avec le collectif [good-it!](https://www.good-it.org/)\n\nAh et j’écris [des articles](/articles) aussi ! Des articles sur le design, le développement web et l’informatique.","src/data/HP/030-about.md","a7abff6d744406ce",{"html":996,"metadata":997},"\u003Ch2 id=\"à-propos\">À propos\u003C/h2>\n\u003Ch3 id=\"formations-personnelles\">Formations personnelles\u003C/h3>\n\u003Cp>Afin de solidifier mes compétences, j’ai suivi les formations et passé les certifications suivantes :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://directory.opquast.com/fr/certificat/CTQSKP/\">Opquast\u003C/a> - Maîtrise de la qualité en projet web ;\u003C/li>\n\u003Cli>Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"formations-des-autres\">Formations des autres\u003C/h3>\n\u003Cp>Depuis plusieurs années, j’interviens dans différents campus afin de dispenser des cours de développement web.\u003C/p>\n\u003Ch3 id=\"temps-libre\">Temps libre\u003C/h3>\n\u003Cp>J’essaie de contribuer à des \u003Ca href=\"https://git.nardu.in/explore/repos\">projets open source\u003C/a> qui me tiennent à cœur et je m’engage localement avec le collectif \u003Ca href=\"https://www.good-it.org/\">good-it!\u003C/a>\u003C/p>\n\u003Cp>Ah et j’écris \u003Ca href=\"/articles\">des articles\u003C/a> aussi ! Des articles sur le design, le développement web et l’informatique.\u003C/p>",{"headings":998,"imagePaths":1011,"frontmatter":1012},[999,1002,1005,1008],{"depth":150,"slug":1000,"text":1001},"à-propos","À propos",{"depth":154,"slug":1003,"text":1004},"formations-personnelles","Formations personnelles",{"depth":154,"slug":1006,"text":1007},"formations-des-autres","Formations des autres",{"depth":154,"slug":1009,"text":1010},"temps-libre","Temps libre",[],{"type":908,"uid":988,"lang":16,"image":989,"order":154,"quickTitle":990,"quickImage":991}] \ No newline at end of file +[["Map",1,2,9,10,124,125,173,174,537,538,552,553],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.1.1","content-config-digest","8021b3469f132349","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"site\":\"https://www.nardu.in\",\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true},\"redirects\":{\"/articles/en/[...id]\":\"/articles/en-[...id]\",\"/snippets/en/[...id]\":\"/fragments/en-[...id]\"},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[\"assets.nardu.in\"],\"remotePatterns\":[{\"protocol\":\"https\"}]},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":false,\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[[null,{\"theme\":\"one-dark-pro\",\"plugins\":[{\"name\":\"Line numbers\",\"styleSettings\":{\"defaultValues\":{\"lineNumbers\":{\"foreground\":\"inherit\",\"highlightForeground\":\"inherit\"}},\"cssVarExclusions\":[],\"cssVarReplacements\":[]},\"hooks\":{}},{\"name\":\"astro-expressive-code\",\"hooks\":{}}],\"defaultProps\":{\"showLineNumbers\":false,\"overridesByLang\":{\"css,html,js,ts,vue\":{\"showLineNumbers\":true}}}}]],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"responsiveImages\":false},\"legacy\":{\"collections\":false}}","HPsections",["Map",11,12,31,32,52,53,78,79,96,97],"013-offre",{"id":11,"data":13,"body":18,"filePath":19,"digest":20,"rendered":21},{"type":14,"lang":15,"image":16,"order":17},"section","fr","/assets/images/home/offre-1.3.svg",1.3,"## Et l'éco-conception alors ?\n\nJe ne conçois pas l'éco-conception comme une offre. C'est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l'éco-conception sans accessibilité, j'applique donc ces méthodologies quelque soit le projet !","src/data/HP/013-offre.md","03e37f364ac27cb4",{"html":22,"metadata":23},"\u003Ch2 id=\"et-léco-conception-alors\">Et l’éco-conception alors ?\u003C/h2>\n\u003Cp>Je ne conçois pas l’éco-conception comme une offre. C’est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l’éco-conception sans accessibilité, j’applique donc ces méthodologies quelque soit le projet !\u003C/p>",{"headings":24,"imagePaths":29,"frontmatter":30},[25],{"depth":26,"slug":27,"text":28},2,"et-léco-conception-alors","Et l’éco-conception alors ?",[],{"type":14,"lang":15,"order":17,"image":16},"011-offre",{"id":31,"data":33,"body":40,"filePath":41,"digest":42,"rendered":43},{"type":14,"lang":15,"uid":34,"image":35,"order":36,"quickTitle":37,"quickImage":38,"reference":39},"offre","/assets/images/home/offre-1.1.svg",1.1,"Mes offres en freelance","/assets/images/home/icon-desktop.svg","parole-expression","## L'offre site web classique\n\nCette offre est destinée à un public souhaitant **se doter d'un site web**, sans forcément intégrer l'accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du [référentiel général d'amélioration de l'accessibilité](https://accessibilite.numerique.gouv.fr/) (\u003Cabbr>RGAA\u003C/abbr>).\n\nL'objectif principal de cette offre étant d'**établir une présence en ligne** pour le client. Que cette dernière ait un but informatif et/ou éditorial.\n\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->","src/data/HP/011-offre.md","290ecd1ed94a1087",{"html":44,"metadata":45},"\u003Ch2 id=\"loffre-site-web-classique\">L’offre site web classique\u003C/h2>\n\u003Cp>Cette offre est destinée à un public souhaitant \u003Cstrong>se doter d’un site web\u003C/strong>, sans forcément intégrer l’accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du \u003Ca href=\"https://accessibilite.numerique.gouv.fr/\">référentiel général d’amélioration de l’accessibilité\u003C/a> (\u003Cabbr>RGAA\u003C/abbr>).\u003C/p>\n\u003Cp>L’objectif principal de cette offre étant d’\u003Cstrong>établir une présence en ligne\u003C/strong> pour le client. Que cette dernière ait un but informatif et/ou éditorial.\u003C/p>\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->",{"headings":46,"imagePaths":50,"frontmatter":51},[47],{"depth":26,"slug":48,"text":49},"loffre-site-web-classique","L’offre site web classique",[],{"type":14,"uid":34,"lang":15,"image":35,"order":36,"quickTitle":37,"quickImage":38,"reference":39},"020-methodo",{"id":52,"data":54,"body":59,"filePath":60,"digest":61,"rendered":62},{"type":14,"lang":15,"uid":55,"image":56,"order":26,"quickTitle":57,"quickImage":58},"methodology","/assets/images/home/methodo.svg","Ma méthodologie","/assets/images/home/icon-methodo.svg","## Méthodologie\n\n### Accessibilité par défaut\n\nEngagé pour un web plus accessible, je crée des **sites web** en m'appuyant sur le [référentiel général d'amélioration de l'accessibilité (RGAA)](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) ainsi que sur les bonnes pratiques [Opquast.](https://www.opquast.com/rendre-le-web-meilleur/)\n\n### Sobriété par choix\n\nJe privilégie le développement de **sites statiques** en adoptant une approche [d'éco-conception numérique.](https://eco-conception.designersethiques.org/guide/fr/) \nC'est-à-dire que le site est pensé pour n'embarquer que les fonctionnalités nécessaires à son utilisation.\n\nCette approche présente de **nombreux avantages :**\n\n- chargement rapide des pages ;\n- sécurité renforcée ;\n- coûts serveur réduits ;\n- maintenance facilitée.\n\nLorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l'interface. Cela permet de garantir que **le site reste en ligne** même si le CMS venait à ne plus fonctionner.","src/data/HP/020-methodo.md","75a09b4e0b1e926b",{"html":63,"metadata":64},"\u003Ch2 id=\"méthodologie\">Méthodologie\u003C/h2>\n\u003Ch3 id=\"accessibilité-par-défaut\">Accessibilité par défaut\u003C/h3>\n\u003Cp>Engagé pour un web plus accessible, je crée des \u003Cstrong>sites web\u003C/strong> en m’appuyant sur le \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité (RGAA)\u003C/a> ainsi que sur les bonnes pratiques \u003Ca href=\"https://www.opquast.com/rendre-le-web-meilleur/\">Opquast.\u003C/a>\u003C/p>\n\u003Ch3 id=\"sobriété-par-choix\">Sobriété par choix\u003C/h3>\n\u003Cp>Je privilégie le développement de \u003Cstrong>sites statiques\u003C/strong> en adoptant une approche \u003Ca href=\"https://eco-conception.designersethiques.org/guide/fr/\">d’éco-conception numérique.\u003C/a>\u003Cbr>\nC’est-à-dire que le site est pensé pour n’embarquer que les fonctionnalités nécessaires à son utilisation.\u003C/p>\n\u003Cp>Cette approche présente de \u003Cstrong>nombreux avantages :\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>chargement rapide des pages ;\u003C/li>\n\u003Cli>sécurité renforcée ;\u003C/li>\n\u003Cli>coûts serveur réduits ;\u003C/li>\n\u003Cli>maintenance facilitée.\u003C/li>\n\u003C/ul>\n\u003Cp>Lorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l’interface. Cela permet de garantir que \u003Cstrong>le site reste en ligne\u003C/strong> même si le CMS venait à ne plus fonctionner.\u003C/p>",{"headings":65,"imagePaths":76,"frontmatter":77},[66,69,73],{"depth":26,"slug":67,"text":68},"méthodologie","Méthodologie",{"depth":70,"slug":71,"text":72},3,"accessibilité-par-défaut","Accessibilité par défaut",{"depth":70,"slug":74,"text":75},"sobriété-par-choix","Sobriété par choix",[],{"type":14,"uid":55,"lang":15,"image":56,"order":26,"quickTitle":57,"quickImage":58},"012-offre",{"id":78,"data":80,"body":84,"filePath":85,"digest":86,"rendered":87},{"type":14,"lang":15,"image":81,"order":82,"reference":83},"/assets/images/home/offre-1.2.svg",1.2,"rose-primaire","## L'offre accessibilité avancée\n\nCette offre s'adresse plus spécifiquement aux entités pour lesquelles **l'accessibilité du site est un critère majeur.** Qu'il s'agisse d'une création ou d'une mise en conformité après un audit d'accessibilité.\n\nLorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\n\n- [Rose Primaire](https://roseprimaire.com/) pour le conseil et l'accompagnement du projet ;\n- [Sylvain Plantier](https://jedessinebien.com/) et/ou [Benoît Etchevery](http://ben-etche.com/) pour l'illustration et la direction artistique.\n\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->","src/data/HP/012-offre.md","2a3bf3411b3c171b",{"html":88,"metadata":89},"\u003Ch2 id=\"loffre-accessibilité-avancée\">L’offre accessibilité avancée\u003C/h2>\n\u003Cp>Cette offre s’adresse plus spécifiquement aux entités pour lesquelles \u003Cstrong>l’accessibilité du site est un critère majeur.\u003C/strong> Qu’il s’agisse d’une création ou d’une mise en conformité après un audit d’accessibilité.\u003C/p>\n\u003Cp>Lorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://roseprimaire.com/\">Rose Primaire\u003C/a> pour le conseil et l’accompagnement du projet ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://jedessinebien.com/\">Sylvain Plantier\u003C/a> et/ou \u003Ca href=\"http://ben-etche.com/\">Benoît Etchevery\u003C/a> pour l’illustration et la direction artistique.\u003C/li>\n\u003C/ul>\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->",{"headings":90,"imagePaths":94,"frontmatter":95},[91],{"depth":26,"slug":92,"text":93},"loffre-accessibilité-avancée","L’offre accessibilité avancée",[],{"type":14,"lang":15,"order":82,"image":81,"reference":83},"030-about",{"id":96,"data":98,"body":103,"filePath":104,"digest":105,"rendered":106},{"type":14,"lang":15,"uid":99,"image":100,"order":70,"quickTitle":101,"quickImage":102},"about","/assets/images/home/about.svg","Moi","/assets/images/home/icon-heart.svg","## À propos\n\n### Formations personnelles\n\nAfin de solidifier mes compétences, j'ai suivi les formations et passé les certifications suivantes :\n\n- [Opquast](https://directory.opquast.com/fr/certificat/CTQSKP/) - Maîtrise de la qualité en projet web ;\n- Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\n\n### Formations des autres\n\nDepuis plusieurs années, j'interviens dans différents campus afin de dispenser des cours de développement web.\n\n### Temps libre\n\nJ’essaie de contribuer à des [projets open source](https://git.nardu.in/explore/repos) qui me tiennent à cœur et je m'engage localement avec le collectif [good-it!](https://www.good-it.org/)\n\nAh et j’écris [des articles](/articles) aussi ! Des articles sur le design, le développement web et l’informatique.","src/data/HP/030-about.md","a7abff6d744406ce",{"html":107,"metadata":108},"\u003Ch2 id=\"à-propos\">À propos\u003C/h2>\n\u003Ch3 id=\"formations-personnelles\">Formations personnelles\u003C/h3>\n\u003Cp>Afin de solidifier mes compétences, j’ai suivi les formations et passé les certifications suivantes :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://directory.opquast.com/fr/certificat/CTQSKP/\">Opquast\u003C/a> - Maîtrise de la qualité en projet web ;\u003C/li>\n\u003Cli>Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"formations-des-autres\">Formations des autres\u003C/h3>\n\u003Cp>Depuis plusieurs années, j’interviens dans différents campus afin de dispenser des cours de développement web.\u003C/p>\n\u003Ch3 id=\"temps-libre\">Temps libre\u003C/h3>\n\u003Cp>J’essaie de contribuer à des \u003Ca href=\"https://git.nardu.in/explore/repos\">projets open source\u003C/a> qui me tiennent à cœur et je m’engage localement avec le collectif \u003Ca href=\"https://www.good-it.org/\">good-it!\u003C/a>\u003C/p>\n\u003Cp>Ah et j’écris \u003Ca href=\"/articles\">des articles\u003C/a> aussi ! Des articles sur le design, le développement web et l’informatique.\u003C/p>",{"headings":109,"imagePaths":122,"frontmatter":123},[110,113,116,119],{"depth":26,"slug":111,"text":112},"à-propos","À propos",{"depth":70,"slug":114,"text":115},"formations-personnelles","Formations personnelles",{"depth":70,"slug":117,"text":118},"formations-des-autres","Formations des autres",{"depth":70,"slug":120,"text":121},"temps-libre","Temps libre",[],{"type":14,"uid":99,"lang":15,"image":100,"order":70,"quickTitle":101,"quickImage":102},"references",["Map",126,127,139,140,39,153,83,163],"3w",{"id":126,"data":128,"filePath":135,"digest":136,"rendered":137},{"title":126,"subtitle":129,"url":130,"lang":15,"slug":126,"tags":131,"createdAt":134},"J'ai fait de la doc!","https://3-w.fr",[132,133],"Front-end","documentation",["Date","2022-10-19T18:02:00.000Z"],"src/content/references/3w.md","0d3d94c8af754e1b",{"html":138},"","natureo",{"id":139,"data":141,"filePath":150,"digest":151,"rendered":152},{"title":142,"subtitle":143,"url":144,"lang":15,"slug":139,"tags":145,"createdAt":149},"Nature en Occitanie","La sobriété au naturel.","https://www.natureo.org/",[132,146,147,148],"accessibilité","éco-conception","CMS",["Date","2023-04-19T18:02:00.000Z"],"src/content/references/natureo.md","6a7169b855b57024",{"html":138},{"id":39,"data":154,"filePath":160,"digest":161,"rendered":162},{"title":155,"subtitle":156,"url":157,"lang":15,"slug":39,"tags":158,"createdAt":159},"Parole Expression","Un nouveau site pour l'association.","https://www.paroleexpression.fr/",[132,147,148],["Date","2022-04-19T17:11:00.000Z"],"src/content/references/parole-expression.md","ec95a408f8c3e99c",{"html":138},{"id":83,"data":164,"filePath":170,"digest":171,"rendered":172},{"title":165,"subtitle":166,"url":167,"lang":15,"slug":83,"tags":168,"createdAt":169},"Rose Primaire","Une agence comme on l'aime.","https://roseprimaire.com/",[132,146,147,148],["Date","2023-04-19T17:11:00.000Z"],"src/content/references/rose-primaire.md","a0133200cf1bee58",{"html":138},"articles",["Map",175,176,188,189,225,226,238,239,270,271,288,289,318,319,347,348,363,364,376,377,387,388,398,399,415,416,432,433,483,484,493,494],"en-after-effects-expressions",{"id":175,"data":177,"body":185,"filePath":186,"digest":187,"deferredRender":184},{"title":178,"subtitle":179,"lang":180,"tags":181,"type":173,"slug":175,"createdAt":183,"code":184},"After Effects Expressions","Animation on steroïds.","en",[182],"Design",["Date","2019-04-24T09:00:00.000Z"],true,"import AstroImage from '../../../components/AstroImage.astro'\n\n## An ever lasting battle\n\nThere is very little documentation and the existing one is hard to find or very old. Very often I just don't have the time to dive into expression learning while animating even though it could help the entire project on the long term.\nSo the last time I had to do a complex animation, **I took the damn time!**\n\n## The begining of the end (of keyframes).\n\nEveryone uses expressions whether they know it or not. Most of the time it's a rather transparent process for the animator. For example: when parenting a property to another one, After Effects creates an expression for us.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/basic_expression_d81b12f1ac.jpeg'\n\twidth='728'\n\theight='80'\n\talt='Parenting the position of the form to a null creates an expression.'\n/>\n\nOver the last updates, Adobe has made an effort to make expressions more accessible to everyone. For example, the expression box is now resembling a code editor thanks to code-coloring and auto-completion features. After Effects expression feel like JavaScript with custom functions.\n\nThose custom functions can be called through a menu once you enabled the expressions on a property. It offers organized shortcut and proper syntax to all of AE native functions and a bunch of JavaScript standard ones.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/shortcut_39cc19d383.jpeg'\n\twidth='728'\n\theight='322'\n\talt='Alt + Click the stopwatch to access the shortcuts.'\n/>\n\n## So I need to learn javascript to do motion design now?\n\n### Why bother?\n\nI know that most animators don't have any kind of development background. However, if Adobe thought it best to let us use expressions, I think we ought to, at least, try.\n\n> A lot of incredible professionals like [Mt Mograph](https://www.mtmograph.com/) and [Video Copilot](https://videocopilot.net/) use expressions.\n\nLike every optimization process, building an expressions knowledge takes time. However, like all optimization process, you will benefit from it afterwards.\n\n### Where to learn\n\nI've gathered a list of my favourite learning grounds. Plenty more exist, **go get'em!**\n\n- [Adobe official expression starter guide (FR)](https://helpx.adobe.com/fr/after-effects/using/expression-language-reference.html)\n- [Adobe official expression basic (EN)](https://helpx.adobe.com/after-effects/using/expression-basics.html)\n- [Adobe forums for expressions](https://community.adobe.com/t5/after-effects/bd-p/after-effects?page=1&sort=latest_replies&filter=all&topics=label-expressions)\n- [Creative Cow expressions forums](https://creativecow.net/forums/forum/adobe-after-effects-expressions/)\n- [Youtube channel about expressions](https://www.youtube.com/playlist?list=PLvr5U5ZSt6IzHyvSL9fo0M9NRPsTvra31)\n- [All expressions explained](http://aescript.jecool.net/reference/)\n- [All expressions explained again](http://expressions.aenhancers.com/index.html)\n- [Nice examples of basic expressions](https://www.schoolofmotion.com/tutorials/amazing-expressions-in-after-effects)\n\n## Real world example\n\n### Number counter\n\nLet's say you need to animate a rather simple counter from 0% to 100%.\n\n- Start by creating a text layer. Define your typographic choices, colours, etc.\n- On the effect menu add expression options > slider control\n- Alt + Click the Source text property\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/alt-counter.mp4' type='video/mp4' />\n\u003C/video>\n\n- Parent the source text to the slider control through the pickwhip.\n\n\u003Cvideo width='462' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/pickwhip.mp4' type='video/mp4' />\n\u003C/video>\n\nYou should get something like this in the expressions panel:\n\n```javascript\neffect(\"Slider Control\")(\"Slider\")​\n```\n\n- Set two keyframes on the slider from 0 to 100. The text should update accordingly.\n- By default, After Effects does not round numbers. In the expression panel, wrap your expression with the `Math.round()` function.\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/round.mp4' type='video/mp4' />\n\u003C/video>\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\"))​\n```\n\nGreat! We have a working counter. But we wanted a percentage counter. We could add a % glyph in another text layer but let's not.\n\nStill in the expression panel, we're going to add a string containing the % glyph, using basic JavaScript concatenation: `+ '%'`\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\")) + '%'​\n```\n\n\u003Cvideo width='538' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/percent.mp4' type='video/mp4' />\n\u003C/video>\n\n**And there we go!** A fully functioning and customizable counter using a slider controller and expressions.","src/content/articles/en/after-effects-expressions.mdx","3b6f88fbf35af1a4","en-2023",{"id":188,"data":190,"body":197,"filePath":198,"digest":199,"rendered":200},{"title":191,"subtitle":192,"lang":180,"tags":193,"type":173,"slug":188,"createdAt":195,"updatedAt":196},"Nico v2.5","Update 2023.",[194],"Freelance",["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"This article will be updated when I have something new to share during the year 2023.\n\n## The website\n\n### Technologies\n\nOops... I (re)did it again.\n\nI have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself [in 2022 !](/en/articles/2022/#the-website)\n\nI will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\n\nMy \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I'm back to a solid **95/100** without any particular optimization. With some small efforts, I've reached the good old 100/100.\n\nI then did a work of modernization of the codebase. Hello CSS variables and goodbye `media queries`. In no particular order, here are some of the improvements I made:\n\n- `flexbox` and `grid` to adapt the layout to different screen sizes;\n- CSS variables for colors, font sizes and margins;\n- some `container queries`, just to try;\n- logical CSS properties (`inline` and `block` instead of `width` and `height` for example).\n\nI took this opportunity to publish [the source code](https://git.nardu.in/nardu.in/website-astro) on my git repository.\n\n**Update #1:** I've added [an RSS feed](/en/rss.xml) as I find myself using it more and more on other websites.\n\n### Analytics\n\nI removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\n\nIt's nice to see that your site is consulted, but if there is no other purpose behind it, it's an extra resource loaded for nothing by visitors. Maybe I'll reactivate the tracking when I have a use for it (other than flattering my ego).\n\nPrevious visit reports can be found at [this link.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Content\n\n- I've added a [work](/en/work/) page to list some of my projects.\n- I've also added [a page](/en/veille/) where I list some interesting things from around the web.\n\n## Additional projects\n\nI'm still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at [3-w.fr](https://3-w.fr/) (an address I am very proud of).\n\nI have to update it more regularly but I hope that the platform will help students progress!\n\n**More to come soon!**","src/content/articles/en/2023.md","489c650e66cced63",{"html":201,"metadata":202},"\u003Cp>This article will be updated when I have something new to share during the year 2023.\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oops… I (re)did it again.\u003C/p>\n\u003Cp>I have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself \u003Ca href=\"/en/articles/2022/#the-website\">in 2022 !\u003C/a>\u003C/p>\n\u003Cp>I will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\u003C/p>\n\u003Cp>My \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I’m back to a solid \u003Cstrong>95/100\u003C/strong> without any particular optimization. With some small efforts, I’ve reached the good old 100/100.\u003C/p>\n\u003Cp>I then did a work of modernization of the codebase. Hello CSS variables and goodbye \u003Ccode>media queries\u003C/code>. In no particular order, here are some of the improvements I made:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> and \u003Ccode>grid\u003C/code> to adapt the layout to different screen sizes;\u003C/li>\n\u003Cli>CSS variables for colors, font sizes and margins;\u003C/li>\n\u003Cli>some \u003Ccode>container queries\u003C/code>, just to try;\u003C/li>\n\u003Cli>logical CSS properties (\u003Ccode>inline\u003C/code> and \u003Ccode>block\u003C/code> instead of \u003Ccode>width\u003C/code> and \u003Ccode>height\u003C/code> for example).\u003C/li>\n\u003C/ul>\n\u003Cp>I took this opportunity to publish \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">the source code\u003C/a> on my git repository.\u003C/p>\n\u003Cp>\u003Cstrong>Update #1:\u003C/strong> I’ve added \u003Ca href=\"/en/rss.xml\">an RSS feed\u003C/a> as I find myself using it more and more on other websites.\u003C/p>\n\u003Ch3 id=\"analytics\">Analytics\u003C/h3>\n\u003Cp>I removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\u003C/p>\n\u003Cp>It’s nice to see that your site is consulted, but if there is no other purpose behind it, it’s an extra resource loaded for nothing by visitors. Maybe I’ll reactivate the tracking when I have a use for it (other than flattering my ego).\u003C/p>\n\u003Cp>Previous visit reports can be found at \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">this link.\u003C/a>\u003C/p>\n\u003Ch3 id=\"content\">Content\u003C/h3>\n\u003Cul>\n\u003Cli>I’ve added a \u003Ca href=\"/en/work/\">work\u003C/a> page to list some of my projects.\u003C/li>\n\u003Cli>I’ve also added \u003Ca href=\"/en/veille/\">a page\u003C/a> where I list some interesting things from around the web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"additional-projects\">Additional projects\u003C/h2>\n\u003Cp>I’m still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (an address I am very proud of).\u003C/p>\n\u003Cp>I have to update it more regularly but I hope that the platform will help students progress!\u003C/p>\n\u003Cp>\u003Cstrong>More to come soon!\u003C/strong>\u003C/p>",{"headings":203,"imagePaths":219,"frontmatter":220},[204,207,210,213,216],{"depth":26,"slug":205,"text":206},"the-website","The website",{"depth":70,"slug":208,"text":209},"technologies","Technologies",{"depth":70,"slug":211,"text":212},"analytics","Analytics",{"depth":70,"slug":214,"text":215},"content","Content",{"depth":26,"slug":217,"text":218},"additional-projects","Additional projects",[],{"title":191,"subtitle":192,"lang":180,"slug":188,"excerpt":221,"tags":222,"type":173,"createdAt":223,"updatedAt":224},"New changes.",[194],"2023-02-03T17:41:00.000Z","2023-05-17T17:41:00.000Z","en-sci-hub-unblock",{"id":225,"data":227,"body":235,"filePath":236,"digest":237,"deferredRender":184},{"title":228,"subtitle":229,"lang":180,"tags":230,"type":173,"slug":225,"createdAt":233,"updatedAt":234},"Access blocked Sci-hub","The science of sharing.",[231,232],"Internet","Science",["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nThe current sci-hub address is: \u003Ca href=\"https://www.sci-hub.st/\" rel=\"noreferer noopener\">sci-hub.st\u003C/a>\n\n## What is this about?\n\nNot being a researcher myself, here’s an [extremely well done explanatory video](https://youtu.be/rcgxY__YXEc) on the subject of scientific publication (french audio with auto subtitle).\n\n> “This is outrageous!”​\n\nI noticed that my ISP was indeed blocking access. I have not yet been able to check for the other suppliers, but I imagine that they have all complied with the court decision.\nThe restriction in place is quite basic. This is a “DNS” block. A DNS is a server that is used to link a domain name: **www.sci-hub.tw** to an IP address: **186.2.163.90**\nIt is, in a way, the Internet phone book. Without the address, it is impossible to contact the domain. What ISPs have certainly done: block requests to the [sci-hub.se.](http://sci-hub.se/) domain name. As a result, no IP address is returned and the site is not accessible.\n\n## How to bypass this?\n\n- Either by using a VPN\n- Either by modifying the DNS servers of your computers/Internet box\n\nI would recommend the second solution because it allows you to protect yourself against future blockages/filtering/censorship from your ISP and does not require any financial compensation.\nI will focus on change from a computer because it will be effective wherever you are and not only from your home.\n\n### MacOs\n\nGo to:\n\n1. System Preferences\n1. Network\n1. (wi-fi and/or ethernet)\n1. Advanced\n1. DNS\n\nFrom there, you can add DNS servers by clicking the + icon. Click ok and apply the new settings. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS network and DNS settings'\n/>\n\n### Windows (10)\n\nGo to:\n\n1. System Settings\n1. Network & Internet\n1. Change adapter options\n1. Right click your adapter then “properties”\n1. Select “internet protocol version 4” (and/or 6)\n1. Properties\n1. Use the following DNS server addresses\n\nFrom there, you can add DNS servers. Click save. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Windows system settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows network settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows network connections settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows network adapter settings'\n/>\n\n## Which DNS?\n\nThere are many DNS servers available. The best known are Google, Cloudflare and OpenDNS. If you really want to use Google’s, I’ll let you look up their address. Here are my recommendations in order of preference.\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMy favorite since it is a [french association](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net)\n\nQuand9 is a non-profit foundation offering free public DNS servers. Their classic servers offer filtering of identified malicious domains. They do not collect data and are \u003Cabbr title=\"General Data Protection Regulation\">GDPR\u003C/abbr>-compliant.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## That's it.\n\nBy changing these settings, you are free from your ISPs and their content filtering rules.\n\nFor the moment, these restrictions are almost symbolic because if Sci-hub were to change its url, the block would no longer work. But the publishers’ victory in court shows that they have not had their last word. We are therefore not immune to a wider and stronger block in the future.\n\nIf you want to learn more about the struggle of the people who fight to ensure that research is not a paid commodity, I recommend [this documentary](https://youtu.be/y_CQATGOX2w) on Aaron Shwartz. Or [this article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) about the founder of Sci-hub.\n\nIn the meantime, good readings to all of you. We stand with you!","src/content/articles/en/sci-hub-blocage.mdx","af48e8c0c3b463bf","en-2022",{"id":238,"data":240,"body":245,"filePath":246,"digest":247,"rendered":248},{"title":241,"subtitle":242,"lang":180,"tags":243,"type":173,"slug":238,"createdAt":244},"Nico v2.0","2022 update of many things.",[194],["Date","2022-06-08T14:24:06.000Z"],"After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\n\n## Services\n\n### No more print\n\nEven though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for \"classic\" graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\n\n### Internet all the way\n\nOn the other hand, I spend my time **doing web stuff.** A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer **more specific web offerings,** in which I have specialised.\n\nThus, **accessibility** and **eco-design** become integrated expertises in my practice. They are no longer options on a quote but **my core business.**\n\n## The website\n\nI have reworked my website, especially the homepage and its content, to better reflect these decisions.\n\nI have also made several behavioural changes:\n\n- external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven't found a good reason to continue using this behaviour;\n- I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu);\n- \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\n- I only trigger animations if the user has not asked the system to reduce the amount motion [(reference)](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).\n\nI am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello [astro](https://astro.build/) 👀).\n\n## Le Nico\n\nOn a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\n\nI have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.","src/content/articles/en/2022.md","7b98592763cb0929",{"html":249,"metadata":250},"\u003Cp>After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\u003C/p>\n\u003Ch2 id=\"services\">Services\u003C/h2>\n\u003Ch3 id=\"no-more-print\">No more print\u003C/h3>\n\u003Cp>Even though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for “classic” graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\u003C/p>\n\u003Ch3 id=\"internet-all-the-way\">Internet all the way\u003C/h3>\n\u003Cp>On the other hand, I spend my time \u003Cstrong>doing web stuff.\u003C/strong> A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer \u003Cstrong>more specific web offerings,\u003C/strong> in which I have specialised.\u003C/p>\n\u003Cp>Thus, \u003Cstrong>accessibility\u003C/strong> and \u003Cstrong>eco-design\u003C/strong> become integrated expertises in my practice. They are no longer options on a quote but \u003Cstrong>my core business.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Cp>I have reworked my website, especially the homepage and its content, to better reflect these decisions.\u003C/p>\n\u003Cp>I have also made several behavioural changes:\u003C/p>\n\u003Cul>\n\u003Cli>external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven’t found a good reason to continue using this behaviour;\u003C/li>\n\u003Cli>I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a>;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\u003C/li>\n\u003Cli>I only trigger animations if the user has not asked the system to reduce the amount motion \u003Ca href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion\">(reference)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>I am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello \u003Ca href=\"https://astro.build/\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>On a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\u003C/p>\n\u003Cp>I have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.\u003C/p>",{"headings":251,"imagePaths":265,"frontmatter":266},[252,255,258,261,262],{"depth":26,"slug":253,"text":254},"services","Services",{"depth":70,"slug":256,"text":257},"no-more-print","No more print",{"depth":70,"slug":259,"text":260},"internet-all-the-way","Internet all the way",{"depth":26,"slug":205,"text":206},{"depth":26,"slug":263,"text":264},"le-nico","Le Nico",[],{"title":241,"subtitle":242,"lang":180,"slug":238,"excerpt":267,"tags":268,"type":173,"createdAt":269},"Changes in my services, the website and myself.",[194],"2022-06-08T14:24:06.000Z","en-gratuiste",{"id":270,"data":272,"body":277,"filePath":278,"digest":279,"rendered":280},{"title":273,"subtitle":274,"lang":180,"tags":275,"type":173,"slug":270,"createdAt":276,"draft":184},"Gratuiste","Translation in progress, stay tuned ;)",[182,194],["Date","2017-05-27T07:47:36.000Z"],"[Go back to available articles](/en/articles)","src/content/articles/en/gratuiste.md","ebec75d19f0ff741",{"html":281,"metadata":282},"\u003Cp>\u003Ca href=\"/en/articles\">Go back to available articles\u003C/a>\u003C/p>",{"headings":283,"imagePaths":284,"frontmatter":285},[],[],{"title":273,"subtitle":274,"lang":180,"slug":270,"draft":184,"excerpt":274,"tags":286,"type":173,"createdAt":287},[182,194],"2017-05-27T07:47:36.000Z","2022",{"id":288,"data":290,"body":294,"filePath":295,"digest":296,"rendered":297},{"title":241,"subtitle":291,"lang":15,"tags":292,"type":173,"slug":288,"createdAt":293},"Mise à jour 2022 de plein de trucs.",[194],["Date","2022-06-08T14:24:06.000Z"],"Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\n\n## Les services\n\n### J’arrête le print\n\nMême si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\n\n### J’internet à fond\n\nÀ l’inverse, je passe mon temps à **faire du web.** Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer **des offres web plus précises,** dans lesquelles je me suis spécialisé.\n\nAinsi, **l’accessibilité numérique** et **l’éco-conception** deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien **mon cœur de métier.**\n\n## Le site\n\nJ’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\n\nJ’ai également fait plusieurs changements de comportements :\n\n- les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\n- j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec [cette analyse](https://twitter.com/HTeuMeuLeu/status/1370310316496728065) de [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu) ;\n- [idem pour la favicon](https://twitter.com/HTeuMeuLeu/status/1370310312214339586) ;\n- je ne déclenche les animations que si l'utilisateur n'a pas demandé au système de minimiser la quantité d'animation ou de mouvement [(référence de l'option)](https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion).\n\nJe suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> 👀).\n\n## Le Nico\n\nD’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif [Good-it!](https://www.good-it.org/) et en participant activement à son développement.\n\nJ’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.","src/content/articles/fr/2022.md","2589166172138721",{"html":298,"metadata":299},"\u003Cp>Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\u003C/p>\n\u003Ch2 id=\"les-services\">Les services\u003C/h2>\n\u003Ch3 id=\"jarrête-le-print\">J’arrête le print\u003C/h3>\n\u003Cp>Même si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\u003C/p>\n\u003Ch3 id=\"jinternet-à-fond\">J’internet à fond\u003C/h3>\n\u003Cp>À l’inverse, je passe mon temps à \u003Cstrong>faire du web.\u003C/strong> Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer \u003Cstrong>des offres web plus précises,\u003C/strong> dans lesquelles je me suis spécialisé.\u003C/p>\n\u003Cp>Ainsi, \u003Cstrong>l’accessibilité numérique\u003C/strong> et \u003Cstrong>l’éco-conception\u003C/strong> deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien \u003Cstrong>mon cœur de métier.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Cp>J’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\u003C/p>\n\u003Cp>J’ai également fait plusieurs changements de comportements :\u003C/p>\n\u003Cul>\n\u003Cli>les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\u003C/li>\n\u003Cli>j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\">cette analyse\u003C/a> de \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a> ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\">idem pour la favicon\u003C/a> ;\u003C/li>\n\u003Cli>je ne déclenche les animations que si l’utilisateur n’a pas demandé au système de minimiser la quantité d’animation ou de mouvement \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion\">(référence de l’option)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>Je suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>D’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif \u003Ca href=\"https://www.good-it.org/\">Good-it!\u003C/a> et en participant activement à son développement.\u003C/p>\n\u003Cp>J’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.\u003C/p>",{"headings":300,"imagePaths":314,"frontmatter":315},[301,304,307,310,313],{"depth":26,"slug":302,"text":303},"les-services","Les services",{"depth":70,"slug":305,"text":306},"jarrête-le-print","J’arrête le print",{"depth":70,"slug":308,"text":309},"jinternet-à-fond","J’internet à fond",{"depth":26,"slug":311,"text":312},"le-site","Le site",{"depth":26,"slug":263,"text":264},[],{"title":241,"subtitle":291,"lang":15,"slug":288,"excerpt":316,"tags":317,"type":173,"createdAt":269},"Évolution des services, du site et de moi-même.",[194],"2023",{"id":318,"data":320,"body":325,"filePath":326,"digest":327,"rendered":328},{"title":191,"subtitle":321,"lang":15,"tags":322,"type":173,"slug":318,"createdAt":323,"updatedAt":324},"Mise à jour 2023.",[194],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"Cet article sera mis à jour lorsque j'aurai des nouveautés à partager au cours de l'année 2023.\n\n## Le site\n\n### Technologies\n\nOups… je l'ai encore (re)fait.\n\nJ'ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même [en 2022 !](/articles/2022/#le-site)\n\nJe ferai certainement un ou deux articles/fragments sur Astro et les extensions que j'ai utilisées. En tout cas c'était super comme expérience. Nuxt v2 n'étant plus vraiment à jour, les performances n'étaient plus au rendez-vous. Astro a complètement corrigé ça.\n\nMon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide **95/100** sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\n\nJ'ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les `media queries`. En vrac, voici certaines améliorations que j'ai mises en place :\n\n- `flexbox` et `grid` pour adapter la mise en page aux différentes tailles d'écran ;\n- variables CSS pour les couleurs, les tailles de polices et les marges ;\n- quelques \u003Cspan lang=\"en\">`container queries`\u003C/span> pour essayer ;\n- propriétés logiques CSS (\u003Cspan lang=\"en\">`inline`\u003C/span> et \u003Cspan lang=\"en\">`block`\u003C/span> à la place de \u003Cspan lang=\"en\">`width`\u003C/span> et \u003Cspan lang=\"en\">`height`\u003C/span> par exemple).\n\nJ'en ai profité pour publier [le code source](https://git.nardu.in/nardu.in/website-astro) sur mon dépôt git.\n\n**Mise à jour #1 :** J'ai ajouté [un flux RSS](/rss.xml) car j'utilise de plus en plus le RSS sur d'autres sites web.\n\n### Suivi des visites\n\nJ’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n'était collectée et je consultais rarement les rapports.\n\nC'est sympa de voir que son site est visité, mais s'il n'y a aucun autre but derrière, c'est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j'en aurai l'utilité (autre que flatter mon égo).\n\nLes rapports de visites précédents sont consultables sur [ce lien.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Contenu\n\n- J'ai ajouté une page [références](/references/) pour lister certains de mes projets.\n- J'ai également ajouté [une page](/veille/) où je répertorie des choses intéressantes trouvées sur le web.\n\n## Projets annexes\n\nJe continue d'enseigner le développement web cette année. Afin d'étoffer mes supports de cours, j'ai mis en place un mini site de documentation disponible à l'adresse [3-w.fr](https://3-w.fr/) (adresse dont je suis très fier).\n\nIl faut que j'arrive à être plus régulier dans sa mise à jour mais j'ai bon espoir que la plateforme aide les élèves à progresser !\n\n**Plus de trucs bientôt!**","src/content/articles/fr/2023.md","d97f4a5af975333f",{"html":329,"metadata":330},"\u003Cp>Cet article sera mis à jour lorsque j’aurai des nouveautés à partager au cours de l’année 2023.\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oups… je l’ai encore (re)fait.\u003C/p>\n\u003Cp>J’ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même \u003Ca href=\"/articles/2022/#le-site\">en 2022 !\u003C/a>\u003C/p>\n\u003Cp>Je ferai certainement un ou deux articles/fragments sur Astro et les extensions que j’ai utilisées. En tout cas c’était super comme expérience. Nuxt v2 n’étant plus vraiment à jour, les performances n’étaient plus au rendez-vous. Astro a complètement corrigé ça.\u003C/p>\n\u003Cp>Mon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide \u003Cstrong>95/100\u003C/strong> sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\u003C/p>\n\u003Cp>J’ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les \u003Ccode>media queries\u003C/code>. En vrac, voici certaines améliorations que j’ai mises en place :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> et \u003Ccode>grid\u003C/code> pour adapter la mise en page aux différentes tailles d’écran ;\u003C/li>\n\u003Cli>variables CSS pour les couleurs, les tailles de polices et les marges ;\u003C/li>\n\u003Cli>quelques \u003Cspan lang=\"en\">\u003Ccode>container queries\u003C/code>\u003C/span> pour essayer ;\u003C/li>\n\u003Cli>propriétés logiques CSS (\u003Cspan lang=\"en\">\u003Ccode>inline\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>block\u003C/code>\u003C/span> à la place de \u003Cspan lang=\"en\">\u003Ccode>width\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>height\u003C/code>\u003C/span> par exemple).\u003C/li>\n\u003C/ul>\n\u003Cp>J’en ai profité pour publier \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">le code source\u003C/a> sur mon dépôt git.\u003C/p>\n\u003Cp>\u003Cstrong>Mise à jour #1 :\u003C/strong> J’ai ajouté \u003Ca href=\"/rss.xml\">un flux RSS\u003C/a> car j’utilise de plus en plus le RSS sur d’autres sites web.\u003C/p>\n\u003Ch3 id=\"suivi-des-visites\">Suivi des visites\u003C/h3>\n\u003Cp>J’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n’était collectée et je consultais rarement les rapports.\u003C/p>\n\u003Cp>C’est sympa de voir que son site est visité, mais s’il n’y a aucun autre but derrière, c’est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j’en aurai l’utilité (autre que flatter mon égo).\u003C/p>\n\u003Cp>Les rapports de visites précédents sont consultables sur \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">ce lien.\u003C/a>\u003C/p>\n\u003Ch3 id=\"contenu\">Contenu\u003C/h3>\n\u003Cul>\n\u003Cli>J’ai ajouté une page \u003Ca href=\"/references/\">références\u003C/a> pour lister certains de mes projets.\u003C/li>\n\u003Cli>J’ai également ajouté \u003Ca href=\"/veille/\">une page\u003C/a> où je répertorie des choses intéressantes trouvées sur le web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"projets-annexes\">Projets annexes\u003C/h2>\n\u003Cp>Je continue d’enseigner le développement web cette année. Afin d’étoffer mes supports de cours, j’ai mis en place un mini site de documentation disponible à l’adresse \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (adresse dont je suis très fier).\u003C/p>\n\u003Cp>Il faut que j’arrive à être plus régulier dans sa mise à jour mais j’ai bon espoir que la plateforme aide les élèves à progresser !\u003C/p>\n\u003Cp>\u003Cstrong>Plus de trucs bientôt!\u003C/strong>\u003C/p>",{"headings":331,"imagePaths":343,"frontmatter":344},[332,333,334,337,340],{"depth":26,"slug":311,"text":312},{"depth":70,"slug":208,"text":209},{"depth":70,"slug":335,"text":336},"suivi-des-visites","Suivi des visites",{"depth":70,"slug":338,"text":339},"contenu","Contenu",{"depth":26,"slug":341,"text":342},"projets-annexes","Projets annexes",[],{"title":191,"subtitle":321,"lang":15,"slug":318,"excerpt":345,"tags":346,"type":173,"createdAt":223,"updatedAt":224},"Suite des évolutions.",[194],"en-faq",{"id":347,"data":349,"body":277,"filePath":353,"digest":354,"rendered":355},{"title":350,"subtitle":274,"lang":180,"tags":351,"type":173,"slug":347,"createdAt":352,"draft":184},"Accessibility and sobriety",[194],["Date","2022-06-22T15:34:45.000Z"],"src/content/articles/en/faq.md","82d516449896f6ca",{"html":281,"metadata":356},{"headings":357,"imagePaths":358,"frontmatter":359},[],[],{"title":350,"subtitle":274,"lang":180,"slug":347,"draft":184,"excerpt":360,"tags":361,"type":173,"createdAt":362},"Why, how et and especially what.",[194],"2022-06-22T15:34:45.000Z","en-the-day-I-jamd",{"id":363,"data":365,"body":373,"filePath":374,"digest":375,"deferredRender":184},{"title":366,"subtitle":367,"lang":180,"tags":368,"type":173,"slug":363,"createdAt":371,"updatedAt":372},"The day I Jam’d","A story of unusual tools and fun gambles.",[369,370],"Dev","Jamstack",["Date","2020-10-08T09:00:00.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## The not so easy choice\n\nWhen I was still using Wordpress for my personal website, I thought it would be nice to try [OpenLiteSpeed](https://openlitespeed.org) webserver. Being a designer, I always like to have a graphical interface and I heard OLS had very nice caching and overall performances.\n\n## FIGHT!\n\nA few years later, I learned about Jamstack and its incredible potential. Not being impulsive at all, I chose to entirely remake my website with tools like [11ty](https://www.11ty.dev/) and [Strapi](https://strapi.io/).\n\nI remember Strapi still being in alpha/beta and colleagues telling me it was a risky gamble, especially since I was pretty new to the node.js world.\n\n> Open source and french? Sign me up!\n\nSo I started recreating my website identically with 11ty and Strapi. Same hosting on a Digital Ocean droplet, same webserver, same content. I had done a fair amout of performance optimizations on my wordpress install so I was eager to compare the results with the new static version.\n\nBoy did they exceed my expectations! With almost no optimization on the static side, I got the following results.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 53/100 on Wordpress.'\n/>\n\nDespite a lot of efforts I could not do better. I’m no expert in caching, do not use CDN and relied on plugins to achieve a lot of stuff (php not being my strongest skill 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 97/100 on jamstack.'\n/>\n\nAlmost **zero** special configuration (I was too anxious to test) and I reached an awesome score. I know lighthouse scores are not everything but hey, **53 vs 97**… I’ll take it!\n\n## Now kiss 🥰\n\nBoth of these approaches have their benefits and drawbacks. As a freelance, my clients often prefer or ask for Wordpress because of its reputation. I always present a Jamstack alternative when possible but it’s still scary to most compared to Wordpress. I feel however that it’s going to be easier to use Jamstack with time.\n\n## I did it again…\n\nHere we are now, a quarantine and a few months later and this website is running with… [Nuxt.js](https://nuxtjs.org/). I know, I’m sorry, I couldn’t resist the latest [nuxt content](https://content.nuxtjs.org/) functionnality.\n\nSo I re-did everything again… and let me just say: **wow**, what an experience!\nI **love** developing with Nuxt. Using nuxt content allowed me to focus on design and, well, content.\nNo more Apollo client and graphQL query, only markdown and a few promises.\n\nDon’t get me wrong, I really like working with Strapi and its graphQL capabilities but for the purpose of this website, nuxt content does it (extremely well).\n\nI’m still using Strapi as a way to upload, store and manage images, videos, gifs, etc. It might be too much for this use case but I like to know that I can still go back to it if I want to! Also, I spent quite a bit of time setting it up with OpenLiteSpeed and I’m still too attached to this accomplishment to let it go.\n\n## In the end\n\nWordpress, Jamstack, vanilla everything… Does it really matter? For me, the dev experience was far more enjoyable working with 11ty, nuxt.js and strapi than with Wordpress.\n\nOn the performance and accessibility side, it also seems to be the better/smarter choice. It might not be everytime! ¯\\\\\\_(ツ)\\_/¯\n\nCan’t wait to learn [astro](https://astro.build/) and start from scratch again!","src/content/articles/en/the-day-I-jamd.mdx","60b77e216e02f618","en-video-compression",{"id":376,"data":378,"body":384,"filePath":385,"digest":386,"deferredRender":184},{"title":379,"subtitle":380,"lang":180,"tags":381,"type":173,"slug":376,"createdAt":382,"updatedAt":383},"Video compression","Encode like you mean it.",[182],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Let's play.\n\nVideos are everywhere. **EVERYWHERE!** But videos can and will be huge when 4k becomes an internet standard. Currently, 1920x1080 is king and we usually have no problem hosting or playing this resolution.\n\n## Because we can doesn't mean we should.\n\nRight now, the (good) trend of web performance is on the rise. Everyone wants a blazing fast loading website, which might not be possible if we send requests to 100mb (or even more) videos.\n\nWith a good connection, users will not see the difference. But if we go down that path, nor will they with a 300mb one. So the goal is to make every asset as small as possible. It's already the case with images. But it's simpler and faster than video encoding.\n\n## Small size, best quality.\n\nLet's say we exported​ a 1920x1080 video from Premiere Pro with these basic settings:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-premiere-1.jpeg'\n\twidth='673'\n\theight='800'\n/>\n\nIt's gorgeous, it's Full HD, it's 1:30 minute of excellent editing but it's 50mb… What a shame.\n\n> We can already bring down the size from Premiere or Media Encoder by selecting CBR instead of VBR and using a low bitrate (like 2 or 3).\n\nLet's now use [Handbrake!](https://handbrake.fr/) It's free, open source and multi platform. You can also read this great article from [Ueno](https://loremipsum.ueno.co/dear-ueno-how-do-you-compress-videos-6657ebd9dd28?gi=930afecec398) on video encoding.\n\n**Please please PLEASE. Never export videos from within After Effects.**\n\n## Handbrake\n\n### Summary screen\n\nWhile it's not as nice as Premiere Pro, it has way more exporting capabilities. Follow these steps to use good standard settings:\n\n1. Open your source video\n1. Select a preset corresponding to your future usage like Fast 1080p30\n1. Check Web Optimized\n1. Keep MPEG-4 as the format\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-1.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Video screen\n\n1. Keep H.264 (x264) or use H.264 nvidia nvenc if you can (crazy fast encoding by nvidia)\n1. Choose Constant Quality and try a value between 20 and 30​ (higher = smaller size but lower quality)\n1. Choose Peak Framerate. If you don't know the framerate, keep the default setting\n1. Choose the type of video you are encoding (film, animation…)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-2.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Audio screen\n\nIf you don't have audio, be sure to set the audio channel to none.\nIf you have an audio channel, these settings are great and will not influence the size much​:\n\n1. Codec AAC\n1. Samplerate 44.1\n1. Bitrate 192 to 256 (your choice)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-3.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Export!\n\nI used a RF of 25 for this example and no audio.\n\n1. My Premiere Pro video was 50,6mb\n1. My Handbrake video is 5,5mb​\n\n> What a save!\n\n​I ended up dividing the original size by 10. Which is cool.\nI tried with a RF of 30. The video was still pretty good and only 3,3mb.\n\n## Exporting for the web\n\nNow that we know how to properly compress videos, let's go further. Say we have a website with a lot of videos on the same page. We still want to load the content as fast as possible. So our videos need to be as small as possible. We won't do better than previously seen using mp4/H.264. However, we can use **webm/VP9.**\nWebm is an html video format and VP9 is its latest codec.\n\nUsing Handbrake and webm/VP9, we can achieve really great compression without losing too much quality (or none at all depending on the settings). I was able to divide by 4 the size of a video using these presets:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-4.jpg'\n\twidth='728'\n\theight='313'\n\talt=''\n/>\n\nThe only down side is that it takes some time to encode. It will depend on the video length and your computing power.\n\nI tried various settings but I read [here](https://trac.ffmpeg.org/wiki/Encode/VP9) that VP9 is supposed to be used with two-pass encoding. You then have to find the right bitrate (here 1000) for your situation.","src/content/articles/en/video-compression.mdx","5bb9f69df6c651d1","sci-hub-blocage",{"id":387,"data":389,"body":395,"filePath":396,"digest":397,"deferredRender":184},{"title":390,"subtitle":391,"lang":15,"tags":392,"type":173,"slug":387,"createdAt":393,"updatedAt":394},"Sci-hub bloqué, comment contourner","La science du partage.",[231,232],["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nL'adresse actuelle de sci-hub est : \u003Ca href=\"https://www.sci-hub.st/\" rel=\"noreferer noopener\">sci-hub.st\u003C/a>\n\n## Résumé de la situation\n\nN’étant pas moi-même directement chercheur, je vous laisse regarder [cette vidéo](https://youtu.be/rcgxY__YXEc) explicative extrêmement bien faite sur le sujet de la publication scientifique.\n\n> “ Mais c’est scandaleux ! ”​\n\nJ’ai constaté que le blocage était actif chez SFR. Je n’ai pas encore pu vérifier pour les autres fournisseurs mais j’imagine qu’ils se sont tous conformés à la décision de justice.\nLe blocage mis en place est assez basique. Il s’agit d’un blocage “ DNS ”.\n\nUn DNS est un serveur qui sert à faire le lien entre un nom de domaine : **sci-hub.tw** et une adresse IP : **186.2.163.90**.\n\nC’est en quelque sorte l’annuaire d’internet. Sans l’adresse, impossible de contacter le domaine. Ce que les FAI ont certainement fait : bloquer les requêtes au nom de domaine [sci-hub.se.](http://sci-hub.se/) Ainsi, aucune adresse IP n’est renvoyée et le site n’est pas accessible.\n\n## Comment contourner ce blocage ?\n\n- Soit en utilisant un VPN\n- Soit en modifiant les serveurs DNS de vos ordinateurs/box internet\n\nJe recommande la deuxième solution car elle permet de se prémunir contre de futurs blocages/filtrages/censures de la part de votre FAI et ne nécessite pas de contrepartie financière.\nJe vais me focaliser sur le changement depuis un ordinateur car il sera effectif où que vous soyez.\n\n### Sur MacOs\n\nOuvrez :\n\n1. Préférences système\n1. Réseau\n1. Ethernet et/ou Wi-fi\n1. Avancé\n1. DNS\n1. Serveurs DNS\n\nDe là, vous pouvez ajouter des serveurs DNS en cliquant sur l'icône +. Cliquez sur ok et appliquez les nouveaux paramètres. Vous devrez peut-être redémarrer votre ordinateur pour que les changements fonctionnent.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS réglages réseau et DNS'\n/>\n\n### Sur Windows (ici 10)\n\nOuvrez :\n\n1. Réglages\n1. Réseau et internet\n1. Modifier les options de l'adaptateur\n1. Clic droit sur les propriétés de votre interface réseau\n1. Selectionnez « protocole Internet version 4 » (et/ou 6)\n1. Propriétés\n1. Utiliser l’adresse de serveur DNS suivante\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Réglages windows'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows réglages réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows régalges connections réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows options adaptateur réseau'\n/>\n\n## Quels serveurs DNS utiliser ?\n\nIl y a de nombreux serveurs DNS accessibles. Les plus connus étant ceux de Google, Cloudflare et OpenDNS. Si vous tenez vraiment à utiliser ceux de Google, je vous laisse chercher leur adresse. Voici mes recommandations par ordre de préférence.\n\nPlusieurs fournisseurs :\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMes favoris puisqu’il s’agit d’une [association française.](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net/fr)\n\nQuand9 est une fondation à but non lucratif proposant des serveurs DNS publics et gratuits. Leurs serveur classiques offrent un filtrage de domaines malveillants identifiés. Ils ne collectent pas de données et sont conforment au \u003Cabbr title=\"Règlement général sur la protection des données\">RGPD\u003C/abbr>.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## C'est tout.\n\nEn modifiant ces réglages, vous vous affranchissez de vos fournisseurs d’accès et de leurs règles de filtrage du contenu.\n\nPour l’instant, ces blocages sont presque symboliques car si Sci-hub venait à changer d’url, le blocage ne fonctionnerait plus. Mais la victoire des éditeurs au tribunal montre qu’ils n’ont pas dit leur dernier mot. Nous ne sommes donc pas à l’abri d’un futur blocage plus large et plus dur à contrer.\n\nSi vous voulez en apprendre plus sur le combat de ces gens qui se battent pour que la recherche ne soit pas une marchandise, je vous conseille [ce documentaire](https://youtu.be/y_CQATGOX2w) sur Aaron Shwartz. Ou plus simplement [cet article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) sur la fondatrice de Sci-hub.\n\nEn attendant, bonnes lectures à tou·te·s. On est avec vous !","src/content/articles/fr/sci-hub-blocage.mdx","3a003b105dcd5e24","after-effects-expressions",{"id":398,"data":400,"body":404,"filePath":405,"digest":406,"rendered":407},{"title":178,"subtitle":401,"lang":15,"tags":402,"type":173,"slug":398,"createdAt":403,"draft":184},"En cours de traduction, revenez bientôt ;)",[182],["Date","2019-04-24T09:00:00.000Z"],"[Retour aux articles](/articles)","src/content/articles/fr/after-effects-expressions.md","884d725859a7bab5",{"html":408,"metadata":409},"\u003Cp>\u003Ca href=\"/articles\">Retour aux articles\u003C/a>\u003C/p>",{"headings":410,"imagePaths":411,"frontmatter":412},[],[],{"title":178,"subtitle":401,"lang":15,"draft":184,"slug":398,"excerpt":401,"tags":413,"type":173,"createdAt":414},[182],"2019-04-24T09:00:00.000Z","video-compression",{"id":415,"data":417,"body":404,"filePath":422,"digest":423,"rendered":424},{"title":418,"subtitle":401,"lang":15,"tags":419,"type":173,"slug":415,"createdAt":420,"updatedAt":421,"draft":184},"Compression vidéo",[182],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"src/content/articles/fr/video-compression.md","2296c41874b23b3d",{"html":408,"metadata":425},{"headings":426,"imagePaths":427,"frontmatter":428},[],[],{"title":418,"subtitle":401,"lang":15,"draft":184,"slug":415,"excerpt":429,"tags":430,"type":173,"createdAt":431,"updatedAt":269},"Pas encore traduit",[182],"2021-05-05T09:00:00.000Z","faq",{"id":432,"data":434,"body":439,"filePath":440,"digest":441,"rendered":442},{"title":435,"subtitle":436,"lang":15,"tags":437,"type":173,"slug":432,"createdAt":438},"Accessibilité, sobriété et F.A.Q.","Explications sur ma vision et mon fonctionnement.",[194],["Date","2022-06-22T15:34:45.000Z"],"## l'Accessibilité\n\n### Quèsaco ?\n\nD'après [access42 :](https://access42.net)\n\n> L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\n\nAinsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que **n'importe quel visiteur** puisse l'utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais **ce n'est pas le cas !**\n\nLorsqu'un site est pensé et conçu avec l'accessibilité en tête, il ne prend **pas plus de temps** qu'un projet qui ne le fait pas. En revanche, **corriger** un site existant qui n'a pas bénéficié de cette réflexion en amont **demande beaucoup plus d'efforts.**\n\n### Pourquoi c'est important ?\n\nAprès avoir été sensibilisé à l'accessibilité et aux [situations frustrantes voire bloquantes](https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles) que rencontrent les personnes handicapées sur le web, j'ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m'a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\n\n## l'Éco-conception\n\n### Quèsaco ?\n\nD'après le collectif [\u003Cspan lang=\"en\">green it\u003C/span> :](https://www.greenit.fr)\n\n> L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\n\nIl s'agit ici pour moi de créer des produits les plus sobres possibles. C'est-à-dire de développer ou d'utiliser une fonctionnalité uniquement si elle est indispensable.\n\nPar exemple, mettre en place **un formulaire de contact** sur un site web implique plusieurs choses :\n\n- développer un formulaire\n- envoyer les données au serveur\n- vérifier les données envoyées\n- envoyer les données par mail\n- confirmer l'envoi du mail (en fournissant une copie)\n- gérer les erreurs à chaque étape\n\nUn site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d'effectuer ces opérations (ou un prestataire qui s'en charge). C'est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu'un formulaire. Dans le cas d'un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\n\n### Pourquoi c'est important ?\n\nL'éco-conception fait beaucoup de bien à la qualité globale d'un site et à l'expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\n\n## F.A.Q.\n\n### Cette démarche est-elle opportuniste ?\n\n**Non.** Il est vrai que l'accessibilité et, surtout, l'éco-conception, commencent à être « tendance ». On pourrait donc croire que j'en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c'est ma responsabilité de créer des sites web accessibles et éco-conçus **par défaut.**\n\n### Un site accessible est-il plus cher ?\n\n**Oui et non.** Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l'accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j'augmente mes tarifs suite à l'obtention de certifications relatives à mon activité.\n\n### Mon site sera-t-il 100 % accessible ?\n\n**Non,** je ne suis pas en mesure de garantir ou de certifier la conformité totale d'un site au [référentiel général d'amélioration de l'accessibilité.](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d'un site. Cependant, je peux vous accompagner avant et après l'audit afin d'anticiper puis de corriger les critères d'accessibilité requis. [Access42](https://access42.net/) et [Tanaguru](https://www.tanaguru.com/) font parties de ces entreprises spécialisées.\n\n### Pourquoi ne pas utiliser un outil automatique ?\n\nCar ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom [sous peine de procès](https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/)), ne sont pas des solutions micracles. Lisez [cet article](https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/) d'une experte en accessibilité et/ou [ce test](https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/) de différents outils pour en savoir plus.\n\n### Un site éco-conçu et accessible peut-il être beau ?\n\n**Oui, évidemment.** Je vous laisse juger par vous-même avec [cette liste](https://lowww.directory/) de sites éco-conçus. En ce qui concerne l'accessibilité, elle n'impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d'un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l'utilisation d'un produit.","src/content/articles/fr/faq.md","65e9e60bcd00806c",{"html":443,"metadata":444},"\u003Ch2 id=\"laccessibilité\">l’Accessibilité\u003C/h2>\n\u003Ch3 id=\"quèsaco\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après \u003Ca href=\"https://access42.net\">access42 :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Ainsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que \u003Cstrong>n’importe quel visiteur\u003C/strong> puisse l’utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais \u003Cstrong>ce n’est pas le cas !\u003C/strong>\u003C/p>\n\u003Cp>Lorsqu’un site est pensé et conçu avec l’accessibilité en tête, il ne prend \u003Cstrong>pas plus de temps\u003C/strong> qu’un projet qui ne le fait pas. En revanche, \u003Cstrong>corriger\u003C/strong> un site existant qui n’a pas bénéficié de cette réflexion en amont \u003Cstrong>demande beaucoup plus d’efforts.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>Après avoir été sensibilisé à l’accessibilité et aux \u003Ca href=\"https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles\">situations frustrantes voire bloquantes\u003C/a> que rencontrent les personnes handicapées sur le web, j’ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m’a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\u003C/p>\n\u003Ch2 id=\"léco-conception\">l’Éco-conception\u003C/h2>\n\u003Ch3 id=\"quèsaco-1\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après le collectif \u003Ca href=\"https://www.greenit.fr\">\u003Cspan lang=\"en\">green it\u003C/span> :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Il s’agit ici pour moi de créer des produits les plus sobres possibles. C’est-à-dire de développer ou d’utiliser une fonctionnalité uniquement si elle est indispensable.\u003C/p>\n\u003Cp>Par exemple, mettre en place \u003Cstrong>un formulaire de contact\u003C/strong> sur un site web implique plusieurs choses :\u003C/p>\n\u003Cul>\n\u003Cli>développer un formulaire\u003C/li>\n\u003Cli>envoyer les données au serveur\u003C/li>\n\u003Cli>vérifier les données envoyées\u003C/li>\n\u003Cli>envoyer les données par mail\u003C/li>\n\u003Cli>confirmer l’envoi du mail (en fournissant une copie)\u003C/li>\n\u003Cli>gérer les erreurs à chaque étape\u003C/li>\n\u003C/ul>\n\u003Cp>Un site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d’effectuer ces opérations (ou un prestataire qui s’en charge). C’est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu’un formulaire. Dans le cas d’un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important-1\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>L’éco-conception fait beaucoup de bien à la qualité globale d’un site et à l’expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\u003C/p>\n\u003Ch2 id=\"faq\">F.A.Q.\u003C/h2>\n\u003Ch3 id=\"cette-démarche-est-elle-opportuniste\">Cette démarche est-elle opportuniste ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non.\u003C/strong> Il est vrai que l’accessibilité et, surtout, l’éco-conception, commencent à être « tendance ». On pourrait donc croire que j’en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c’est ma responsabilité de créer des sites web accessibles et éco-conçus \u003Cstrong>par défaut.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"un-site-accessible-est-il-plus-cher\">Un site accessible est-il plus cher ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui et non.\u003C/strong> Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l’accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j’augmente mes tarifs suite à l’obtention de certifications relatives à mon activité.\u003C/p>\n\u003Ch3 id=\"mon-site-sera-t-il-100-accessible\">Mon site sera-t-il 100 % accessible ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non,\u003C/strong> je ne suis pas en mesure de garantir ou de certifier la conformité totale d’un site au \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité.\u003C/a> Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d’un site. Cependant, je peux vous accompagner avant et après l’audit afin d’anticiper puis de corriger les critères d’accessibilité requis. \u003Ca href=\"https://access42.net/\">Access42\u003C/a> et \u003Ca href=\"https://www.tanaguru.com/\">Tanaguru\u003C/a> font parties de ces entreprises spécialisées.\u003C/p>\n\u003Ch3 id=\"pourquoi-ne-pas-utiliser-un-outil-automatique\">Pourquoi ne pas utiliser un outil automatique ?\u003C/h3>\n\u003Cp>Car ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom \u003Ca href=\"https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/\">sous peine de procès\u003C/a>), ne sont pas des solutions micracles. Lisez \u003Ca href=\"https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/\">cet article\u003C/a> d’une experte en accessibilité et/ou \u003Ca href=\"https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/\">ce test\u003C/a> de différents outils pour en savoir plus.\u003C/p>\n\u003Ch3 id=\"un-site-éco-conçu-et-accessible-peut-il-être-beau\">Un site éco-conçu et accessible peut-il être beau ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui, évidemment.\u003C/strong> Je vous laisse juger par vous-même avec \u003Ca href=\"https://lowww.directory/\">cette liste\u003C/a> de sites éco-conçus. En ce qui concerne l’accessibilité, elle n’impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d’un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l’utilisation d’un produit.\u003C/p>",{"headings":445,"imagePaths":479,"frontmatter":480},[446,449,452,455,458,460,462,464,467,470,473,476],{"depth":26,"slug":447,"text":448},"laccessibilité","l’Accessibilité",{"depth":70,"slug":450,"text":451},"quèsaco","Quèsaco ?",{"depth":70,"slug":453,"text":454},"pourquoi-cest-important","Pourquoi c’est important ?",{"depth":26,"slug":456,"text":457},"léco-conception","l’Éco-conception",{"depth":70,"slug":459,"text":451},"quèsaco-1",{"depth":70,"slug":461,"text":454},"pourquoi-cest-important-1",{"depth":26,"slug":432,"text":463},"F.A.Q.",{"depth":70,"slug":465,"text":466},"cette-démarche-est-elle-opportuniste","Cette démarche est-elle opportuniste ?",{"depth":70,"slug":468,"text":469},"un-site-accessible-est-il-plus-cher","Un site accessible est-il plus cher ?",{"depth":70,"slug":471,"text":472},"mon-site-sera-t-il-100-accessible","Mon site sera-t-il 100 % accessible ?",{"depth":70,"slug":474,"text":475},"pourquoi-ne-pas-utiliser-un-outil-automatique","Pourquoi ne pas utiliser un outil automatique ?",{"depth":70,"slug":477,"text":478},"un-site-éco-conçu-et-accessible-peut-il-être-beau","Un site éco-conçu et accessible peut-il être beau ?",[],{"title":435,"subtitle":436,"lang":15,"slug":432,"excerpt":481,"tags":482,"type":173,"createdAt":362},"Pourquoi, comment et surtout quèsaco.",[194],"the-day-I-jamd",{"id":483,"data":485,"body":490,"filePath":491,"digest":492,"deferredRender":184},{"title":366,"subtitle":486,"lang":15,"tags":487,"type":173,"slug":483,"createdAt":488,"updatedAt":489},"Des paris, des outils et du fun.",[369,370],["Date","2020-10-08T07:47:36.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## La solution de non facilité\n\nLorsque j’utilisais encore Wordpress pour mon site web personnel, j’ai voulu essayer le serveur web \u003Ca href=\"https://openlitespeed.org\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">OpenLiteSpeed (en anglais)\u003C/a>. En tant que designer, j’ai toujours aimé avoir une interface graphique et j’avais entendu dire qu’OLS jouissait de bonnes performances en général et de cache en particulier.\n\n## Battez-vous!\n\nQuelques années plus tard, je découvrais l’univers Jamstack et son incroyable potentiel. N’étant pas du tout impulsif, j’ai choisi de refaire entièrement mon site web avec des outils comme \u003Ca href=\"https://www.11ty.dev/\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">11ty (en anglais)\u003C/a> et \u003Ca href=\"https://strapi.io/\" hreflang=\"en\">Strapi (en anglais)\u003C/a>.\n\nJe me souviens que Strapi était encore en alpha/beta et que certains collègues me disaient que c’était un pari risqué, surtout que je découvrais à peine le monde de node.js.\n\n> Open source et français ? Je dis banco !\n\nJ’ai donc commencé à recréer mon site web à l’identique avec 11ty et Strapi. Même hébergement chez Digital Ocean, même serveur web, même contenu. J’avais fait pas mal d’optimisations de performances sur mon installation wordpress, j’étais donc impatient de comparer les résultats avec la nouvelle version statique.\n\nJ’en suis resté pantois ! Quasiment sans optimisation du côté statique, j’ai obtenu les résultats ci-dessous.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 53/100 sur Wordpress.'\n/>\n\nMalgré beaucoup d’efforts, je n’ai pas pu faire mieux. Je ne suis pas un expert en cache, je n’utilise pas de CDN et je me suis appuyé sur des plugins pour réaliser beaucoup de choses (php n’étant pas ma spécialité 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 97/100 en Jamstack.'\n/>\n\nPresque **zéro** configuration spéciale (j’étais trop impatient de tester) et j’ai atteint un score impressionnant. Je sais que les scores lighthouse ne font pas tout mais **53 contre 97**… Ça me va !\n\n## Embrassez-vous 🥰\n\nCes deux approches ont leurs avantages et leurs inconvénients. En tant que freelance, mes clients préfèrent ou demandent souvent Wordpress en raison de sa réputation. Je présente toujours une alternative Jamstack lorsque c’est possible, mais cela reste effrayant la plupart du temps par rapport à Wordpress. Je pense cependant qu’il sera plus facile d’utiliser la Jamstack avec le temps.\n\n## Encore et encore…\n\nNous voici maintenant une quarantaine et quelques mois plus tard et ce site fonctionne avec… [Nuxt.js](https://fr.nuxtjs.org/). Je sais, je suis désolé, je n’ai pas pu résister à la dernière fonctionnalité [\u003Cspan lang=\"en\">nuxt content\u003C/span>](https://content.nuxtjs.org/fr) de Nuxt.\n\nDu coup j’ai tout refait… et laissez-moi vous dire : **wow**, quelle expérience !\nJ’adore développer avec Nuxt. L’utilisation de \u003Cspan lang=\"en\">nuxt content\u003C/span> m’a permis de me concentrer sur le design et, évidemment, sur le contenu.\nPlus de client Apollo ni de requête graphQL, seulement du \u003Cspan lang=\"en\">markdown\u003C/span> et quelques promesses.\n\nAttention, j’aime beaucoup travailler avec Strapi et son interface graphQL mais pour les besoins de ce site, \u003Cspan lang=\"en\">nuxt content\u003C/span> fait le \u003Cspan lang=\"en\">job\u003C/span> (extrêmement bien).\n\nJ’utilise toujours Strapi pour téléverser, stocker et gérer les images, vidéos, gifs, etc. C’est peut-être trop pour ce que j’en fait mais j’aime savoir que je peux toujours y revenir si j’ai envie ! De plus, j’ai passé pas mal de temps à le mettre en place avec \u003Cspan lang=\"en\">OpenLiteSpeed\u003C/span> et je suis encore trop attaché à cette réussite pour la laisser tomber.\n\n## Et en fait à la fin\n\nWordpress, Jamstack, fait main… Est-ce vraiment important ? Pour moi, l’expérience de développement a été bien plus agréable en travaillant avec 11ty, nuxt.js et strapi qu’avec Wordpress.\n\nDu point de vue de la performance et de l’accessibilité, il semble également que ce soit le choix le plus judicieux. Ce n’est peut-être pas le cas à chaque fois ! ¯\\\\\\_(ツ)\\_/¯\n\nJ’ai hâte d’apprendre \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> et de tout recommencer à zéro !","src/content/articles/fr/the-day-I-jamd.mdx","57bd292bda8b6632","gratuiste",{"id":493,"data":495,"body":501,"filePath":502,"digest":503,"rendered":504},{"title":273,"subtitle":496,"lang":15,"tags":497,"type":173,"slug":493,"createdAt":499,"updatedAt":500},"Ou le travail gratuit.",[498,194],"Graphisme",["Date","2017-05-27T07:47:36.000Z"],["Date","2022-12-27T15:36:06.000Z"],"## Gratuiste, qu’est-ce que c’est ?\n\nDans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc. \nDe plus en plus, la communauté s’élève contre ces pratiques et les [dénonce.](https://twitter.com/PayeTonAffiche)\n\n> “ On n’est pas des gratuistes ! ”\n\nComprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez [cette vidéo](https://youtu.be/essNmNOrQto) qui transpose ces pratiques à des métiers “ standards ” et [celle-ci](https://youtu.be/DsstOs-K7gk) qui explique en détails le processus actuel.\n\n## T’es débile du coup ?\n\nJ’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\n\nÉtant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre. \nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\n\n## Le concept\n\nJe compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux. \nCe type de prestation porte le nom de “ **pro bono publico** ” – “ **pour le bien public** ”.\n\nCette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\n\n> Graphiste pro bono, pourquoi pas ?\n\n## Quels genres de services ?\n\nEn toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\n\n### En résumé :\n\n- maquette de site web\n- intégration front-end (en dur ou via wordpress) du site\n- gestion de la mise en ligne du site\n- newsletter (design et/ou intégration)\n- flyers\n- autres petites demandes\n\nVous pouvez avoir un aperçu de mon travail [sur ce même site.](/) J’ai déjà eu l’occasion de travailler pour :\n\n- [Cygnal](/projets/cygnal)\n- [OpenMole](https://openmole.org/)\n- [Good-it](https://good-it.org)\n\n## Dans quelles conditions ?\n\n- l’association doit être active\n- elle doit porter des valeurs que je partage\n- elle doit pouvoir me montrer ses actions\n- elle ne doit pas avoir les moyens de se payer un graphiste\n\n## C’est un peu trop beau pour être vrai ton truc…\n\nIl faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\n\nSi vous êtes intéressés, [envoyez-moi un mail !](mailto:contac@nardu.in)\n\n## Qu’est-ce que t’y gagnes toi ?\n\nSimplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.","src/content/articles/fr/gratuiste.md","80c20493583a842c",{"html":505,"metadata":506},"\u003Ch2 id=\"gratuiste-quest-ce-que-cest\">Gratuiste, qu’est-ce que c’est ?\u003C/h2>\n\u003Cp>Dans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc.\u003Cbr>\nDe plus en plus, la communauté s’élève contre ces pratiques et les \u003Ca href=\"https://twitter.com/PayeTonAffiche\">dénonce.\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“ On n’est pas des gratuistes ! ”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Comprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez \u003Ca href=\"https://youtu.be/essNmNOrQto\">cette vidéo\u003C/a> qui transpose ces pratiques à des métiers “ standards ” et \u003Ca href=\"https://youtu.be/DsstOs-K7gk\">celle-ci\u003C/a> qui explique en détails le processus actuel.\u003C/p>\n\u003Ch2 id=\"tes-débile-du-coup\">T’es débile du coup ?\u003C/h2>\n\u003Cp>J’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\u003C/p>\n\u003Cp>Étant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre.\u003Cbr>\nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\u003C/p>\n\u003Ch2 id=\"le-concept\">Le concept\u003C/h2>\n\u003Cp>Je compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux.\u003Cbr>\nCe type de prestation porte le nom de “ \u003Cstrong>pro bono publico\u003C/strong> ” – “ \u003Cstrong>pour le bien public\u003C/strong> ”.\u003C/p>\n\u003Cp>Cette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Graphiste pro bono, pourquoi pas ?\u003C/p>\n\u003C/blockquote>\n\u003Ch2 id=\"quels-genres-de-services\">Quels genres de services ?\u003C/h2>\n\u003Cp>En toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\u003C/p>\n\u003Ch3 id=\"en-résumé\">En résumé :\u003C/h3>\n\u003Cul>\n\u003Cli>maquette de site web\u003C/li>\n\u003Cli>intégration front-end (en dur ou via wordpress) du site\u003C/li>\n\u003Cli>gestion de la mise en ligne du site\u003C/li>\n\u003Cli>newsletter (design et/ou intégration)\u003C/li>\n\u003Cli>flyers\u003C/li>\n\u003Cli>autres petites demandes\u003C/li>\n\u003C/ul>\n\u003Cp>Vous pouvez avoir un aperçu de mon travail \u003Ca href=\"/\">sur ce même site.\u003C/a> J’ai déjà eu l’occasion de travailler pour :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"/projets/cygnal\">Cygnal\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://openmole.org/\">OpenMole\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://good-it.org\">Good-it\u003C/a>\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"dans-quelles-conditions\">Dans quelles conditions ?\u003C/h2>\n\u003Cul>\n\u003Cli>l’association doit être active\u003C/li>\n\u003Cli>elle doit porter des valeurs que je partage\u003C/li>\n\u003Cli>elle doit pouvoir me montrer ses actions\u003C/li>\n\u003Cli>elle ne doit pas avoir les moyens de se payer un graphiste\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"cest-un-peu-trop-beau-pour-être-vrai-ton-truc\">C’est un peu trop beau pour être vrai ton truc…\u003C/h2>\n\u003Cp>Il faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\u003C/p>\n\u003Cp>Si vous êtes intéressés, \u003Ca href=\"mailto:contac@nardu.in\">envoyez-moi un mail !\u003C/a>\u003C/p>\n\u003Ch2 id=\"quest-ce-que-ty-gagnes-toi\">Qu’est-ce que t’y gagnes toi ?\u003C/h2>\n\u003Cp>Simplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.\u003C/p>",{"headings":507,"imagePaths":532,"frontmatter":533},[508,511,514,517,520,523,526,529],{"depth":26,"slug":509,"text":510},"gratuiste-quest-ce-que-cest","Gratuiste, qu’est-ce que c’est ?",{"depth":26,"slug":512,"text":513},"tes-débile-du-coup","T’es débile du coup ?",{"depth":26,"slug":515,"text":516},"le-concept","Le concept",{"depth":26,"slug":518,"text":519},"quels-genres-de-services","Quels genres de services ?",{"depth":70,"slug":521,"text":522},"en-résumé","En résumé :",{"depth":26,"slug":524,"text":525},"dans-quelles-conditions","Dans quelles conditions ?",{"depth":26,"slug":527,"text":528},"cest-un-peu-trop-beau-pour-être-vrai-ton-truc","C’est un peu trop beau pour être vrai ton truc…",{"depth":26,"slug":530,"text":531},"quest-ce-que-ty-gagnes-toi","Qu’est-ce que t’y gagnes toi ?",[],{"title":273,"subtitle":496,"lang":15,"slug":493,"excerpt":534,"tags":535,"type":173,"createdAt":287,"updatedAt":536},"J’ai cherché un moyen de mettre mes compétences au service d’autrui et je pense avoir trouvé: je vais travailler gratuitement pour des associations.",[498,194],"2022-12-27T15:36:06.000Z","veille",["Map",318,539],{"id":318,"data":540,"body":542,"filePath":543,"digest":544,"rendered":545},{"lang":15,"title":318,"updatedAt":541},["Date","2023-04-20T17:12:06.000Z"],"- [mmm.page](https://build.mmm.page/) - Éditeur de sites web très simples, en glisser-déposer, pour n'importe quoi.\n- [Color.io](https://www.color.io/) - Éditeur photo en ligne.\n- [Addy's toolkit](https://toolkit.addy.codes/) - Outils et ressources pour les designers et développeurs sites web.\n- [L’accessibilité n’est pas une variable d’ajustement](https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/) — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n > L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\n- [3D en CSS (english)](https://garden.bradwoods.io/notes/css/3d) – Explications et exemples des propriétés 3D en CSS.\n- [Climat : Comment ne pas déprimer ?](https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html) – Podcast.\n- [Fable (english)](https://fable.app) – Application de motion design.\n- [Rive (english)](https://rive.app) – Application de motion design.\n- [Cake Desk](https://cakedesk.app/) – Application de facturation.\n- [Ombre fluide en CSS](https://shadows.brumm.af/) – Générateur.\n- [Smol CSS](https://smolcss.dev/) – Collection de fragments CSS.\n- [Ajustement optique](https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/) (english) – Aligner visuellement plutôt que techniquement.\n- [Datawrapper](https://blog.datawrapper.de/category/datavis-dos-and-donts/) (english) – Conseils pour montrer de la donnée.\n- [Assistivlabs](https://assistivlabs.com/) (english) – Service de test des technologies d'assistance (browserstack mais pour l'accessibilité).\n- [Les caractères fantaisistes et l'accessibilité](https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/) – Explications et exemples de l'enfer que sont les caractères Unicode pour les technologies d'assistance.\n- [Créer un champ `time` sur le web](https://adamsilver.io/blog/designing-a-time-input-backed-by-research/) (english) – Article.\n- [La cascade](https://la-cascade.io) – Collection d'articles sur le CSS.\n- [Tabby](https://tabby.sh) (english) – An alternative terminal app.\n- [Newglyph](https://newglyph.com/) – Fonderie indépendante.\n- [\u003Cspan lang=\"en\">Headless UI\u003C/span>](https://headlessui.com/vue/dialog) (english) – Librairie de composants vue et react.\n- [Vie privée sexy](https://privacy.sexy) (english) – Outils de confidentialité pour windows et macos.\n- [33 concepts JavaScript](https://github.com/leonardomso/33-js-concepts) (english) – Articles.\n- [Formbricks](https://formbricks.com/) (english) – Alternative open source à google form/typeform.\n- [Animations de chargement SVG](https://github.com/n3r4zzurr0/svg-spinners) – Collection.\n- [a11yphant](https://a11yphant.com/) (english) – Challenges de code pour apprendre l'accessibilité.\n- [CSS moderne](https://moderncss.dev/) (english) – Fragments CSS.\n- [Conteneur moderne en CSS](https://twitter.com/KevinJPowell/status/1501555193799925761) (english) – Tweet de Kevin Powell ❤️","src/data/veille/2023.md","1135beec386f207f",{"html":546,"metadata":547},"\u003Cul>\n\u003Cli>\u003Ca href=\"https://build.mmm.page/\">mmm.page\u003C/a> - Éditeur de sites web très simples, en glisser-déposer, pour n’importe quoi.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.color.io/\">Color.io\u003C/a> - Éditeur photo en ligne.\u003C/li>\n\u003Cli>\u003Ca href=\"https://toolkit.addy.codes/\">Addy’s toolkit\u003C/a> - Outils et ressources pour les designers et développeurs sites web.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/\">L’accessibilité n’est pas une variable d’ajustement\u003C/a> — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n\u003Cblockquote>\n\u003Cp>L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\u003C/p>\n\u003C/blockquote>\n\u003C/li>\n\u003Cli>\u003Ca href=\"https://garden.bradwoods.io/notes/css/3d\">3D en CSS (english)\u003C/a> – Explications et exemples des propriétés 3D en CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html\">Climat : Comment ne pas déprimer ?\u003C/a> – Podcast.\u003C/li>\n\u003Cli>\u003Ca href=\"https://fable.app\">Fable (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://rive.app\">Rive (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://cakedesk.app/\">Cake Desk\u003C/a> – Application de facturation.\u003C/li>\n\u003Cli>\u003Ca href=\"https://shadows.brumm.af/\">Ombre fluide en CSS\u003C/a> – Générateur.\u003C/li>\n\u003Cli>\u003Ca href=\"https://smolcss.dev/\">Smol CSS\u003C/a> – Collection de fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/\">Ajustement optique\u003C/a> (english) – Aligner visuellement plutôt que techniquement.\u003C/li>\n\u003Cli>\u003Ca href=\"https://blog.datawrapper.de/category/datavis-dos-and-donts/\">Datawrapper\u003C/a> (english) – Conseils pour montrer de la donnée.\u003C/li>\n\u003Cli>\u003Ca href=\"https://assistivlabs.com/\">Assistivlabs\u003C/a> (english) – Service de test des technologies d’assistance (browserstack mais pour l’accessibilité).\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/\">Les caractères fantaisistes et l’accessibilité\u003C/a> – Explications et exemples de l’enfer que sont les caractères Unicode pour les technologies d’assistance.\u003C/li>\n\u003Cli>\u003Ca href=\"https://adamsilver.io/blog/designing-a-time-input-backed-by-research/\">Créer un champ \u003Ccode>time\u003C/code> sur le web\u003C/a> (english) – Article.\u003C/li>\n\u003Cli>\u003Ca href=\"https://la-cascade.io\">La cascade\u003C/a> – Collection d’articles sur le CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://tabby.sh\">Tabby\u003C/a> (english) – An alternative terminal app.\u003C/li>\n\u003Cli>\u003Ca href=\"https://newglyph.com/\">Newglyph\u003C/a> – Fonderie indépendante.\u003C/li>\n\u003Cli>\u003Ca href=\"https://headlessui.com/vue/dialog\">\u003Cspan lang=\"en\">Headless UI\u003C/span>\u003C/a> (english) – Librairie de composants vue et react.\u003C/li>\n\u003Cli>\u003Ca href=\"https://privacy.sexy\">Vie privée sexy\u003C/a> (english) – Outils de confidentialité pour windows et macos.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/leonardomso/33-js-concepts\">33 concepts JavaScript\u003C/a> (english) – Articles.\u003C/li>\n\u003Cli>\u003Ca href=\"https://formbricks.com/\">Formbricks\u003C/a> (english) – Alternative open source à google form/typeform.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/n3r4zzurr0/svg-spinners\">Animations de chargement SVG\u003C/a> – Collection.\u003C/li>\n\u003Cli>\u003Ca href=\"https://a11yphant.com/\">a11yphant\u003C/a> (english) – Challenges de code pour apprendre l’accessibilité.\u003C/li>\n\u003Cli>\u003Ca href=\"https://moderncss.dev/\">CSS moderne\u003C/a> (english) – Fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/KevinJPowell/status/1501555193799925761\">Conteneur moderne en CSS\u003C/a> (english) – Tweet de Kevin Powell ❤️\u003C/li>\n\u003C/ul>",{"headings":548,"imagePaths":549,"frontmatter":550},[],[],{"lang":15,"title":318,"updatedAt":551},"2023-04-20T17:12:06.000Z","fragments",["Map",554,555,566,567,584,585,601,602,612,613,667,668,677,678,688,689,699,700,712,713,747,748,771,772,813,814,853,854,887,888,951,952],"en-image-full",{"id":554,"data":556,"body":563,"filePath":564,"digest":565,"deferredRender":184},{"title":557,"subtitle":274,"lang":180,"tags":558,"type":560,"slug":554,"createdAt":561,"updatedAt":562,"draft":184},"Full width image",[559],"CSS","snippets",["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"[Go back to available snippets](/en/snippets)","src/content/fragments/en/image-full.mdx","2e3dddf593f6d72f","array-vs-array",{"id":566,"data":568,"body":574,"filePath":575,"digest":576,"rendered":577},{"title":569,"subtitle":570,"lang":15,"tags":571,"type":552,"slug":566,"createdAt":573,"draft":184},"Filtrer un array avec un autre array","En cours de traduction.",[572],"nuxt.js",["Date","2022-06-08T14:24:06.000Z"],"[Voir les fragments disponibles](/fragments)","src/content/fragments/fr/array-vs-array.md","7321d444177c3841",{"html":578,"metadata":579},"\u003Cp>\u003Ca href=\"/fragments\">Voir les fragments disponibles\u003C/a>\u003C/p>",{"headings":580,"imagePaths":581,"frontmatter":582},[],[],{"title":569,"subtitle":570,"lang":15,"draft":184,"slug":566,"createdAt":269,"excerpt":570,"tags":583,"type":552},[572],"en-visited-links",{"id":584,"data":586,"body":563,"filePath":590,"digest":591,"rendered":592},{"title":587,"subtitle":274,"lang":180,"tags":588,"type":560,"slug":584,"createdAt":589,"draft":184},"Visited links and visuel aid",[132],["Date","2023-06-06T18:34:00.000Z"],"src/content/fragments/en/visited-links.md","cb7c11c12c25067e",{"html":593,"metadata":594},"\u003Cp>\u003Ca href=\"/en/snippets\">Go back to available snippets\u003C/a>\u003C/p>",{"headings":595,"imagePaths":596,"frontmatter":597},[],[],{"title":587,"subtitle":274,"lang":180,"draft":184,"slug":584,"excerpt":598,"tags":599,"type":560,"createdAt":600},"Petit hack CSS",[132],"2023-06-06T18:34:00.000Z","en-super-cookies",{"id":601,"data":603,"body":609,"filePath":610,"digest":611,"deferredRender":184},{"title":604,"subtitle":605,"lang":180,"tags":606,"type":560,"slug":601,"createdAt":608},"The best cookies","Consentless biscuits.",[607],"food",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 tablespoon of baking powder\n- 3/4 of aquafaba from 400g of chickpea (chickpea water)\n- 125 grams of coconut oil\n- 2 teaspoons of maple syrup\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- if necessary, melt the coconut oil over low heat\n- meanwhile, mix all the dry ingredients\n- add all liquid ingredients (oil, aquafaba, maple syrup)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Non vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 table spoon of baking powder\n- 1 egg\n- 125 grams of melted butter\n- 2 teaspoons of honey\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- melt butter over low heat\n- meanwhile, mix all dry ingredients\n- add all liquid ingredients (melted butter, egg, honey)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Notes\n\nChocolate can be replaced by anything like nuts, raisins, legos... (don't eat legos be reasonable).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='All ingredients mixed together to form a brown paste.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='The cookies are round and soft after baking.'\n/>","src/content/fragments/en/super-cookies.mdx","b0c67adad40c177c","en-toulouse-fun",{"id":612,"data":614,"body":620,"filePath":621,"digest":622,"rendered":623},{"title":615,"subtitle":616,"lang":180,"tags":617,"type":560,"slug":612,"createdAt":619},"Toulouse yourself","Only the bestest",[618],"lifestyle",["Date","2022-06-22T15:34:45.000Z"],"Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite. \n**It's always a good idea to make a reservation!**\n\n## Restaurants\n\n### French cuisine\n\n- [Solides](https://www.solides.fr/) — semi-gastronomic\n- [Les impulsifs](https://les-impulsifs-toulouse.eatbu.com/?lang=en) — semi-gastronomic\n- [Sixta](https://sixta-toulouse.fr/) — vege/vegan/gluten friendly\n- [Attila](https://attila.site-solocal.com/) — great **fish restaurant,** just above the Victor Hugo market\n- [Chez Emile](https://www.restaurant-emile.com/) - best [cassoulet](https://en.wikipedia.org/wiki/Cassoulet) in town (or so I'm told)\n\n### Korean\n\n- [Le ptit Louis](https://leptitlouis.fr/) — best of its kind, **only for lunch**\n- [Kongbap](https://kong-bap.com/) — street-food like\n\n### Japanese\n\n- [Iori](https://www.iori.fr/) — best ramen\n- [Japoyaki](https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402) — best sushi/sashimis\n\n## Drinks and snacks\n\n### Bars\n\n- [Le Bièrographe](https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327) — all time favourite, **check out the typical toulouse basement**\n- [A Taula](https://www.facebook.com/ataulatolosa/) — all time favourite in summer, **amazing terrace,** also: great tapas\n- [The Hopscotch Pub](https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385) — good beers, good whiskies, good cocktials, good food\n\n### Cafés & tea rooms\n\n- [Bapz](https://www.bapz.fr/contact) — Excellent pastries / hot beverages\n- [Ô thé divin](https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/) — nice lunch options\n- [Les Rêveries d’Hercule](https://www.lesreveriesdhercule.com/) — Pottery Café, relaxing activity (ceramics need to be baked, there'll be a delay to get them back)\n- Bonus: the best bakeries in [Carmes](https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872) and [Saint-Aubin](https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694) — croissants, baguettes **traditions**, chocolatines and more\n\n### Wine shops\n\n- [l'envie du sud](https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930) — amazing selection of wines and other spirits, excellent advice from the staff\n- [enoteca](https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952) — smaller selection but more beers and great advice from the staff as well\n\n## Other delights\n\n### Ice creams\n\n- [Forno gusto](https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450) — only in the summer\n- [Moustache](https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540) — lots of flavours\n\n### Cheese shop\n\n- [Xavier](https://xavier.fr/) — one of the **best of the country**, two shops in Toulouse, including one at Victor Hugo market\n- [Massembea](https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490) — a serious contender in Toulouse (weird hours)\n\n### Delicatessen\n\n- [Café Bacquié](http://cafe-bacquie.com/) — stock up on fine foods, coffees, teas and other great quality products","src/content/fragments/en/toulouse-fun.md","370491cc68079e8c",{"html":624,"metadata":625},"\u003Cp>Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite.\u003Cbr>\n\u003Cstrong>It’s always a good idea to make a reservation!\u003C/strong>\u003C/p>\n\u003Ch2 id=\"restaurants\">Restaurants\u003C/h2>\n\u003Ch3 id=\"french-cuisine\">French cuisine\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.solides.fr/\">Solides\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://les-impulsifs-toulouse.eatbu.com/?lang=en\">Les impulsifs\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://sixta-toulouse.fr/\">Sixta\u003C/a> — vege/vegan/gluten friendly\u003C/li>\n\u003Cli>\u003Ca href=\"https://attila.site-solocal.com/\">Attila\u003C/a> — great \u003Cstrong>fish restaurant,\u003C/strong> just above the Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.restaurant-emile.com/\">Chez Emile\u003C/a> - best \u003Ca href=\"https://en.wikipedia.org/wiki/Cassoulet\">cassoulet\u003C/a> in town (or so I’m told)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"korean\">Korean\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://leptitlouis.fr/\">Le ptit Louis\u003C/a> — best of its kind, \u003Cstrong>only for lunch\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://kong-bap.com/\">Kongbap\u003C/a> — street-food like\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"japanese\">Japanese\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.iori.fr/\">Iori\u003C/a> — best ramen\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402\">Japoyaki\u003C/a> — best sushi/sashimis\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"drinks-and-snacks\">Drinks and snacks\u003C/h2>\n\u003Ch3 id=\"bars\">Bars\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327\">Le Bièrographe\u003C/a> — all time favourite, \u003Cstrong>check out the typical toulouse basement\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.facebook.com/ataulatolosa/\">A Taula\u003C/a> — all time favourite in summer, \u003Cstrong>amazing terrace,\u003C/strong> also: great tapas\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385\">The Hopscotch Pub\u003C/a> — good beers, good whiskies, good cocktials, good food\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cafés--tea-rooms\">Cafés & tea rooms\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.bapz.fr/contact\">Bapz\u003C/a> — Excellent pastries / hot beverages\u003C/li>\n\u003Cli>\u003Ca href=\"https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/\">Ô thé divin\u003C/a> — nice lunch options\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lesreveriesdhercule.com/\">Les Rêveries d’Hercule\u003C/a> — Pottery Café, relaxing activity (ceramics need to be baked, there’ll be a delay to get them back)\u003C/li>\n\u003Cli>Bonus: the best bakeries in \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872\">Carmes\u003C/a> and \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694\">Saint-Aubin\u003C/a> — croissants, baguettes \u003Cstrong>traditions\u003C/strong>, chocolatines and more\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"wine-shops\">Wine shops\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930\">l’envie du sud\u003C/a> — amazing selection of wines and other spirits, excellent advice from the staff\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952\">enoteca\u003C/a> — smaller selection but more beers and great advice from the staff as well\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"other-delights\">Other delights\u003C/h2>\n\u003Ch3 id=\"ice-creams\">Ice creams\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450\">Forno gusto\u003C/a> — only in the summer\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540\">Moustache\u003C/a> — lots of flavours\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cheese-shop\">Cheese shop\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://xavier.fr/\">Xavier\u003C/a> — one of the \u003Cstrong>best of the country\u003C/strong>, two shops in Toulouse, including one at Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490\">Massembea\u003C/a> — a serious contender in Toulouse (weird hours)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"delicatessen\">Delicatessen\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"http://cafe-bacquie.com/\">Café Bacquié\u003C/a> — stock up on fine foods, coffees, teas and other great quality products\u003C/li>\n\u003C/ul>",{"headings":626,"imagePaths":663,"frontmatter":664},[627,630,633,636,639,642,645,648,651,654,657,660],{"depth":26,"slug":628,"text":629},"restaurants","Restaurants",{"depth":70,"slug":631,"text":632},"french-cuisine","French cuisine",{"depth":70,"slug":634,"text":635},"korean","Korean",{"depth":70,"slug":637,"text":638},"japanese","Japanese",{"depth":26,"slug":640,"text":641},"drinks-and-snacks","Drinks and snacks",{"depth":70,"slug":643,"text":644},"bars","Bars",{"depth":70,"slug":646,"text":647},"cafés--tea-rooms","Cafés & tea rooms",{"depth":70,"slug":649,"text":650},"wine-shops","Wine shops",{"depth":26,"slug":652,"text":653},"other-delights","Other delights",{"depth":70,"slug":655,"text":656},"ice-creams","Ice creams",{"depth":70,"slug":658,"text":659},"cheese-shop","Cheese shop",{"depth":70,"slug":661,"text":662},"delicatessen","Delicatessen",[],{"title":615,"subtitle":616,"lang":180,"slug":612,"excerpt":665,"tags":666,"type":560,"createdAt":362},"Gonna have to trust me on this ¯\\_(ツ)_/¯",[618],"buttons",{"id":667,"data":669,"body":674,"filePath":675,"digest":676,"deferredRender":184},{"title":670,"subtitle":671,"lang":15,"tags":672,"type":552,"slug":667,"createdAt":673,"code":184,"draft":184},"Effets de survol de boutons","Simples mais efficaces.",[559],["Date","2020-10-08T09:00:00.000Z"],"## Styles généraux\n\nTous les boutons présents utilisent ces styles comme base en guise de « reset » :\n\n> N'oubliez pas de préfixer si besoin !\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Ajout d'icône\n\n\u003Cbutton role='none' class='btn btn-icon'>\n\t\u003Cspan>Icône\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('./assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double volet\n\n\u003Cbutton role='none' class='btn btn-rideau'>\n\t\u003Cspan>Volet\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Dégradé animé\n\n\u003Cbutton role='none' class='btn btn-gradient'>\n\t\u003Cspan>Dégradé\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Échelle non desctructrice\n\n\u003Cbutton role='none' class='btn btn-scale'>\n\t\u003Cspan>Échelle\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/fr/buttons.mdx","f5d7b03520f96b04","image-full",{"id":677,"data":679,"body":685,"filePath":686,"digest":687,"deferredRender":184},{"title":680,"subtitle":681,"lang":15,"tags":682,"type":552,"slug":677,"createdAt":683,"updatedAt":684},"Image pleine largeur","Casser le conteneur.",[559],["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Image inline\n\nOn est parfois obligé d'utiliser des images dans des balises `img` plutôt que dans un `background` en css. Comment faire alors pour que l'image sorte de son conteneur pour en faire une bannière ? Exemple pratique à partir de ce même site.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_container_9e3939b3ae.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Contexte\n\nConsidérons le html suivant :\n\n```html\n\u003C!-- index.html -->\n\u003Csection class=\"container\">\n\t\u003Cdiv class=\"hero\">\n\t\t\u003Cimg class=\"hero__image\" src=\"hero.img\" />\n\t\u003C/div>\n\u003C/section>\n```\n\nEt le style suivant :\n\n```css\n/* style.css */\n.container {\n\tpadding: 0 14px;\n\tmargin-inline: auto;\n\tmax-inline-size: 1040px;\n}\nimg {\n\tmax-inline-size: 100%;\n\tblock-size: auto;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_original_d49f0d11bf.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Déborder du conteneur\n\nAfin de faire prendre à l'image toute la largeur, on agit sur son conteneur :\n\n```css\n/* style.css */\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_full_2a902f9539.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Faire une bannière\n\nOn peut alors réduire la hauteur du conteneur pour obtenir une bannière plutôt que l'image entière et faire correspondre la hauteur de l'image à la hauteur du conteneur :\n\n```css title='style.css' ins={5, 7-9}\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n\tblock-size: 200px;\n}\n.hero__image {\n\tblock-size: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_height_81b4ce969a.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nIl faut ensuite forcer l'image à prendre toute la largeur du conteneur :\n\n```css title='style.css' ins={3}\n.hero__image {\n\tblock-size: 100%;\n\tinline-size: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_deformed_479046d2cb.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nPas top…\n\n### J'ai cassé l'image…\n\n**ENFIN** le code magique pour redonner son ratio à l'image sans la déformer :\n\n```css title='style.css' ins={4,5}\n.hero__image {\n\tblock-size: 100%;\n\tinline-size: 100%;\n\tobject-fit: cover;\n\tobject-position: center; /* à positionner comme on veut */\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_6c164e82b3.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nCette technique s'apparente à l'utilisation d'une image de background.\n\n## TL;DR\n\nLe code complet :\n\n```css\n/* style.css */\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n\tblock-size: 200px;\n}\n.hero__image {\n\tinline-size: 100%;\n\tblock-size: 100%;\n\t-o-object-fit: cover;\n\tobject-fit: cover;\n\t-o-object-position: center;\n\tobject-position: center;\n}\n```","src/content/fragments/fr/image-full.mdx","585dcfae92fb08fb","super-cookies",{"id":688,"data":690,"body":696,"filePath":697,"digest":698,"deferredRender":184},{"title":691,"subtitle":692,"lang":15,"tags":693,"type":552,"slug":688,"createdAt":695},"Les meilleurs cookies","Des gâteaux sans consentement.",[694],"cuisine",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Version végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 3/4 de l'aquafaba de 400g de pois chiche (l'eau des pois chiche)\n- 125 grammes d'huile de noix de coco\n- 2 cuillères à café de sirop d'érable\n- 1 plaquette de chocolat (noir) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre si besoin l'huile de noix de coco à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (huile, aquafaba, sirop d'érable)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Version non végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 1 œuf\n- 125 grammes de beurre fondu\n- 2 cuillères à café de miel\n- 1 plaquette de chocolat (noir/blanc/les deux) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre le beurre à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (beurre fondu, œuf, miel)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Notes\n\nLe chocolat peut-être remplacé par n'importe quoi comme des noix, des raisins secs, des légos… (mangez pas des légos soyez sérieux).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Tous les ingrédients mélangés forment une pâte marron.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Les cookies cuits sont bombés et très moelleux.'\n/>","src/content/fragments/fr/super-cookies.mdx","f7a802e0b68cb04a","toulouse-fun",{"id":699,"data":701,"body":574,"filePath":704,"digest":705,"rendered":706},{"title":615,"subtitle":570,"lang":15,"tags":702,"type":552,"slug":699,"createdAt":703,"draft":184},[618],["Date","2022-06-22T15:34:45.000Z"],"src/content/fragments/fr/toulouse-fun.md","a0c25b438b34c05e",{"html":578,"metadata":707},{"headings":708,"imagePaths":709,"frontmatter":710},[],[],{"title":615,"subtitle":570,"lang":15,"draft":184,"slug":699,"createdAt":362,"excerpt":570,"tags":711,"type":552},[618],"visited-links",{"id":712,"data":714,"body":720,"filePath":721,"digest":722,"rendered":723},{"title":715,"subtitle":716,"lang":15,"tags":717,"type":560,"slug":712,"createdAt":718,"draft":719},"Liens visités et indication visuelle","Comment différencier les liens déjà cliqués",[132],["Date","2023-06-06T18:34:00.000Z"],false,"## La théorie\n\nIl est possible sur le web d'appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu'un lien visité est violet.\n\nGénéralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L'information qu'un lien a déjà été visité ne semble pas indispensable à la navigation. C'est sûrement vrai, mais personnellement, je suis assez content d'avoir un rappel des pages que j'ai déjà consultées lorsque je navigue.\n\nUne information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J'ai alors cherché un moyen d'ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n'est certainement pas idéale, elle se rapproche plus d'une expérience, à priori inoffensive pour l'internaute.\n\n## La spécification\n\nQuand je me suis intéressé à ce qu'il était possible de faire avec les liens déjà visités, j'ai découvert qu'extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu'il était possible de récupérer l'historique de navigation d'un utilisateur grâce aux styles des liens visités. Le sélecteur `:visited` a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. [Plus d'informations dans cet article.](https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector)\n\n## La pratique\n\nQue faire alors, en terme de style, quand on ne peut changer que des couleurs ?\n\nD'après MDN, les propriétés suivantes sont modifiables :\n\n- `color`\n- `background-color`\n- `border-color` (et les propriétés détaillées associées),\n- `column-rule-color`\n- `outline-color`\n- `text-decoration-color`\n- `text-emphasis-color`\n- Les composantes de couleur liées aux attributs SVG `fill` et `stroke`.\n\nChanger la couleur d'un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\n\nEn revanche, il est possible de \" masquer \" un élément en modifiant sa couleur pour qu'elle corresponde à la couleur du fond de la page ou de l'élément parent. On pourrait ainsi imaginer masquer une `border` ou un `outline`.\n\nJ'ai personnellement choisi de faire différemment. J'ai décidé d'utiliser un pseudo-élément `::before` sur l'état non visité du lien puis de le masquer quand celui-ci devient visité.\n\n### Le code\n\n```css {5,16} title=\"style.css\"\na {\n\tposition: relative;\n\ttext-decoration: none;\n}\na::before {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 0;\n\tinline-size: 2px;\n\tblock-size: 2px;\n\tborder-radius: 4px;\n\ttransform: translate(-6px, 0);\n\tbackground-color: grey;\n}\na:visited::before {\n\tbackground-color: white;\n}\n```\n\nCes règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\n\n### Accessibilité\n\nOn pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété `content` mais les lecteurs d'écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d'écrans annoncent déjà si un lien est visité avant de lire son intitulé.\n\n## Aller plus loin\n\nAfin de pousser l'expérience un peu plus loin, j'ai tenté d'utiliser des éléments plus explicites pour signifier l'état visité du lien. Bien qu'encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\n\nL'idée est d'avoir un `::before` et un `::after`, chacun contenant une icône en base 64 blanche en tant qu'image de fond. Quand le lien est non visité, le `::before` contient un fond coloré qui fait apparaître l'icône. Quand le lien passe en visité, le fond du `::before` devient blanc et celui du `::after` devient coloré, ce qui masque la première icône et affiche la deuxième.\n\nIl est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l'une sur l'autre.\n\n[Voir la démo sur codepen.](https://codepen.io/narduin/pen/VwVwmrO)","src/content/fragments/fr/visited-links.md","c062a565e4c30dfe",{"html":724,"metadata":725},"\u003Ch2 id=\"la-théorie\">La théorie\u003C/h2>\n\u003Cp>Il est possible sur le web d’appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu’un lien visité est violet.\u003C/p>\n\u003Cp>Généralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L’information qu’un lien a déjà été visité ne semble pas indispensable à la navigation. C’est sûrement vrai, mais personnellement, je suis assez content d’avoir un rappel des pages que j’ai déjà consultées lorsque je navigue.\u003C/p>\n\u003Cp>Une information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J’ai alors cherché un moyen d’ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n’est certainement pas idéale, elle se rapproche plus d’une expérience, à priori inoffensive pour l’internaute.\u003C/p>\n\u003Ch2 id=\"la-spécification\">La spécification\u003C/h2>\n\u003Cp>Quand je me suis intéressé à ce qu’il était possible de faire avec les liens déjà visités, j’ai découvert qu’extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu’il était possible de récupérer l’historique de navigation d’un utilisateur grâce aux styles des liens visités. Le sélecteur \u003Ccode>:visited\u003C/code> a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector\">Plus d’informations dans cet article.\u003C/a>\u003C/p>\n\u003Ch2 id=\"la-pratique\">La pratique\u003C/h2>\n\u003Cp>Que faire alors, en terme de style, quand on ne peut changer que des couleurs ?\u003C/p>\n\u003Cp>D’après MDN, les propriétés suivantes sont modifiables :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>background-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>border-color\u003C/code> (et les propriétés détaillées associées),\u003C/li>\n\u003Cli>\u003Ccode>column-rule-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>outline-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-decoration-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-emphasis-color\u003C/code>\u003C/li>\n\u003Cli>Les composantes de couleur liées aux attributs SVG \u003Ccode>fill\u003C/code> et \u003Ccode>stroke\u003C/code>.\u003C/li>\n\u003C/ul>\n\u003Cp>Changer la couleur d’un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\u003C/p>\n\u003Cp>En revanche, il est possible de ” masquer ” un élément en modifiant sa couleur pour qu’elle corresponde à la couleur du fond de la page ou de l’élément parent. On pourrait ainsi imaginer masquer une \u003Ccode>border\u003C/code> ou un \u003Ccode>outline\u003C/code>.\u003C/p>\n\u003Cp>J’ai personnellement choisi de faire différemment. J’ai décidé d’utiliser un pseudo-élément \u003Ccode>::before\u003C/code> sur l’état non visité du lien puis de le masquer quand celui-ci devient visité.\u003C/p>\n\u003Ch3 id=\"le-code\">Le code\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">style.css\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">relative\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-decoration: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line highlight mark\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#eca3a8\">a\u003C/span>\u003Cspan style=\"--0:#73c3cc\">::before\u003C/span>\u003Cspan style=\"--0:#b0b6c3\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">inline-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">block-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">4\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-6\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: grey;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line highlight mark\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#eca3a8\">a\u003C/span>\u003Cspan style=\"--0:#73c3cc\">:visited::before\u003C/span>\u003Cspan style=\"--0:#b0b6c3\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"a { position: relative; text-decoration: none;}a::before { content: ''; position: absolute; top: 50%; left: 0; inline-size: 2px; block-size: 2px; border-radius: 4px; transform: translate(-6px, 0); background-color: grey;}a:visited::before { background-color: white;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Ces règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\u003C/p>\n\u003Ch3 id=\"accessibilité\">Accessibilité\u003C/h3>\n\u003Cp>On pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété \u003Ccode>content\u003C/code> mais les lecteurs d’écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d’écrans annoncent déjà si un lien est visité avant de lire son intitulé.\u003C/p>\n\u003Ch2 id=\"aller-plus-loin\">Aller plus loin\u003C/h2>\n\u003Cp>Afin de pousser l’expérience un peu plus loin, j’ai tenté d’utiliser des éléments plus explicites pour signifier l’état visité du lien. Bien qu’encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\u003C/p>\n\u003Cp>L’idée est d’avoir un \u003Ccode>::before\u003C/code> et un \u003Ccode>::after\u003C/code>, chacun contenant une icône en base 64 blanche en tant qu’image de fond. Quand le lien est non visité, le \u003Ccode>::before\u003C/code> contient un fond coloré qui fait apparaître l’icône. Quand le lien passe en visité, le fond du \u003Ccode>::before\u003C/code> devient blanc et celui du \u003Ccode>::after\u003C/code> devient coloré, ce qui masque la première icône et affiche la deuxième.\u003C/p>\n\u003Cp>Il est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l’une sur l’autre.\u003C/p>\n\u003Cp>\u003Ca href=\"https://codepen.io/narduin/pen/VwVwmrO\">Voir la démo sur codepen.\u003C/a>\u003C/p>",{"headings":726,"imagePaths":744,"frontmatter":745},[727,730,733,736,739,741],{"depth":26,"slug":728,"text":729},"la-théorie","La théorie",{"depth":26,"slug":731,"text":732},"la-spécification","La spécification",{"depth":26,"slug":734,"text":735},"la-pratique","La pratique",{"depth":70,"slug":737,"text":738},"le-code","Le code",{"depth":70,"slug":146,"text":740},"Accessibilité",{"depth":26,"slug":742,"text":743},"aller-plus-loin","Aller plus loin",[],{"title":715,"subtitle":716,"lang":15,"draft":719,"slug":712,"excerpt":598,"tags":746,"type":560,"createdAt":600},[132],"en-array-vs-array",{"id":747,"data":749,"body":754,"filePath":755,"digest":756,"rendered":757},{"title":750,"subtitle":751,"lang":180,"tags":752,"type":560,"slug":747,"createdAt":753},"Filter an array against another array","Array vs Array.",[572],["Date","2022-06-08T14:24:06.000Z"],"## Context\n\nFor a project, I had to come up with a way to filter an array of objects based on another array of strings.\n\nIn other words, I needed to include every object which `user` property was found in the second array.\n\nHere is an example:\n\n```javascript\nconst skills = [\n\t{\n\t\tname: 'Be awesome',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Great jokes',\n\t\tuser: 'Jacques'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Beatriz'\n\t}\n]\n\nconst selectedUsers = ['Jean', 'Beatriz']\n```\n\nI thought it would be pretty easy but I guess I'm not familiar enough with javascript 😬\n\n## My solution\n\nAfter a bit of thinking, I came up with the following statement:\n\n> I need to filter the skills based on which users are selected. So I need to loop over the `selectedUsers` array and filter the skills according to their `user` value.\n\nAfter a bit more trials and errors, this is the code I ended up using in a `computed property`:\n\n```javascript\n// index.vue\nconst filteredSkills = selectedUsers.map((user) => {\n\treturn skills.filter((skill) => {\n\t\treturn skill.user === user\n\t})\n})\n```\n\nI used `map()` in order to loop on the second array and used its string value to only include the corresponding skills with `filter()`.\n\nI'm pretty sure there is a better way to do it though…","src/content/fragments/en/array-vs-array.md","c63ba57b1049cf4c",{"html":758,"metadata":759},"\u003Ch2 id=\"context\">Context\u003C/h2>\n\u003Cp>For a project, I had to come up with a way to filter an array of objects based on another array of strings.\u003C/p>\n\u003Cp>In other words, I needed to include every object which \u003Ccode>user\u003C/code> property was found in the second array.\u003C/p>\n\u003Cp>Here is an example:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Be awesome'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Great jokes'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jacques'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Beatriz'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">selectedUsers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> [\u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#98C379\">'Beatriz'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const skills = [ { name: 'Be awesome', user: 'Jean' }, { name: 'Great jokes', user: 'Jacques' }, { name: 'Heavy sleeper', user: 'Jean' }, { name: 'Heavy sleeper', user: 'Beatriz' }]const selectedUsers = ['Jean', 'Beatriz']\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>I thought it would be pretty easy but I guess I’m not familiar enough with javascript 😬\u003C/p>\n\u003Ch2 id=\"my-solution\">My solution\u003C/h2>\n\u003Cp>After a bit of thinking, I came up with the following statement:\u003C/p>\n\u003Cblockquote>\n\u003Cp>I need to filter the skills based on which users are selected. So I need to loop over the \u003Ccode>selectedUsers\u003C/code> array and filter the skills according to their \u003Ccode>user\u003C/code> value.\u003C/p>\n\u003C/blockquote>\n\u003Cp>After a bit more trials and errors, this is the code I ended up using in a \u003Ccode>computed property\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">filteredSkills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">selectedUsers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">map\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">((\u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) \u003C/span>\u003Cspan style=\"--0:#CD89E1\">=>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">filter\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">((\u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">skill\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) \u003C/span>\u003Cspan style=\"--0:#CD89E1\">=>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skill\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">===\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const filteredSkills = selectedUsers.map((user) => { return skills.filter((skill) => { return skill.user === user })})\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>I used \u003Ccode>map()\u003C/code> in order to loop on the second array and used its string value to only include the corresponding skills with \u003Ccode>filter()\u003C/code>.\u003C/p>\n\u003Cp>I’m pretty sure there is a better way to do it though…\u003C/p>",{"headings":760,"imagePaths":767,"frontmatter":768},[761,764],{"depth":26,"slug":762,"text":763},"context","Context",{"depth":26,"slug":765,"text":766},"my-solution","My solution",[],{"title":750,"subtitle":751,"lang":180,"slug":747,"createdAt":269,"excerpt":769,"tags":770,"type":560},"My peak javascript",[572],"en-nuxt-graphql-static",{"id":771,"data":773,"body":779,"filePath":780,"digest":781,"rendered":782},{"title":774,"subtitle":775,"lang":180,"tags":776,"type":560,"slug":771,"createdAt":777,"updatedAt":778},"Static website and GraphQL queries with Nuxt.js","Graphql client is king.",[572],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## The problem\n\nI encountered a nasty bug while using static generation with Nuxt and [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (new tab)') client.\nI found [the issue](https://github.com/nuxt-community/apollo-module/issues/339 'Github issue on nuxt/apollo repository (new tab)') already reported on github.\n\nIt seems the module doesn't handle static generation correctly with `nuxt generate`.\n\nI could find request to my local API url after the static generation. Moreover, it also seemed like `\u003Cnuxt-link>` navigation was broken.\n\n## The solution 🙌\n\nFortunately, there is another Nuxt module that handles GraphQL requests!\n\n[Nuxt graphql request to the rescue!](https://github.com/gomah/nuxt-graphql-request)\n\n### The conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### The request\n\nThe best approach so far is to use `asyncData` in pages and `fetch` in components. Using `fetch` in pages does not work well at all with `nuxt generate`.\n\nI also install the `graphql-tag` package (only in `devDependencies`) to be able to import directly `.gql` files.\n\nQuery example:\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Inside a page\n\n```vue\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n\tasync asyncData({ $graphql }) {\n\t\tconst data = await $graphql.default.request(homepageQuery)\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```\n\n#### Inside a component\n\nIt is safer to wait until `fetch` has received a response before displaying anything. You can use `$fetchState` to be sure ([documentation](https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation on the fetch hook (new tab)')).\n\n```vue\n// Header.vue\n\u003Ctemplate>\n\t\u003Cheader v-if=\"!$fetchState.pending\">…\u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tdata: {}\n\t\t}\n\t},\n\tasync fetch() {\n\t\ttry {\n\t\t\tconst data = await this.$graphql.default.request(headerQuery)\n\t\t\tthis.data = data\n\t\t} catch (error) {\n\t\t\tconsole.error(JSON.stringify(error, undefined, 2))\n\t\t}\n\t}\n}\n\u003C/script>\n```\n\n### Options\n\nTo pass options to the request, for example for a multilingual version with [nuxt/i18n](https://i18n.nuxtjs.org/) and/or a url parameter in a dynamic page:\n\n```vue\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n\tasync asyncData({ $graphql, app, params }) {\n\t\tconst locale = app.i18n.localeProperties.iso\n\t\tconst data = await $graphql.default.request(articleQuery, {\n\t\t\tcode: locale,\n\t\t\tslug: params.slug\n\t\t})\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```","src/content/fragments/en/nuxt-graphql-static.md","c5d4f0dd6ca0e1c2",{"html":783,"metadata":784},"\u003Ch2 id=\"the-problem\">The problem\u003C/h2>\n\u003Cp>I encountered a nasty bug while using static generation with Nuxt and \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (new tab)\">nuxt apollo\u003C/a> client.\nI found \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Github issue on nuxt/apollo repository (new tab)\">the issue\u003C/a> already reported on github.\u003C/p>\n\u003Cp>It seems the module doesn’t handle static generation correctly with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I could find request to my local API url after the static generation. Moreover, it also seemed like \u003Ccode><nuxt-link>\u003C/code> navigation was broken.\u003C/p>\n\u003Ch2 id=\"the-solution\">The solution 🙌\u003C/h2>\n\u003Cp>Fortunately, there is another Nuxt module that handles GraphQL requests!\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\">Nuxt graphql request to the rescue!\u003C/a>\u003C/p>\n\u003Ch3 id=\"the-conf\">The conf\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">nuxt.config.js\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">buildModules\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">clients\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">endpoint\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">options\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">authorization\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"buildModules: [ 'nuxt-graphql-request',],graphql: { clients: { default: { endpoint: 'http://API_URL/graphql', options: { headers: { authorization: 'Bearer API_TOKEN', }, }, }, },},\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"the-request\">The request\u003C/h3>\n\u003Cp>The best approach so far is to use \u003Ccode>asyncData\u003C/code> in pages and \u003Ccode>fetch\u003C/code> in components. Using \u003Ccode>fetch\u003C/code> in pages does not work well at all with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I also install the \u003Ccode>graphql-tag\u003C/code> package (only in \u003Ccode>devDependencies\u003C/code>) to be able to import directly \u003Ccode>.gql\u003C/code> files.\u003C/p>\n\u003Cp>Query example:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">homepage.gql\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"graphql\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">query\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepage\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">subtitle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">hero\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">id\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">alt\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"query { homepage { title subtitle hero { id alt } }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"inside-a-page\">Inside a page\u003C/h4>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/homepage'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import homepageQuery from '~/graphql/queries/singles/homepage'export default { async asyncData({ $graphql }) { const data = await $graphql.default.request(homepageQuery) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"inside-a-component\">Inside a component\u003C/h4>\n\u003Cp>It is safer to wait until \u003Ccode>fetch\u003C/code> has received a response before displaying anything. You can use \u003Ccode>$fetchState\u003C/code> to be sure (\u003Ca href=\"https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation on the fetch hook (new tab)\">documentation\u003C/a>).\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">Header.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">v-if\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#56B6C2\">!\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$fetchState\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">pending\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>…</\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/header'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">fetch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">try\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">} \u003C/span>\u003Cspan style=\"--0:#CD89E1\">catch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> (\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">console\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E5C07B\">JSON\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">stringify\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">undefined\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">))\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ctemplate> \u003Cheader v-if="!$fetchState.pending">…\u003C/header>\u003C/template>\u003Cscript>import headerQuery from '~/graphql/queries/singles/header'export default { data() { return { data: {} } }, async fetch() { try { const data = await this.$graphql.default.request(headerQuery) this.data = data } catch (error) { console.error(JSON.stringify(error, undefined, 2)) } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"options\">Options\u003C/h3>\n\u003Cp>To pass options to the request, for example for a multilingual version with \u003Ca href=\"https://i18n.nuxtjs.org/\">nuxt/i18n\u003C/a> and/or a url parameter in a dynamic page:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">_slug.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/articles'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">i18n\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">localeProperties\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">iso\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">code\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E6888F\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E5C07B\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import articleQuery from '~/graphql/queries/articles'export default { async asyncData({ $graphql, app, params }) { const locale = app.i18n.localeProperties.iso const data = await $graphql.default.request(articleQuery, { code: locale, slug: params.slug }) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":785,"imagePaths":808,"frontmatter":809},[786,789,792,795,798,802,805],{"depth":26,"slug":787,"text":788},"the-problem","The problem",{"depth":26,"slug":790,"text":791},"the-solution","The solution 🙌",{"depth":70,"slug":793,"text":794},"the-conf","The conf",{"depth":70,"slug":796,"text":797},"the-request","The request",{"depth":799,"slug":800,"text":801},4,"inside-a-page","Inside a page",{"depth":799,"slug":803,"text":804},"inside-a-component","Inside a component",{"depth":70,"slug":806,"text":807},"options","Options",[],{"title":774,"subtitle":775,"lang":180,"slug":771,"createdAt":269,"updatedAt":810,"excerpt":811,"tags":812,"type":560},"2022-09-08T13:43:33.000Z","When the most used gql module doesn't work…",[572],"nuxt-graphql-static",{"id":813,"data":815,"body":821,"filePath":822,"digest":823,"rendered":824},{"title":816,"subtitle":817,"lang":15,"tags":818,"type":552,"slug":813,"createdAt":819,"updatedAt":820},"Site statique et requêtes GraphQL avec Nuxt.js","Le client graphql est roi.",[572],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## Le problème\n\nJe me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (nouvel onglet)').\nAprès quelques recherches, voici [le bug constaté par quelqu'un d'autre](https://github.com/nuxt-community/apollo-module/issues/339 'Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)') sur github.\n\nIl semblerait que le module en l'état ne gère pas correctement la génération statique avec `nuxt generate`.\n\nJe trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les `\u003Cnuxt-link>` ne fonctionnait pas.\n\n## La solution 🙌\n\nHeureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\n\n[Nuxt graphql request à la rescousse !](https://github.com/gomah/nuxt-graphql-request 'Dépôt github du module (nouvel onglet)')\n\n### La conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### La requête\n\nLa meilleure méthode à ce jour est d'utiliser `asyncData` dans les pages et `fetch` dans les composants. Utiliser `fetch` dans les pages ne fonctionne pas bien du tout avec `nuxt generate`.\n\nJ'installe également le paquet `graphql-tag` (uniquement en `devDependencies`) afin de pouvoir importer directement des fichiers `.gql`\n\nExemple de fichier :\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Dans une page\n\n```vue\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n\tasync asyncData({ $graphql }) {\n\t\tconst data = await $graphql.default.request(homepageQuery)\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```\n\n#### Dans un composant\n\nIl est plus prudent d'attendre que `fetch` ait reçu une réponse avant d'afficher quoi que ce soit. On peut utiliser `$fetchState` afin d'être tranquille ([documentation](https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation sur la méthode fetch (nouvel onglet)')).\n\n```vue\n// Header.vue\n\u003Ctemplate>\n\t\u003Cheader v-if=\"!$fetchState.pending\">…\u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tdata: {}\n\t\t}\n\t},\n\tasync fetch() {\n\t\ttry {\n\t\t\tconst data = await this.$graphql.default.request(headerQuery)\n\t\t\tthis.data = data\n\t\t} catch (error) {\n\t\t\tconsole.error(JSON.stringify(error, undefined, 2))\n\t\t}\n\t}\n}\n\u003C/script>\n```\n\n### Les options\n\nPour passer des options à la requête, par exemple pour une version multilingue avec [nuxt/i18n](https://i18n.nuxtjs.org/ 'Documentation de nuxt i18n (nouvel onglet)') et/ou un paramètre d'url dans le cadre d'une page dynamique :\n\n```vue\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n\tasync asyncData({ $graphql, app, params }) {\n\t\tconst locale = app.i18n.localeProperties.iso\n\t\tconst data = await $graphql.default.request(articleQuery, {\n\t\t\tcode: locale,\n\t\t\tslug: params.slug\n\t\t})\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```","src/content/fragments/fr/nuxt-graphql-static.md","6304f174b83f0078",{"html":825,"metadata":826},"\u003Ch2 id=\"le-problème\">Le problème\u003C/h2>\n\u003Cp>Je me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (nouvel onglet)\">nuxt apollo\u003C/a>.\nAprès quelques recherches, voici \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)\">le bug constaté par quelqu’un d’autre\u003C/a> sur github.\u003C/p>\n\u003Cp>Il semblerait que le module en l’état ne gère pas correctement la génération statique avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>Je trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les \u003Ccode><nuxt-link>\u003C/code> ne fonctionnait pas.\u003C/p>\n\u003Ch2 id=\"la-solution\">La solution 🙌\u003C/h2>\n\u003Cp>Heureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\" title=\"Dépôt github du module (nouvel onglet)\">Nuxt graphql request à la rescousse !\u003C/a>\u003C/p>\n\u003Ch3 id=\"la-conf\">La conf\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">nuxt.config.js\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">buildModules\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">clients\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">endpoint\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">options\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">authorization\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"buildModules: [ 'nuxt-graphql-request',],graphql: { clients: { default: { endpoint: 'http://API_URL/graphql', options: { headers: { authorization: 'Bearer API_TOKEN', }, }, }, },},\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"la-requête\">La requête\u003C/h3>\n\u003Cp>La meilleure méthode à ce jour est d’utiliser \u003Ccode>asyncData\u003C/code> dans les pages et \u003Ccode>fetch\u003C/code> dans les composants. Utiliser \u003Ccode>fetch\u003C/code> dans les pages ne fonctionne pas bien du tout avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>J’installe également le paquet \u003Ccode>graphql-tag\u003C/code> (uniquement en \u003Ccode>devDependencies\u003C/code>) afin de pouvoir importer directement des fichiers \u003Ccode>.gql\u003C/code>\u003C/p>\n\u003Cp>Exemple de fichier :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">homepage.gql\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"graphql\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">query\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepage\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">subtitle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">hero\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">id\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">alt\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"query { homepage { title subtitle hero { id alt } }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"dans-une-page\">Dans une page\u003C/h4>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/homepage'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import homepageQuery from '~/graphql/queries/singles/homepage'export default { async asyncData({ $graphql }) { const data = await $graphql.default.request(homepageQuery) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"dans-un-composant\">Dans un composant\u003C/h4>\n\u003Cp>Il est plus prudent d’attendre que \u003Ccode>fetch\u003C/code> ait reçu une réponse avant d’afficher quoi que ce soit. On peut utiliser \u003Ccode>$fetchState\u003C/code> afin d’être tranquille (\u003Ca href=\"https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation sur la méthode fetch (nouvel onglet)\">documentation\u003C/a>).\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">Header.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">v-if\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#56B6C2\">!\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$fetchState\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">pending\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>…</\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/header'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">fetch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">try\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">} \u003C/span>\u003Cspan style=\"--0:#CD89E1\">catch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> (\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">console\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E5C07B\">JSON\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">stringify\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">undefined\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">))\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ctemplate> \u003Cheader v-if="!$fetchState.pending">…\u003C/header>\u003C/template>\u003Cscript>import headerQuery from '~/graphql/queries/singles/header'export default { data() { return { data: {} } }, async fetch() { try { const data = await this.$graphql.default.request(headerQuery) this.data = data } catch (error) { console.error(JSON.stringify(error, undefined, 2)) } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"les-options\">Les options\u003C/h3>\n\u003Cp>Pour passer des options à la requête, par exemple pour une version multilingue avec \u003Ca href=\"https://i18n.nuxtjs.org/\" title=\"Documentation de nuxt i18n (nouvel onglet)\">nuxt/i18n\u003C/a> et/ou un paramètre d’url dans le cadre d’une page dynamique :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">_slug.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/articles'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">i18n\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">localeProperties\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">iso\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">code\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E6888F\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E5C07B\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import articleQuery from '~/graphql/queries/articles'export default { async asyncData({ $graphql, app, params }) { const locale = app.i18n.localeProperties.iso const data = await $graphql.default.request(articleQuery, { code: locale, slug: params.slug }) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":827,"imagePaths":849,"frontmatter":850},[828,831,834,837,840,843,846],{"depth":26,"slug":829,"text":830},"le-problème","Le problème",{"depth":26,"slug":832,"text":833},"la-solution","La solution 🙌",{"depth":70,"slug":835,"text":836},"la-conf","La conf",{"depth":70,"slug":838,"text":839},"la-requête","La requête",{"depth":799,"slug":841,"text":842},"dans-une-page","Dans une page",{"depth":799,"slug":844,"text":845},"dans-un-composant","Dans un composant",{"depth":70,"slug":847,"text":848},"les-options","Les options",[],{"title":816,"subtitle":817,"lang":15,"slug":813,"createdAt":269,"updatedAt":810,"excerpt":851,"tags":852,"type":552},"Quand le module gql le plus utilisé ne fonctionne pas…",[572],"en-buttons",{"id":853,"data":855,"body":860,"filePath":861,"digest":862,"rendered":863},{"title":856,"subtitle":857,"lang":180,"tags":858,"type":560,"slug":853,"createdAt":859,"code":184,"draft":184},"Buttons hover","Simple, but nice.",[559],["Date","2020-10-08T09:00:00.000Z"],"## General rules\n\nAll the buttons use these styles as a “reset”:\n\n> Don't forget to prefix if necessary!\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Add an icon\n\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('~assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double shutter down\n\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Animated gradient\n\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Non destructive scale\n\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/en/buttons.md","ea9a5513a5a4cef4",{"html":864,"metadata":865},"\u003Ch2 id=\"general-rules\">General rules\u003C/h2>\n\u003Cp>All the buttons use these styles as a “reset”:\u003C/p>\n\u003Cblockquote>\n\u003Cp>Don’t forget to prefix if necessary!\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">margin: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">padding: \u003C/span>\u003Cspan style=\"--0:#D19A66\">12\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">26\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">relative\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">display: \u003C/span>\u003Cspan style=\"--0:#D19A66\">inline-block\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">overflow: \u003C/span>\u003Cspan style=\"--0:#D19A66\">hidden\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">font-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">rem\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">; \u003C/span>\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\">/* 20px */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">line-height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">1.6\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-align: \u003C/span>\u003Cspan style=\"--0:#D19A66\">center\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-decoration: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">font-weight: \u003C/span>\u003Cspan style=\"--0:#D19A66\">bold\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">cursor: \u003C/span>\u003Cspan style=\"--0:#D19A66\">pointer\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">-moz-appearance\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">-webkit-appearance\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: background-color \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn { margin: 20px 0; padding: 12px 26px; position: relative; display: inline-block; overflow: hidden; font-size: 20rem; /* 20px */ line-height: 1.6; text-align: center; text-decoration: none; font-weight: bold; cursor: pointer; border: none; border-radius: 2px; -moz-appearance: none; -webkit-appearance: none; color: white; background-color: hotpink; transition: background-color 0.3s ease;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"add-an-icon\">Add an icon\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">url\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#98C379\">'~assets/svg/arrow-right-white.svg'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">right: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">40\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">-50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: darkorchid;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-10\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">-50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">display: \u003C/span>\u003Cspan style=\"--0:#D19A66\">inline-block\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">27\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">28\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">29\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translateX\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-10\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">30\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-icon { background-color: hotpink;}.btn-icon::before { content: url('~assets/svg/arrow-right-white.svg'); position: absolute; width: 20px; top: 50%; right: 0; transform: translate(40px, -50%); transition: transform ease 0.3s;}.btn-icon:hover,.btn-icon:focus { background-color: darkorchid;}.btn-icon:hover::before,.btn-icon:focus::before { transform: translate(-10px, -50%);}.btn-icon > span { display: inline-block; width: 100%; height: 100%; transition: transform 0.3s ease;}.btn-icon:hover > span,.btn-icon:focus > span { transform: translateX(-10px);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"double-shutter-down\">Double shutter down\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">solid\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">transparent\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: \u003C/span>\u003Cspan style=\"--0:#D19A66\">color\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: darkorchid;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">bottom: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">z-index: \u003C/span>\u003Cspan style=\"--0:#D19A66\">-1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-timing-function: \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">27\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-timing-function: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">cubic-bezier\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">0.75\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.125\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">28\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">29\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">30\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">31\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">32\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">33\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translateY\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">34\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">35\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">36\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">37\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-delay: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.175\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">38\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-rideau { border: 2px solid #10113a; color: #10113a; background-color: transparent; transition: color 0.3s ease;}.btn-rideau:hover { color: white;}.btn-rideau::before { background: hotpink;}.btn-rideau::after { background: darkorchid;}.btn-rideau::before,.btn-rideau::after { content: ''; position: absolute; height: 100%; width: 100%; bottom: 100%; left: 0; z-index: -1; transition: transform 0.3s; transition-timing-function: ease; transition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);}.btn-rideau:hover::before,.btn-rideau:hover::after,.btn-rideau:focus::before,.btn-rideau:focus::after { transform: translateY(100%);}.btn-rideau:hover::after,.btn-rideau:focus::after { transition-delay: 0.175s;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"animated-gradient\">Animated gradient\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">linear-gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-45\u003C/span>\u003Cspan style=\"--0:#E6888F\">deg\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#ee7752\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#e73c7e\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#23a6d5\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#23d5ab\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">400\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">400\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">animation: GradientReverse \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.5\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">normal\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">forwards\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">animation: Gradient \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.5\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">normal\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">forwards\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">@keyframes\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">Gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">0% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">100% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">@keyframes\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">GradientReverse\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">0% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">100% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-gradient { background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); background-size: 400% 400%; background-position: 0% 50%; animation: GradientReverse 0.5s ease 1 normal forwards;}.btn-gradient:hover,.btn-gradient:focus { animation: Gradient 0.5s ease 1 normal forwards;}@keyframes Gradient { 0% { background-position: 0% 50%; } 100% { background-position: 100% 100%; }}@keyframes GradientReverse { 0% { background-position: 100% 100%; } 100% { background-position: 0% 50%; }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"non-destructive-scale\">Non destructive scale\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">overflow: \u003C/span>\u003Cspan style=\"--0:#D19A66\">visible\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">transparent\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">bottom: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">solid\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">scale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">1.1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-scale { overflow: visible; color: #10113a; background-color: transparent;}.btn-scale::after { content: ''; position: absolute; top: 0; left: 0; bottom: 0; width: 100%; border: 2px solid #10113a; border-radius: 2px; transition: transform 0.3s ease;}.btn-scale:hover::after,.btn-scale:focus::after { transform: scale(1.1);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":866,"imagePaths":882,"frontmatter":883},[867,870,873,876,879],{"depth":26,"slug":868,"text":869},"general-rules","General rules",{"depth":26,"slug":871,"text":872},"add-an-icon","Add an icon",{"depth":26,"slug":874,"text":875},"double-shutter-down","Double shutter down",{"depth":26,"slug":877,"text":878},"animated-gradient","Animated gradient",{"depth":26,"slug":880,"text":881},"non-destructive-scale","Non destructive scale",[],{"title":856,"subtitle":857,"lang":180,"slug":853,"draft":184,"excerpt":884,"tags":885,"code":184,"type":560,"createdAt":886},"Easy to grab and use hover effects.",[559],"2020-10-08T09:00:00.000Z","en-acme-sh-tls-cert",{"id":887,"data":889,"body":895,"filePath":896,"digest":897,"rendered":898},{"title":890,"subtitle":891,"lang":180,"tags":892,"type":560,"slug":887,"createdAt":894},"Strong TLS certificates with acme.sh","384-bit of https",[893],"security",["Date","2022-06-08T14:24:06.000Z"],"## Disclaimer\n\nI'm, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs. \nThis is why I've switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nYou can learn (far) more by reading [this topic](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) and its linked resources.\n\n## Requirements\n\n### Installing acme.sh\n\nFor automation and ease of use purposes, I'm using [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# for using standalone mode, you might have to install as sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changing default authority\n\nBy default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let's Encrypt because according to acme.sh, they're the only ones offering ECC capabilities.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Using your DNS api\n\nIf available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports [a lot](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) of DNS providers.\n\n### Define an api key\n\nFollow the [docs](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) for your DNS provider, usually:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Issue the cert\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Using standalone mode\n\nIf you don't have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\n\nPort `80` must be free.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Examples\n\n### Multi domains standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domain DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Next steps\n\nThe ECC certificate alone will not grant you a high/perfect score.\n\n### TLS version\n\nLimit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a [5% compatibility gap](https://caniuse.com/?search=tls%201.) with 1.2).\n\n### HSTS\n\nUse the [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/) header.\n\n```http\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Cipher suite\n\nUse recent and strong ciphers. This is where my knowledge hits its limit… I'm having a really hard time understanding what to use and why.\n\nI've based my initial choices of ciphers on [this list](https://tls.imirhil.fr/ciphers), cross referencing it with (older?) [browser compatibility](https://tls.imirhil.fr/suite).\n\nI then asked [Aeris](https://twitter.com/aeris22), the creator of [tls.imirhil.fr](https://tls.imirhil.fr), about it and he advised me to use the following:\n\n```cypher\nECDHE+AES:ECDHE+CHACHA20\n```\n\nIn order to achieve a perfect score, we can be a little more restrictive with:\n\n```cypher\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/en/acme-sh-tls-cert.md","4dc80f1d0e800d6f",{"html":899,"metadata":900},"\u003Ch2 id=\"disclaimer\">Disclaimer\u003C/h2>\n\u003Cp>I’m, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs.\u003Cbr>\nThis is why I’ve switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>You can learn (far) more by reading \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">this topic\u003C/a> and its linked resources.\u003C/p>\n\u003Ch2 id=\"requirements\">Requirements\u003C/h2>\n\u003Ch3 id=\"installing-acmesh\">Installing acme.sh\u003C/h3>\n\u003Cp>For automation and ease of use purposes, I’m using \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\"># for using standalone mode, you might have to install as sudo\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">curl\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">https://get.acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> | \u003C/span>\u003Cspan style=\"--0:#61AFEF\">sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">email=mail@domain.tld\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl https://get.acme.sh | sh -s email=mail@domain.tld\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"changing-default-authority\">Changing default authority\u003C/h3>\n\u003Cp>By default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let’s Encrypt because according to acme.sh, they’re the only ones offering ECC capabilities.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--set-default-ca\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--server\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">letsencrypt\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --set-default-ca --server letsencrypt\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"using-your-dns-api\">Using your DNS api\u003C/h2>\n\u003Cp>If available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">a lot\u003C/a> of DNS providers.\u003C/p>\n\u003Ch3 id=\"define-an-api-key\">Define an api key\u003C/h3>\n\u003Cp>Follow the \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">docs\u003C/a> for your DNS provider, usually:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">PROVIDER_Key\u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#98C379\">\"YOUR_API_KEY\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export PROVIDER_Key="YOUR_API_KEY"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"issue-the-cert\">Issue the cert\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"using-standalone-mode\">Using standalone mode\u003C/h2>\n\u003Cp>If you don’t have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\u003C/p>\n\u003Cp>Port \u003Ccode>80\u003C/code> must be free.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"examples\">Examples\u003C/h2>\n\u003Ch3 id=\"multi-domains-standalone\">Multi domains standalone\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">www.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">subdomain.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"wildcard-domain-dns\">Wildcard domain DNS\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'*.domain.tld'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"next-steps\">Next steps\u003C/h2>\n\u003Cp>The ECC certificate alone will not grant you a high/perfect score.\u003C/p>\n\u003Ch3 id=\"tls-version\">TLS version\u003C/h3>\n\u003Cp>Limit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a \u003Ca href=\"https://caniuse.com/?search=tls%201.\">5% compatibility gap\u003C/a> with 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Use the \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a> header.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">Strict-Transport-Security\u003C/span>\u003Cspan style=\"--0:#CD89E1\">:\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">max-age=31536000; includeSubDomains\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Strict-Transport-Security: max-age=31536000; includeSubDomains\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"cipher-suite\">Cipher suite\u003C/h3>\n\u003Cp>Use recent and strong ciphers. This is where my knowledge hits its limit… I’m having a really hard time understanding what to use and why.\u003C/p>\n\u003Cp>I’ve based my initial choices of ciphers on \u003Ca href=\"https://tls.imirhil.fr/ciphers\">this list\u003C/a>, cross referencing it with (older?) \u003Ca href=\"https://tls.imirhil.fr/suite\">browser compatibility\u003C/a>.\u003C/p>\n\u003Cp>I then asked \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, the creator of \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, about it and he advised me to use the following:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>In order to achieve a perfect score, we can be a little more restrictive with:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES256\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES256:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":901,"imagePaths":947,"frontmatter":948},[902,905,908,911,914,917,920,923,926,929,932,935,938,941,944],{"depth":26,"slug":903,"text":904},"disclaimer","Disclaimer",{"depth":26,"slug":906,"text":907},"requirements","Requirements",{"depth":70,"slug":909,"text":910},"installing-acmesh","Installing acme.sh",{"depth":70,"slug":912,"text":913},"changing-default-authority","Changing default authority",{"depth":26,"slug":915,"text":916},"using-your-dns-api","Using your DNS api",{"depth":70,"slug":918,"text":919},"define-an-api-key","Define an api key",{"depth":70,"slug":921,"text":922},"issue-the-cert","Issue the cert",{"depth":26,"slug":924,"text":925},"using-standalone-mode","Using standalone mode",{"depth":26,"slug":927,"text":928},"examples","Examples",{"depth":70,"slug":930,"text":931},"multi-domains-standalone","Multi domains standalone",{"depth":70,"slug":933,"text":934},"wildcard-domain-dns","Wildcard domain DNS",{"depth":26,"slug":936,"text":937},"next-steps","Next steps",{"depth":70,"slug":939,"text":940},"tls-version","TLS version",{"depth":70,"slug":942,"text":943},"hsts","HSTS",{"depth":70,"slug":945,"text":946},"cipher-suite","Cipher suite",[],{"title":890,"subtitle":891,"lang":180,"slug":887,"createdAt":269,"excerpt":949,"tags":950,"type":560},"Real cert have curves.",[893],"acme-sh-tls-cert",{"id":951,"data":953,"body":959,"filePath":960,"digest":961,"rendered":962},{"title":954,"subtitle":955,"lang":15,"tags":956,"type":552,"slug":951,"createdAt":958},"Certificates TLS robustes avec acme.sh","384-bit de https",[957],"sécurité",["Date","2022-06-08T14:24:06.000Z"],"## Attention\n\nJe ne suis pas du tout un expert en sécurité. J'aime juste les trucs nouveaux et stylés des internets. \nC'est pourquoi j'ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J'ai maintenant un joli 100/100 sur [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nVous pouvez en apprendre (beaucoup) plus [ici](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) et sur les liens cités (en anglais).\n\n## Prérequis\n\n### Installer acme.sh\n\nPour des raisons de simplicité et d'automatisation, j'utilise [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changer l'authorité par défaut\n\nPar défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let's Encrypt car, d'après acme.sh, ils sont les seuls à proposer des certificats ECC.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Utiliser l'api DNS\n\nSi vous en avez la possibilité, la façon la plus simple de générer un certificat est via l'api de votre fournisseur DNS. acme.sh supporte [énormément](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) de fournisseurs DNS.\n\n### Definir la clé api\n\nSuivez la [documentation](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) pour votre fournisseur DNS, généralement:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Émettre le certificat\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Utiliser le mode standalone\n\nSi vous n'avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s'occupe de toutes les vérifications.\n\nLe port `80` doit être disponible.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Exemples\n\n### Multi domaines standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domaine DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Étapes supplémentaires\n\nLe certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\n\n### Version TLS\n\nLimiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu [la différence de compatibilité de 5%](https://caniuse.com/?search=tls%201.) avec 1.2).\n\n### HSTS\n\nUtiliser le header [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/).\n\n```http\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Suite cryptographique\n\nUtiliser une suite cryptographique récente et robuste. C'est ici que mes connaissances deviennent limitées… J'ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\n\nJ'avais basé ma première suite sur [cette liste](https://tls.imirhil.fr/ciphers), en la comparant avec celle de la compatibilité (d'anciens ?) [navigateurs](https://tls.imirhil.fr/suite).\n\nJ'ai ensuite demandé à [Aeris](https://twitter.com/aeris22), le créateur de [tls.imirhil.fr](https://tls.imirhil.fr), ses conseils sur cette suite. Il m'a recommandé d'utiliser :\n\n```cypher\nECDHE+AES:ECDHE+CHACHA20\n```\n\nAfin d'atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\n\n```cypher\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/fr/acme-sh-tls-cert.md","018b0c09d1fdd6cc",{"html":963,"metadata":964},"\u003Ch2 id=\"attention\">Attention\u003C/h2>\n\u003Cp>Je ne suis pas du tout un expert en sécurité. J’aime juste les trucs nouveaux et stylés des internets.\u003Cbr>\nC’est pourquoi j’ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J’ai maintenant un joli 100/100 sur \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>Vous pouvez en apprendre (beaucoup) plus \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">ici\u003C/a> et sur les liens cités (en anglais).\u003C/p>\n\u003Ch2 id=\"prérequis\">Prérequis\u003C/h2>\n\u003Ch3 id=\"installer-acmesh\">Installer acme.sh\u003C/h3>\n\u003Cp>Pour des raisons de simplicité et d’automatisation, j’utilise \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\"># pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">curl\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">https://get.acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> | \u003C/span>\u003Cspan style=\"--0:#61AFEF\">sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">email=mail@domain.tld\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl https://get.acme.sh | sh -s email=mail@domain.tld\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"changer-lauthorité-par-défaut\">Changer l’authorité par défaut\u003C/h3>\n\u003Cp>Par défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let’s Encrypt car, d’après acme.sh, ils sont les seuls à proposer des certificats ECC.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--set-default-ca\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--server\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">letsencrypt\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --set-default-ca --server letsencrypt\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"utiliser-lapi-dns\">Utiliser l’api DNS\u003C/h2>\n\u003Cp>Si vous en avez la possibilité, la façon la plus simple de générer un certificat est via l’api de votre fournisseur DNS. acme.sh supporte \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">énormément\u003C/a> de fournisseurs DNS.\u003C/p>\n\u003Ch3 id=\"definir-la-clé-api\">Definir la clé api\u003C/h3>\n\u003Cp>Suivez la \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">documentation\u003C/a> pour votre fournisseur DNS, généralement:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">PROVIDER_Key\u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#98C379\">\"YOUR_API_KEY\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export PROVIDER_Key="YOUR_API_KEY"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"émettre-le-certificat\">Émettre le certificat\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"utiliser-le-mode-standalone\">Utiliser le mode standalone\u003C/h2>\n\u003Cp>Si vous n’avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s’occupe de toutes les vérifications.\u003C/p>\n\u003Cp>Le port \u003Ccode>80\u003C/code> doit être disponible.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"exemples\">Exemples\u003C/h2>\n\u003Ch3 id=\"multi-domaines-standalone\">Multi domaines standalone\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">www.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">subdomain.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"wildcard-domaine-dns\">Wildcard domaine DNS\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'*.domain.tld'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"étapes-supplémentaires\">Étapes supplémentaires\u003C/h2>\n\u003Cp>Le certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\u003C/p>\n\u003Ch3 id=\"version-tls\">Version TLS\u003C/h3>\n\u003Cp>Limiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu \u003Ca href=\"https://caniuse.com/?search=tls%201.\">la différence de compatibilité de 5%\u003C/a> avec 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Utiliser le header \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a>.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">Strict-Transport-Security\u003C/span>\u003Cspan style=\"--0:#CD89E1\">:\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">max-age=31536000; includeSubDomains\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Strict-Transport-Security: max-age=31536000; includeSubDomains\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"suite-cryptographique\">Suite cryptographique\u003C/h3>\n\u003Cp>Utiliser une suite cryptographique récente et robuste. C’est ici que mes connaissances deviennent limitées… J’ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\u003C/p>\n\u003Cp>J’avais basé ma première suite sur \u003Ca href=\"https://tls.imirhil.fr/ciphers\">cette liste\u003C/a>, en la comparant avec celle de la compatibilité (d’anciens ?) \u003Ca href=\"https://tls.imirhil.fr/suite\">navigateurs\u003C/a>.\u003C/p>\n\u003Cp>J’ai ensuite demandé à \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, le créateur de \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, ses conseils sur cette suite. Il m’a recommandé d’utiliser :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Afin d’atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES256\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES256:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":965,"imagePaths":1009,"frontmatter":1010},[966,969,972,975,978,981,984,987,990,993,996,999,1002,1005,1006],{"depth":26,"slug":967,"text":968},"attention","Attention",{"depth":26,"slug":970,"text":971},"prérequis","Prérequis",{"depth":70,"slug":973,"text":974},"installer-acmesh","Installer acme.sh",{"depth":70,"slug":976,"text":977},"changer-lauthorité-par-défaut","Changer l’authorité par défaut",{"depth":26,"slug":979,"text":980},"utiliser-lapi-dns","Utiliser l’api DNS",{"depth":70,"slug":982,"text":983},"definir-la-clé-api","Definir la clé api",{"depth":70,"slug":985,"text":986},"émettre-le-certificat","Émettre le certificat",{"depth":26,"slug":988,"text":989},"utiliser-le-mode-standalone","Utiliser le mode standalone",{"depth":26,"slug":991,"text":992},"exemples","Exemples",{"depth":70,"slug":994,"text":995},"multi-domaines-standalone","Multi domaines standalone",{"depth":70,"slug":997,"text":998},"wildcard-domaine-dns","Wildcard domaine DNS",{"depth":26,"slug":1000,"text":1001},"étapes-supplémentaires","Étapes supplémentaires",{"depth":70,"slug":1003,"text":1004},"version-tls","Version TLS",{"depth":70,"slug":942,"text":943},{"depth":70,"slug":1007,"text":1008},"suite-cryptographique","Suite cryptographique",[],{"title":954,"subtitle":955,"lang":15,"slug":951,"createdAt":269,"excerpt":1011,"tags":1012,"type":552},"La sécurité avec des courbes.",[957]] \ No newline at end of file diff --git a/astro.config.mjs b/astro.config.mjs index d6cd124..c7cb327 100755 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,30 +1,58 @@ import { defineConfig } from 'astro/config' -import { transformerMetaHighlight } from '@shikijs/transformers' - -// https://astro.build/config import mdx from '@astrojs/mdx' import sitemap from '@astrojs/sitemap' -// https://astro.build/config +import { pluginLineNumbers } from '@expressive-code/plugin-line-numbers' +import expressiveCode from 'astro-expressive-code' + export default defineConfig({ site: 'https://www.nardu.in', build: { format: 'directory' }, - i18n: { - locales: ['fr', 'en'], - defaultLocale: 'fr' + redirects: { + '/en/': { + status: 308, + destination: '/articles/en-2025' + }, + '/articles/en/': { + status: 308, + destination: '/articles/#en-articles' + }, + '/articles/en/[...id]': { + status: 308, + destination: '/articles/en-[...id]' + }, + '/snippets/en/': { + status: 308, + destination: '/fragments/#en-fragments' + }, + '/snippets/en/[...id]': { + status: 308, + destination: '/fragments/en-[...id]' + } }, image: { domains: ['assets.nardu.in'], remotePatterns: [{ protocol: 'https' }] }, - integrations: [mdx(), sitemap()], - markdown: { - shikiConfig: { + integrations: [ + expressiveCode({ theme: 'one-dark-pro', - transformers: [transformerMetaHighlight()] - } - } + plugins: [pluginLineNumbers()], + defaultProps: { + // Disable line numbers by default + showLineNumbers: false, + // But enable line numbers for certain languages + overridesByLang: { + 'css,html,js,ts,vue': { + showLineNumbers: true + } + } + } + }), + mdx(), + sitemap() + ] }) diff --git a/bun.lockb b/bun.lockb index 3ac73a9d088bfa1618cdc76c421d7e996ed12f2b..7240b4a97d57c5db936200212f10130e56c900cd 100755 GIT binary patch delta 46117 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 T)x8Q6XuBu))Ju~zPlEpq9hqM< delta 41123 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 diff --git a/package.json b/package.json index 7293ee8..9d00e78 100755 --- a/package.json +++ b/package.json @@ -14,7 +14,9 @@ "@astrojs/rss": "4.0.10", "@astrojs/sitemap": "3.2.1", "@astrojs/ts-plugin": "^1.10.4", + "@expressive-code/plugin-line-numbers": "^0.38.3", "astro": "5.1.1", + "astro-expressive-code": "^0.38.3", "sharp": "^0.33.5" }, "devDependencies": { diff --git a/src/content/articles/en/2025.md b/src/content/articles/en/2025.md new file mode 100644 index 0000000..fd350bf --- /dev/null +++ b/src/content/articles/en/2025.md @@ -0,0 +1,13 @@ +--- +title: Nico v3.0 +subtitle: Update 2025. +lang: en +slug: en-2023 +excerpt: So long i18n +tags: ['Freelance'] +type: articles +--- + +## This website no longer has an english version. + +I have maintained an english version of my website for some years. But the diff --git a/src/content/articles/en/sci-hub-blocage.mdx b/src/content/articles/en/sci-hub-blocage.mdx index c08ac9d..16b9d8f 100755 --- a/src/content/articles/en/sci-hub-blocage.mdx +++ b/src/content/articles/en/sci-hub-blocage.mdx @@ -13,7 +13,7 @@ updatedAt: '2022-12-27T12:08:00.000Z' import AstroImage from '../../../components/AstroImage.astro' -The current sci-hub address is: <a href="https://sci-hub.se" rel="noreferer noopener">sci-hub.se</a> +The current sci-hub address is: <a href="https://www.sci-hub.st/" rel="noreferer noopener">sci-hub.st</a> ## What is this about? diff --git a/src/content/articles/fr/sci-hub-blocage.mdx b/src/content/articles/fr/sci-hub-blocage.mdx index 1aada43..72d3715 100755 --- a/src/content/articles/fr/sci-hub-blocage.mdx +++ b/src/content/articles/fr/sci-hub-blocage.mdx @@ -12,7 +12,7 @@ updatedAt: '2022-12-27T12:08:00.000Z' import AstroImage from '../../../components/AstroImage.astro' -L'adresse actuelle de sci-hub est : [sci-hub.se](https://sci-hub.se) +L'adresse actuelle de sci-hub est : <a href="https://www.sci-hub.st/" rel="noreferer noopener">sci-hub.st</a> ## Résumé de la situation diff --git a/src/content/fragments/en/acme-sh-tls-cert.md b/src/content/fragments/en/acme-sh-tls-cert.md index b56db8a..d173ce4 100755 --- a/src/content/fragments/en/acme-sh-tls-cert.md +++ b/src/content/fragments/en/acme-sh-tls-cert.md @@ -89,7 +89,7 @@ Limit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a [5% compatibili Use the [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/) header. -``` +```http Strict-Transport-Security: max-age=31536000; includeSubDomains ``` @@ -101,12 +101,12 @@ I've based my initial choices of ciphers on [this list](https://tls.imirhil.fr/c I then asked [Aeris](https://twitter.com/aeris22), the creator of [tls.imirhil.fr](https://tls.imirhil.fr), about it and he advised me to use the following: -``` +```cypher ECDHE+AES:ECDHE+CHACHA20 ``` In order to achieve a perfect score, we can be a little more restrictive with: -``` +```cypher ECDHE+AES256:ECDHE+CHACHA20 ``` diff --git a/src/content/fragments/en/nuxt-graphql-static.md b/src/content/fragments/en/nuxt-graphql-static.md index c34d61b..79ee571 100755 --- a/src/content/fragments/en/nuxt-graphql-static.md +++ b/src/content/fragments/en/nuxt-graphql-static.md @@ -70,16 +70,16 @@ query { #### Inside a page -```javascript +```vue // index.vue <script> import homepageQuery from '~/graphql/queries/singles/homepage' export default { - async asyncData({ $graphql }) { - const data = await $graphql.default.request(homepageQuery) - return { data } - }, + async asyncData({ $graphql }) { + const data = await $graphql.default.request(homepageQuery) + return { data } + } } </script> ``` @@ -88,31 +88,29 @@ export default { It is safer to wait until `fetch` has received a response before displaying anything. You can use `$fetchState` to be sure ([documentation](https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation on the fetch hook (new tab)')). -```javascript +```vue // Header.vue <template> - <header v-if="!$fetchState.pending"> - … - </header> + <header v-if="!$fetchState.pending">…</header> </template> <script> import headerQuery from '~/graphql/queries/singles/header' export default { - data() { - return { - data: {}, - } - }, - async fetch() { - try { - const data = await this.$graphql.default.request(headerQuery) - this.data = data - } catch (error) { - console.error(JSON.stringify(error, undefined, 2)) - } - }, + data() { + return { + data: {} + } + }, + async fetch() { + try { + const data = await this.$graphql.default.request(headerQuery) + this.data = data + } catch (error) { + console.error(JSON.stringify(error, undefined, 2)) + } + } } </script> ``` @@ -121,20 +119,20 @@ export default { To pass options to the request, for example for a multilingual version with [nuxt/i18n](https://i18n.nuxtjs.org/) and/or a url parameter in a dynamic page: -```javascript +```vue // _slug.vue <script> import articleQuery from '~/graphql/queries/articles' export default { - async asyncData({ $graphql, app, params }) { - const locale = app.i18n.localeProperties.iso - const data = await $graphql.default.request(articleQuery, { - code: locale, - slug: params.slug, - }) - return { data } - }, + async asyncData({ $graphql, app, params }) { + const locale = app.i18n.localeProperties.iso + const data = await $graphql.default.request(articleQuery, { + code: locale, + slug: params.slug + }) + return { data } + } } </script> ``` diff --git a/src/content/fragments/fr/acme-sh-tls-cert.md b/src/content/fragments/fr/acme-sh-tls-cert.md index 20f861c..7cc1bc4 100755 --- a/src/content/fragments/fr/acme-sh-tls-cert.md +++ b/src/content/fragments/fr/acme-sh-tls-cert.md @@ -89,7 +89,7 @@ Limiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu [la différence de Utiliser le header [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/). -``` +```http Strict-Transport-Security: max-age=31536000; includeSubDomains ``` @@ -101,12 +101,12 @@ J'avais basé ma première suite sur [cette liste](https://tls.imirhil.fr/cipher J'ai ensuite demandé à [Aeris](https://twitter.com/aeris22), le créateur de [tls.imirhil.fr](https://tls.imirhil.fr), ses conseils sur cette suite. Il m'a recommandé d'utiliser : -``` +```cypher ECDHE+AES:ECDHE+CHACHA20 ``` Afin d'atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci : -``` +```cypher ECDHE+AES256:ECDHE+CHACHA20 ``` diff --git a/src/content/fragments/fr/image-full.mdx b/src/content/fragments/fr/image-full.mdx index a988161..219f1b8 100755 --- a/src/content/fragments/fr/image-full.mdx +++ b/src/content/fragments/fr/image-full.mdx @@ -27,6 +27,7 @@ On est parfois obligé d'utiliser des images dans des balises `img` plutôt que Considérons le html suivant : ```html +<!-- index.html --> <section class="container"> <div class="hero"> <img class="hero__image" src="hero.img" /> @@ -37,15 +38,15 @@ Considérons le html suivant : Et le style suivant : ```css +/* style.css */ .container { padding: 0 14px; - margin-left: auto; - margin-right: auto; - max-width: 1040px; + margin-inline: auto; + max-inline-size: 1040px; } img { - max-width: 100%; - height: auto; + max-inline-size: 100%; + block-size: auto; } ``` @@ -60,10 +61,11 @@ img { Afin de faire prendre à l'image toute la largeur, on agit sur son conteneur : ```css +/* style.css */ .hero { - margin-left: calc(50% - 50vw); + margin-inline-start: calc(50% - 50vw); position: relative; - width: 100vw; + inline-size: 100vw; } ``` @@ -77,12 +79,15 @@ Afin de faire prendre à l'image toute la largeur, on agit sur son conteneur&nbs On peut alors réduire la hauteur du conteneur pour obtenir une bannière plutôt que l'image entière et faire correspondre la hauteur de l'image à la hauteur du conteneur : -```css +```css title='style.css' ins={5, 7-9} .hero { - height: 200px; + margin-inline-start: calc(50% - 50vw); + position: relative; + inline-size: 100vw; + block-size: 200px; } .hero__image { - height: 100%; + block-size: 100%; } ``` @@ -94,9 +99,10 @@ On peut alors réduire la hauteur du conteneur pour obtenir une bannière plutô Il faut ensuite forcer l'image à prendre toute la largeur du conteneur : -```css +```css title='style.css' ins={3} .hero__image { - width: 100%; + block-size: 100%; + inline-size: 100%; } ``` @@ -112,8 +118,10 @@ Pas top… **ENFIN** le code magique pour redonner son ratio à l'image sans la déformer : -```css +```css title='style.css' ins={4,5} .hero__image { + block-size: 100%; + inline-size: 100%; object-fit: cover; object-position: center; /* à positionner comme on veut */ } @@ -125,22 +133,23 @@ Pas top… height='568' /> -Cette technique s'apparente à l'utilisation d'une image de background mais en dur 😁 +Cette technique s'apparente à l'utilisation d'une image de background. ## TL;DR Le code complet : ```css +/* style.css */ .hero { - margin-left: calc(50% - 50vw); + margin-inline-start: calc(50% - 50vw); position: relative; - width: 100vw; - height: 200px; + inline-size: 100vw; + block-size: 200px; } .hero__image { - width: 100%; - height: 100%; + inline-size: 100%; + block-size: 100%; -o-object-fit: cover; object-fit: cover; -o-object-position: center; diff --git a/src/content/fragments/fr/nuxt-graphql-static.md b/src/content/fragments/fr/nuxt-graphql-static.md index b0ba0eb..87fad0f 100755 --- a/src/content/fragments/fr/nuxt-graphql-static.md +++ b/src/content/fragments/fr/nuxt-graphql-static.md @@ -70,16 +70,16 @@ query { #### Dans une page -```javascript +```vue // index.vue <script> import homepageQuery from '~/graphql/queries/singles/homepage' export default { - async asyncData({ $graphql }) { - const data = await $graphql.default.request(homepageQuery) - return { data } - }, + async asyncData({ $graphql }) { + const data = await $graphql.default.request(homepageQuery) + return { data } + } } </script> ``` @@ -88,31 +88,29 @@ export default { Il est plus prudent d'attendre que `fetch` ait reçu une réponse avant d'afficher quoi que ce soit. On peut utiliser `$fetchState` afin d'être tranquille ([documentation](https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation sur la méthode fetch (nouvel onglet)')). -```javascript +```vue // Header.vue <template> - <header v-if="!$fetchState.pending"> - … - </header> + <header v-if="!$fetchState.pending">…</header> </template> <script> import headerQuery from '~/graphql/queries/singles/header' export default { - data() { - return { - data: {}, - } - }, - async fetch() { - try { - const data = await this.$graphql.default.request(headerQuery) - this.data = data - } catch (error) { - console.error(JSON.stringify(error, undefined, 2)) - } - }, + data() { + return { + data: {} + } + }, + async fetch() { + try { + const data = await this.$graphql.default.request(headerQuery) + this.data = data + } catch (error) { + console.error(JSON.stringify(error, undefined, 2)) + } + } } </script> ``` @@ -121,20 +119,20 @@ export default { Pour passer des options à la requête, par exemple pour une version multilingue avec [nuxt/i18n](https://i18n.nuxtjs.org/ 'Documentation de nuxt i18n (nouvel onglet)') et/ou un paramètre d'url dans le cadre d'une page dynamique : -```javascript +```vue // _slug.vue <script> import articleQuery from '~/graphql/queries/articles' export default { - async asyncData({ $graphql, app, params }) { - const locale = app.i18n.localeProperties.iso - const data = await $graphql.default.request(articleQuery, { - code: locale, - slug: params.slug, - }) - return { data } - }, + async asyncData({ $graphql, app, params }) { + const locale = app.i18n.localeProperties.iso + const data = await $graphql.default.request(articleQuery, { + code: locale, + slug: params.slug + }) + return { data } + } } </script> ``` diff --git a/src/content/fragments/fr/visited-links.md b/src/content/fragments/fr/visited-links.md index 5d00dba..f5f007b 100755 --- a/src/content/fragments/fr/visited-links.md +++ b/src/content/fragments/fr/visited-links.md @@ -45,7 +45,7 @@ J'ai personnellement choisi de faire différemment. J'ai décidé d'utiliser un ### Le code -```css {1,4-6} +```css {5,16} title="style.css" a { position: relative; text-decoration: none; diff --git a/src/fonts/wotfard/wotfard-medium-webfont.woff2 b/src/fonts/wotfard/wotfard-medium-webfont.woff2 deleted file mode 100755 index 4af2f232b2cc684bfde8db0092ec47d8e0521477..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33004 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 E05;vW`v3p{ diff --git a/src/fonts/wotfard/wotfard-regular-webfont.woff2 b/src/fonts/wotfard/wotfard-regular-webfont.woff2 deleted file mode 100755 index 1730a04d9b521c623d0162a204766cc1d953311e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31908 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�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 diff --git a/src/fonts/wotfard/wotfard-semibold-webfont.woff2 b/src/fonts/wotfard/wotfard-semibold-webfont.woff2 deleted file mode 100755 index a9bc55985577c3a0c555d112db2af02b30da6aab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33060 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 CY%J0M diff --git a/src/pages/articles/[id].astro b/src/pages/articles/[id].astro index b7ee360..954b845 100755 --- a/src/pages/articles/[id].astro +++ b/src/pages/articles/[id].astro @@ -1,11 +1,13 @@ --- +import { getCollection } from 'astro:content' + +import type { ArticleEntry } from 'src/content.config' import EditorialContent from '../../components/EditorialContent.astro' import BaseLayout from '../../layouts/BaseLayout.astro' -import { getCollection } from 'astro:content' // 1. Generate a new path for every collection entry export async function getStaticPaths() { - const articles = await getCollection('articles') + const articles: ArticleEntry[] = await getCollection('articles') return articles.map((article) => ({ params: { id: article.data.slug }, props: { article } diff --git a/src/pages/articles/index.astro b/src/pages/articles/index.astro index 42dc653..6fe3912 100755 --- a/src/pages/articles/index.astro +++ b/src/pages/articles/index.astro @@ -34,7 +34,7 @@ const pageTitle = 'Articles' <ListCards list={frArticles} routeName='articles' /> </section> <section class='flow' lang='en'> - <h3>In english</h3> + <h3 id='en-articles'>In english</h3> <ListCards list={enArticles} routeName='articles' /> </section> </section> diff --git a/src/pages/fragments/[id].astro b/src/pages/fragments/[id].astro index 8e584a9..24aa62f 100755 --- a/src/pages/fragments/[id].astro +++ b/src/pages/fragments/[id].astro @@ -1,12 +1,13 @@ --- import { getCollection } from 'astro:content' -import EditorialContent from '../../components/EditorialContent.astro' +import type { FragmentEntry } from 'src/content.config' +import EditorialContent from '../../components/EditorialContent.astro' import BaseLayout from '../../layouts/BaseLayout.astro' // 1. Generate a new path for every collection entry export async function getStaticPaths() { - const fragments = await getCollection('fragments') + const fragments: FragmentEntry[] = await getCollection('fragments') return fragments.map((fragment) => ({ params: { id: fragment.data.slug }, props: { fragment } diff --git a/src/pages/fragments/index.astro b/src/pages/fragments/index.astro index 9460240..6bf1088 100755 --- a/src/pages/fragments/index.astro +++ b/src/pages/fragments/index.astro @@ -34,7 +34,7 @@ const pageTitle = 'Fragments' <ListCards list={frFragments} routeName='fragments' /> </section> <section class='flow' lang='en'> - <h3>In english</h3> + <h3 id='en-fragments'>In english</h3> <ListCards list={enFragments} routeName='fragments' /> </section> </section> diff --git a/src/pages/index.astro b/src/pages/index.astro index 0dcbb02..674a479 100755 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -140,7 +140,6 @@ const allReferences = await getCollection('references') } .intro__subtitle { margin: var(--space-s-m) 0; - font-family: 'wotfard'; font-weight: 500; text-align: center; color: var(--color-dark-blue); diff --git a/src/styles/compositions/sidebar.css b/src/styles/compositions/sidebar.css index 0427f2d..9430c6a 100755 --- a/src/styles/compositions/sidebar.css +++ b/src/styles/compositions/sidebar.css @@ -30,7 +30,7 @@ EXCEPTIONS /* A flipped version where the sidebar is on the right */ -.sidebar[data-direction="rtl"] { +.sidebar[data-direction='rtl'] { flex-direction: row-reverse; } diff --git a/src/styles/editorial/buttons.css b/src/styles/editorial/buttons.css index 9c944f6..80ec7e7 100755 --- a/src/styles/editorial/buttons.css +++ b/src/styles/editorial/buttons.css @@ -1,129 +1,131 @@ .btn { - padding: 12px 26px; - position: relative; - display: inline-block; - overflow: hidden; - cursor: pointer; - color: white; - border: none; - background-color: transparent; - transition: background-color 0.3s ease; + padding: 12px 26px; + position: relative; + display: inline-block; + overflow: hidden; + cursor: pointer; + color: white; + border: none; + background-color: transparent; + transition: background-color 0.3s ease; } .btn-icon { - background-color: hotpink; + background-color: hotpink; } .btn-icon::before { - content: url('~assets/svg/arrow-right-white.svg'); - position: absolute; - width: 20px; - top: 50%; - right: 0; - transform: translate(40px, -50%); - transition: transform ease 0.3s; + content: url('~assets/svg/arrow-right-white.svg'); + position: absolute; + width: 20px; + top: 50%; + right: 0; + transform: translate(40px, -50%); + transition: transform ease 0.3s; } .btn-icon:hover, .btn-icon:focus { - background-color: darkorchid; + background-color: darkorchid; } .btn-icon:hover::before, .btn-icon:focus::before { - transform: translate(-10px, -50%); + transform: translate(-10px, -50%); } .btn-icon > span { - display: inline-block; - width: 100%; - height: 100%; - transition: transform 0.3s ease; + display: inline-block; + width: 100%; + height: 100%; + transition: transform 0.3s ease; } .btn-icon:hover > span, .btn-icon:focus > span { - transform: translateX(-10px); + transform: translateX(-10px); } .btn-rideau { - border: 2px solid var(--dark); - color: var(--dark); - background-color: transparent; - transition: color 0.3s ease, border-color 0.3s ease; + border: 2px solid var(--dark); + color: var(--dark); + background-color: transparent; + transition: + color 0.3s ease, + border-color 0.3s ease; } .btn-rideau:hover { - color: white; - border-color: darkorchid; + color: white; + border-color: darkorchid; } .btn-rideau::before { - background: hotpink; + background: hotpink; } .btn-rideau::after { - background: darkorchid; + background: darkorchid; } .btn-rideau::before, .btn-rideau::after { - content: ''; - position: absolute; - height: 100%; - width: 100%; - bottom: 100%; - left: 0; - z-index: -1; - transition: transform 0.3s; - transition-timing-function: ease; - transition-timing-function: cubic-bezier(0.75, 0, 0.125, 1); + content: ''; + position: absolute; + height: 100%; + width: 100%; + bottom: 100%; + left: 0; + z-index: -1; + transition: transform 0.3s; + transition-timing-function: ease; + transition-timing-function: cubic-bezier(0.75, 0, 0.125, 1); } .btn-rideau:hover::before, .btn-rideau:hover::after, .btn-rideau:focus::before, .btn-rideau:focus::after { - transform: translateY(100%); + transform: translateY(100%); } .btn-rideau:hover::after, .btn-rideau:focus::after { - transition-delay: 0.175s; + transition-delay: 0.175s; } .btn-gradient { - background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); - background-size: 400% 400%; - background-position: 0% 50%; - animation: GradientReverse 0.5s ease 1 normal forwards; + background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); + background-size: 400% 400%; + background-position: 0% 50%; + animation: GradientReverse 0.5s ease 1 normal forwards; } .btn-gradient:hover, .btn-gradient:focus { - animation: Gradient 0.5s ease 1 normal forwards; + animation: Gradient 0.5s ease 1 normal forwards; } @keyframes Gradient { - 0% { - background-position: 0% 50%; - } - 100% { - background-position: 100% 100%; - } + 0% { + background-position: 0% 50%; + } + 100% { + background-position: 100% 100%; + } } @keyframes GradientReverse { - 0% { - background-position: 100% 100%; - } - 100% { - background-position: 0% 50%; - } + 0% { + background-position: 100% 100%; + } + 100% { + background-position: 0% 50%; + } } .btn-scale { - overflow: visible; - color: #10113a; - background-color: transparent; + overflow: visible; + color: #10113a; + background-color: transparent; } .btn-scale::after { - content: ''; - position: absolute; - top: 0; - left: 0; - bottom: 0; - width: 100%; - border: 2px solid #10113a; - border-radius: 2px; - transition: transform 0.3s ease; + content: ''; + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 100%; + border: 2px solid #10113a; + border-radius: 2px; + transition: transform 0.3s ease; } .btn-scale:hover::after, .btn-scale:focus::after { - transform: scale(1.1); + transform: scale(1.1); } diff --git a/src/styles/global/fonts.css b/src/styles/global/fonts.css deleted file mode 100755 index 0ceceda..0000000 --- a/src/styles/global/fonts.css +++ /dev/null @@ -1,35 +0,0 @@ -@font-face { - font-family: "wotfard"; - src: url("../../fonts/wotfard/wotfard-medium-webfont.woff2") format("woff2"); - font-weight: 500; - font-style: normal; - font-display: swap; -} -@font-face { - font-family: "wotfard"; - src: url("../../fonts/wotfard/wotfard-semibold-webfont.woff2") format("woff2"); - font-weight: bold; - font-style: normal; - font-display: swap; -} -@font-face { - font-family: "wotfard"; - src: url("../../fonts/wotfard/wotfard-regular-webfont.woff2") format("woff2"); - font-weight: normal; - font-style: normal; - font-display: swap; -} - -/* -* reduces Cumulative Layout Shift -* https://www.24joursdeweb.fr/2021/performance-web-lintegrateur-ce-heros/ -*/ -@font-face { - font-family: "ArialReplace"; - src: local("Arial"); - font-weight: 400; - font-style: normal; - font-display: swap; - size-adjust: 96%; - letter-spacing: 1px; -} diff --git a/src/styles/global/global-styles.css b/src/styles/global/global-styles.css index 9fe406e..f7f554a 100755 --- a/src/styles/global/global-styles.css +++ b/src/styles/global/global-styles.css @@ -14,7 +14,7 @@ body { font-family: var(--font-primary); font-size: var(--size-0); - line-height: 1.5; + line-height: 1.4; color: var(--color-dark); background-color: var(--color-light-white); accent-color: var(--color-brique); @@ -204,46 +204,8 @@ blockquote code { /* code highlight */ -.astro-code, code { font-size: var(--size--1); font-family: var(--font-code); -} -.astro-code { - position: relative; - border-radius: var(--radius-small); - padding-block: var(--space-xs); - direction: ltr; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - word-wrap: normal; - -moz-tab-size: 2; - -o-tab-size: 2; - tab-size: 2; - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; - - code { - padding-inline: var(--space-s); - white-space: pre-wrap; - display: block; - inline-size: fit-content; - min-inline-size: 100%; - } -} - -.line { - &.highlighted::before { - content: ''; - position: absolute; - display: inline-block; - inline-size: 100%; - block-size: 1lh; - inset-inline-start: 0; - background-color: hsla(0, 0%, 80%, 0.1); - } + background-color: var(--color-light-grey); } diff --git a/src/styles/global/reset.css b/src/styles/global/reset.css index 89da684..e361d97 100755 --- a/src/styles/global/reset.css +++ b/src/styles/global/reset.css @@ -1,7 +1,7 @@ /* RESET */ :root { - --font-tnum: "tnum" on; + --font-tnum: 'tnum' on; } * { @@ -29,7 +29,7 @@ } @supports (font-variant-numeric: tabular-nums) { html { - --font-tnum: "____"; + --font-tnum: '____'; font-variant-numeric: tabular-nums; } } @@ -87,7 +87,7 @@ body { /* Remove built-in form typography styles */ :where(input, button, textarea, select), -:where(input[type="file"])::-webkit-file-upload-button { +:where(input[type='file'])::-webkit-file-upload-button { color: inherit; font: inherit; font-size: inherit; @@ -113,7 +113,7 @@ body { } /* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */ -:where(ul, ol)[role="list"] { +:where(ul, ol)[role='list'] { list-style: none; } @@ -124,24 +124,24 @@ a:not([class]) { /* Make it clear that interactive elements are interactive */ :where( - a[href], - area, - button, - input, - label[for], - select, - summary, - textarea, - [tabindex]:not([tabindex*="-"]) - ) { + a[href], + area, + button, + input, + label[for], + select, + summary, + textarea, + [tabindex]:not([tabindex*='-']) +) { cursor: pointer; touch-action: manipulation; } -:where(input[type="file"]) { +:where(input[type='file']) { cursor: auto; } -:where(input[type="file"])::-webkit-file-upload-button, -:where(input[type="file"])::file-selector-button { +:where(input[type='file'])::-webkit-file-upload-button, +:where(input[type='file'])::file-selector-button { cursor: pointer; } @@ -160,14 +160,14 @@ a:not([class]) { /* Make sure users can't select button text */ :where( - button, - button[type], - input[type="button"], - input[type="submit"], - input[type="reset"] - ), -:where(input[type="file"])::-webkit-file-upload-button, -:where(input[type="file"])::file-selector-button { + button, + button[type], + input[type='button'], + input[type='submit'], + input[type='reset'] +), +:where(input[type='file'])::-webkit-file-upload-button, +:where(input[type='file'])::file-selector-button { -webkit-tap-highlight-color: transparent; -webkit-touch-callout: none; user-select: none; @@ -178,9 +178,9 @@ a:not([class]) { :where( button, button[type], - input[type="button"], - input[type="submit"], - input[type="reset"] + input[type='button'], + input[type='submit'], + input[type='reset'] )[disabled] { cursor: not-allowed; } diff --git a/src/styles/global/variables.css b/src/styles/global/variables.css index 9918404..b0f0f4c 100755 --- a/src/styles/global/variables.css +++ b/src/styles/global/variables.css @@ -51,10 +51,10 @@ --space-l-3xl: clamp(2.25rem, calc(-0.08rem + 11.67vw), 7.5rem); /* fonts */ - --font-primary: "wotfard", "ArialReplace", sans-serif; - --font-secondary: "recoleta", Palatino, serif; - --font-code: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; - --font-tnum: "tnum" on; + --font-primary: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', + Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + --font-code: monospace; + --font-tnum: 'tnum' on; /* colors */ --color-dark: hsl(239, 57%, 15%); diff --git a/src/styles/style.css b/src/styles/style.css index 1151ce6..8e37110 100755 --- a/src/styles/style.css +++ b/src/styles/style.css @@ -1,18 +1,10 @@ -/* @import "open-props/style"; */ -/* @import "open-props/normalize"; */ +@import './global/reset.css'; +@import './global/variables.css'; +@import './global/global-styles.css'; -@import "./global/reset.css"; -@import "./global/fonts.css"; -@import "./global/variables.css"; -@import "./global/global-styles.css"; +@import './compositions/grid.css'; +@import './compositions/sidebar.css'; -@import "./compositions/grid.css"; -@import "./compositions/sidebar.css"; - -@import "./utilities/flow.css"; -@import "./utilities/region.css"; -@import "./utilities/wrapper.css"; - -/* @import-glob './blocks/*.css'; */ -/* @import-glob './compositions/*.css'; */ -/* @import-glob './utilities/*.css'; */ +@import './utilities/flow.css'; +@import './utilities/region.css'; +@import './utilities/wrapper.css'; diff --git a/src/styles/utilities/waves.css b/src/styles/utilities/waves.css deleted file mode 100755 index 4fbf8be..0000000 --- a/src/styles/utilities/waves.css +++ /dev/null @@ -1,71 +0,0 @@ -.waves { - background: transparent; - block-size: 4px; - position: relative; -} -.waves::before { - content: ""; - position: absolute; - left: 0; - bottom: 0; - right: 0; - background-repeat: repeat; - block-size: 10px; - background-size: 20px 20px; - background-image: radial-gradient( - circle at 10px -5px, - transparent 12px, - var(--waves-color, var(--color-white)) 13px - ); -} -.waves::after { - content: ""; - position: absolute; - left: 0; - bottom: 0; - right: 0; - background-repeat: repeat; - block-size: 15px; - background-size: 40px 20px; - background-image: radial-gradient( - circle at 10px 15px, - var(--waves-color, var(--color-white)) 12px, - transparent 13px - ); -} - -/* LARGE */ -.waves-container { - block-size: 30px; - position: relative; -} -.waves--large { - position: absolute; - block-size: 30px; - inline-size: 100%; - background: var(--waves-color, var(--color-light)); - bottom: 0; -} - -.waves--large::before, -.waves--large::after { - content: ""; - display: block; - position: absolute; - border-radius: 100% 50%; -} - -.waves--large::before { - inline-size: 55%; - block-size: 100%; - background-color: var(--waves-color, var(--color-light)); - left: -1.5%; - top: 40%; -} -.waves--large::after { - inline-size: 55%; - block-size: 109%; - background-color: var(--waves-bg-color, var(--color-white)); - right: -1.5%; - top: 60%; -} diff --git a/src/styles/utilities/wrapper.css b/src/styles/utilities/wrapper.css index d338ba0..a76a746 100755 --- a/src/styles/utilities/wrapper.css +++ b/src/styles/utilities/wrapper.css @@ -32,6 +32,7 @@ grid-column: full; } /* set full width color to full grid */ +/* prettier-ignore */ .wrapper.full-width-color { /* https://codepen.io/t_afif/pen/oNEaqQX */ border-image: conic-gradient(var(--color-full-width, var(--color-light)) 0 0) diff --git a/src/styles/vendor/one-dark-pro.css b/src/styles/vendor/one-dark-pro.css deleted file mode 100755 index 9eba90b..0000000 --- a/src/styles/vendor/one-dark-pro.css +++ /dev/null @@ -1,271 +0,0 @@ -code[class*="language-"], -pre[class*="language-"], -:not(pre) > code { - color: #abb2bf; - background: none; - font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; - font-size: var(--size--1); - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - word-wrap: normal; - line-height: 1.5; - - -moz-tab-size: 2; - -o-tab-size: 2; - tab-size: 2; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; -} -/* Code blocks */ -pre[class*="language-"] { - padding: var(--space-2xs-xs) var(--space-xs-s); - margin: var(--space-2xs-xs) 0; - overflow: auto; - border-radius: 10px; -} - -/* Inline code */ -:not(pre) > code[class*="language-"], -pre[class*="language-"] { - background: #282c34; -} -:not(pre) > code[class*="language-"], -:not(pre) > code { - padding: 0.2em; - white-space: normal; - color: var(--color-dark); - border-radius: 0.3em; - background-color: var(--color-light-grey); -} -pre[class*="language-"]::selection, -pre[class*="language-"] ::selection, -code[class*="language-"]::selection, -code[class*="language-"] ::selection { - background: rgba(148, 170, 209, 0.2); -} - -/* General styling */ -.token.comment, -.token.prolog, -.token.doctype, -.token.cdata, -.token.punctuation { - color: #abb2bf; -} - -.token.namespace { - opacity: 0.7; -} -.token.keyword, -.token.regex, -.token.important { - color: #c678dd; -} -.token.property, -.token.attr-name, -.token.constant, -.token.symbol, -.token.deleted { - color: #e06c75; -} - -.token.unit { - color: #2f02d1; -} - -.token.boolean, -.token.number, -.token.selector, -.token.tag, -.token.char, -.token.builtin, -.token.inserted, -.token.entity, -.token.url, -.language-css .token.string, -.style .token.string, -.token.variable { - color: #ce004b; -} - -.token.operator, -.token.pseudo-element, -.token.pseudo-class, -.token.attr-value, -.token.function, -.token.class-name { - color: #abb2bf; -} - -.token.atrule { - color: #c678dd; -} - -.token.string { - color: #10113a; -} - -/* Specific styling */ -.language-html .token.doctype-tag { - color: #e06c75; -} -.language-html .token.name { - color: #d19a66; -} -.language-html .token.punctuation { - color: #abb2bf; -} -.language-html .token.tag .token.tag { - color: #e06c75; -} -.language-html .token.tag .token.attr-name { - color: #d19a66; -} -.language-html .token.tag .token.attr-value { - color: #98c379; -} -.language-html .token.tag .token.attr-value .token.punctuation { - color: #98c379; -} -.language-html .token.tag .token.attr-value .token.punctuation.attr-equals { - color: #abb2bf; -} -.language-html .token.comment { - color: #7f848e; - font-style: italic; -} -code[class*="language-css"], -pre[class*="language-css"] { - color: #d19a66; -} -.language-css .token.operator, -.language-css .token.punctuation, -.language-css .token.property, -.language-css .token.operator, -.language-css .token.combinator { - color: #abb2bf; -} -.language-css .token.attr-name, -.language-css .token.color, -.language-css .token.number, -.language-css .token.class { - color: #d19a66; -} -.language-css .token.attr-value, -.language-css .token.string { - color: #98c379; -} -.language-css .token.selector, -.language-css .token.unit { - color: #e06c75; -} -.language-css .token.property.prefix, -.language-css .token.pseudo-element, -.language-css .token.pseudo-class { - color: #56b6c2; -} -.language-css .token.atrule { - color: #abb2bf; -} -.language-css .token.atrule .token.rule { - color: #c678dd; -} -.language-css .token.comment { - color: #7f848e; - font-style: italic; -} -.language-css .token.keyword { - color: #56b6c2; -} -code[class*="language-javascript"], -pre[class*="language-javascript"] { - color: #e06c75; -} -.language-javascript { - color: #e06c75; -} -.language-javascript .token.punctuation { - color: #abb2bf; -} -.language-javascript .token.comment { - color: #7f848e; - font-style: italic; -} -.language-javascript .token.keyword.this, -.language-javascript .token.dom.variable, -.language-javascript .token.class-name { - color: #e5c07b; -} -.language-javascript .token.null, -.language-javascript .token.boolean, -.language-javascript .token.number { - color: #d19a66; -} -.language-javascript .token.property-access, -.language-javascript .token.imports, -.language-javascript .token.parameter { - color: #e06c75; -} -.language-javascript .token.parameter { - font-style: italic; -} -.language-javascript .token.keyword { - color: #c678dd; -} -.language-javascript .token.function, -.language-javascript .token.property-access.function.method { - color: #61afef; -} -.language-javascript .token.regex-source, -.language-javascript .token.operator { - color: #56b6c2; -} -.language-javascript .token.regex-delimiter, -.language-javascript .token.string { - color: #98c379; -} -.language-json .token.punctuation, -.language-json .token.operator { - color: #abb2bf; -} -.language-json .token.string { - color: #98c379; -} -.language-json .token.boolean, -.language-json .token.number, -.language-json .token.null.keyword { - color: #d19a66; -} -.language-json .token.property { - color: #e06c75; -} -.language-bash .token.string, -.language-shell .token.string { - color: #98c379; -} -.language-bash .token.shebang.important, -.language-bash .token.comment, -.language-shell .token.shebang.important, -.language-shell .token.comment { - color: #7f848e; - font-style: italic; -} -.language-bash .token.builtin.class-name, -.language-bash .token.entity, -.language-shell .token.builtin.class-name, -.language-shell .token.entity { - color: #56b6c2; -} -.language-bash .token.keyword, -.language-shell .token.keyword { - color: #c678dd; -} -.language-bash .token.variable, -.language-shell .token.variable { - color: #e06c75; -} diff --git a/src/utils/i18n.ts b/src/utils/i18n.ts deleted file mode 100644 index 0b3fc69..0000000 --- a/src/utils/i18n.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { defaultLang, ui } from '../i18n/ui' - -export function getLangFromUrl(url: URL) { - const [, lang] = url.pathname.split('/') - if (lang in ui) return lang as keyof typeof ui - return defaultLang -} - -type NestedKeyOf<T> = { - [K in keyof T]: T[K] extends object - ? `${K & string}.${NestedKeyOf<T[K]> & string}` - : K & string -}[keyof T] - -export function useTranslations(lang: keyof typeof ui) { - return function t(key: NestedKeyOf<(typeof ui)[typeof defaultLang]>) { - const keys = key.split('.') - let value = ui[lang] - let fallback = ui[defaultLang] - - for (const k of keys) { - value = value?.[k] - fallback = fallback?.[k] - } - - return value || fallback - } -} -- 2.45.2 From 069baaf81c0539f6fb42c64305e89d27b94e960f Mon Sep 17 00:00:00 2001 From: nico <contact@nardu.in> Date: Thu, 2 Jan 2025 14:52:11 +0100 Subject: [PATCH 07/16] remove redirects & fix rss + add rel=me links + en link --- .astro/content-modules.mjs | 6 +- .astro/content.d.ts | 206 ++++++++++++++++++++ .astro/data-store.json | 2 +- astro.config.mjs | 22 --- src/components/CardEditorial.astro | 140 +++++++------ src/components/Footer.astro | 39 ++-- src/components/Head.astro | 10 +- src/components/SocialRel.astro | 12 ++ src/content/articles/en/2025.md | 15 +- src/content/articles/fr/2022.md | 2 + src/content/articles/fr/2023.md | 2 + src/content/articles/fr/sci-hub-blocage.mdx | 2 + src/content/articles/fr/the-day-I-jamd.mdx | 2 + src/pages/rss.xml.js | 2 +- src/styles/global/global-styles.css | 2 +- 15 files changed, 338 insertions(+), 126 deletions(-) create mode 100644 src/components/SocialRel.astro diff --git a/.astro/content-modules.mjs b/.astro/content-modules.mjs index 2ca7e6f..815dd4a 100644 --- a/.astro/content-modules.mjs +++ b/.astro/content-modules.mjs @@ -2,13 +2,13 @@ export default new Map([ ["src/content/articles/en/after-effects-expressions.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fafter-effects-expressions.mdx&astroContentModuleFlag=true")], ["src/content/articles/en/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], -["src/content/fragments/en/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fimage-full.mdx&astroContentModuleFlag=true")], ["src/content/articles/en/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], ["src/content/articles/en/video-compression.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fvideo-compression.mdx&astroContentModuleFlag=true")], +["src/content/fragments/en/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fimage-full.mdx&astroContentModuleFlag=true")], ["src/content/fragments/en/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], ["src/content/articles/fr/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], +["src/content/articles/fr/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], ["src/content/fragments/fr/buttons.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fbuttons.mdx&astroContentModuleFlag=true")], ["src/content/fragments/fr/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fimage-full.mdx&astroContentModuleFlag=true")], -["src/content/fragments/fr/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], -["src/content/articles/fr/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")]]); +["src/content/fragments/fr/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fsuper-cookies.mdx&astroContentModuleFlag=true")]]); \ No newline at end of file diff --git a/.astro/content.d.ts b/.astro/content.d.ts index e69de29..6ea9a82 100644 --- a/.astro/content.d.ts +++ b/.astro/content.d.ts @@ -0,0 +1,206 @@ +declare module 'astro:content' { + interface Render { + '.mdx': Promise<{ + Content: import('astro').MarkdownInstance<{}>['Content']; + headings: import('astro').MarkdownHeading[]; + remarkPluginFrontmatter: Record<string, any>; + components: import('astro').MDXInstance<{}>['components']; + }>; + } +} + +declare module 'astro:content' { + export interface RenderResult { + Content: import('astro/runtime/server/index.js').AstroComponentFactory; + headings: import('astro').MarkdownHeading[]; + remarkPluginFrontmatter: Record<string, any>; + } + interface Render { + '.md': Promise<RenderResult>; + } + + export interface RenderedContent { + html: string; + metadata?: { + imagePaths: Array<string>; + [key: string]: unknown; + }; + } +} + +declare module 'astro:content' { + type Flatten<T> = T extends { [K: string]: infer U } ? U : never; + + export type CollectionKey = keyof AnyEntryMap; + export type CollectionEntry<C extends CollectionKey> = Flatten<AnyEntryMap[C]>; + + export type ContentCollectionKey = keyof ContentEntryMap; + export type DataCollectionKey = keyof DataEntryMap; + + type AllValuesOf<T> = T extends any ? T[keyof T] : never; + type ValidContentEntrySlug<C extends keyof ContentEntryMap> = AllValuesOf< + ContentEntryMap[C] + >['slug']; + + /** @deprecated Use `getEntry` instead. */ + export function getEntryBySlug< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug<C> | (string & {}), + >( + collection: C, + // Note that this has to accept a regular string too, for SSR + entrySlug: E, + ): E extends ValidContentEntrySlug<C> + ? Promise<CollectionEntry<C>> + : Promise<CollectionEntry<C> | undefined>; + + /** @deprecated Use `getEntry` instead. */ + export function getDataEntryById<C extends keyof DataEntryMap, E extends keyof DataEntryMap[C]>( + collection: C, + entryId: E, + ): Promise<CollectionEntry<C>>; + + export function getCollection<C extends keyof AnyEntryMap, E extends CollectionEntry<C>>( + collection: C, + filter?: (entry: CollectionEntry<C>) => entry is E, + ): Promise<E[]>; + export function getCollection<C extends keyof AnyEntryMap>( + collection: C, + filter?: (entry: CollectionEntry<C>) => unknown, + ): Promise<CollectionEntry<C>[]>; + + export function getEntry< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug<C> | (string & {}), + >(entry: { + collection: C; + slug: E; + }): E extends ValidContentEntrySlug<C> + ? Promise<CollectionEntry<C>> + : Promise<CollectionEntry<C> | undefined>; + export function getEntry< + C extends keyof DataEntryMap, + E extends keyof DataEntryMap[C] | (string & {}), + >(entry: { + collection: C; + id: E; + }): E extends keyof DataEntryMap[C] + ? Promise<DataEntryMap[C][E]> + : Promise<CollectionEntry<C> | undefined>; + export function getEntry< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug<C> | (string & {}), + >( + collection: C, + slug: E, + ): E extends ValidContentEntrySlug<C> + ? Promise<CollectionEntry<C>> + : Promise<CollectionEntry<C> | undefined>; + export function getEntry< + C extends keyof DataEntryMap, + E extends keyof DataEntryMap[C] | (string & {}), + >( + collection: C, + id: E, + ): E extends keyof DataEntryMap[C] + ? string extends keyof DataEntryMap[C] + ? Promise<DataEntryMap[C][E]> | undefined + : Promise<DataEntryMap[C][E]> + : Promise<CollectionEntry<C> | undefined>; + + /** Resolve an array of entry references from the same collection */ + export function getEntries<C extends keyof ContentEntryMap>( + entries: { + collection: C; + slug: ValidContentEntrySlug<C>; + }[], + ): Promise<CollectionEntry<C>[]>; + export function getEntries<C extends keyof DataEntryMap>( + entries: { + collection: C; + id: keyof DataEntryMap[C]; + }[], + ): Promise<CollectionEntry<C>[]>; + + export function render<C extends keyof AnyEntryMap>( + entry: AnyEntryMap[C][string], + ): Promise<RenderResult>; + + export function reference<C extends keyof AnyEntryMap>( + collection: C, + ): import('astro/zod').ZodEffects< + import('astro/zod').ZodString, + C extends keyof ContentEntryMap + ? { + collection: C; + slug: ValidContentEntrySlug<C>; + } + : { + collection: C; + id: keyof DataEntryMap[C]; + } + >; + // Allow generic `string` to avoid excessive type errors in the config + // if `dev` is not running to update as you edit. + // Invalid collection names will be caught at build time. + export function reference<C extends string>( + collection: C, + ): import('astro/zod').ZodEffects<import('astro/zod').ZodString, never>; + + type ReturnTypeOrOriginal<T> = T extends (...args: any[]) => infer R ? R : T; + type InferEntrySchema<C extends keyof AnyEntryMap> = import('astro/zod').infer< + ReturnTypeOrOriginal<Required<ContentConfig['collections'][C]>['schema']> + >; + + type ContentEntryMap = { + + }; + + type DataEntryMap = { + "HPsections": Record<string, { + id: string; + body?: string; + collection: "HPsections"; + data: InferEntrySchema<"HPsections">; + rendered?: RenderedContent; + filePath?: string; +}>; +"articles": Record<string, { + id: string; + body?: string; + collection: "articles"; + data: InferEntrySchema<"articles">; + rendered?: RenderedContent; + filePath?: string; +}>; +"fragments": Record<string, { + id: string; + body?: string; + collection: "fragments"; + data: InferEntrySchema<"fragments">; + rendered?: RenderedContent; + filePath?: string; +}>; +"references": Record<string, { + id: string; + body?: string; + collection: "references"; + data: InferEntrySchema<"references">; + rendered?: RenderedContent; + filePath?: string; +}>; +"veille": Record<string, { + id: string; + body?: string; + collection: "veille"; + data: InferEntrySchema<"veille">; + rendered?: RenderedContent; + filePath?: string; +}>; + + }; + + type AnyEntryMap = ContentEntryMap & DataEntryMap; + + export type ContentConfig = typeof import("../src/content.config.js"); +} diff --git a/.astro/data-store.json b/.astro/data-store.json index e0d231f..2c57848 100644 --- a/.astro/data-store.json +++ b/.astro/data-store.json @@ -1 +1 @@ -[["Map",1,2,9,10,124,125,173,174,537,538,552,553],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.1.1","content-config-digest","8021b3469f132349","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"site\":\"https://www.nardu.in\",\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true},\"redirects\":{\"/articles/en/[...id]\":\"/articles/en-[...id]\",\"/snippets/en/[...id]\":\"/fragments/en-[...id]\"},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[\"assets.nardu.in\"],\"remotePatterns\":[{\"protocol\":\"https\"}]},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":false,\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[[null,{\"theme\":\"one-dark-pro\",\"plugins\":[{\"name\":\"Line numbers\",\"styleSettings\":{\"defaultValues\":{\"lineNumbers\":{\"foreground\":\"inherit\",\"highlightForeground\":\"inherit\"}},\"cssVarExclusions\":[],\"cssVarReplacements\":[]},\"hooks\":{}},{\"name\":\"astro-expressive-code\",\"hooks\":{}}],\"defaultProps\":{\"showLineNumbers\":false,\"overridesByLang\":{\"css,html,js,ts,vue\":{\"showLineNumbers\":true}}}}]],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"responsiveImages\":false},\"legacy\":{\"collections\":false}}","HPsections",["Map",11,12,31,32,52,53,78,79,96,97],"013-offre",{"id":11,"data":13,"body":18,"filePath":19,"digest":20,"rendered":21},{"type":14,"lang":15,"image":16,"order":17},"section","fr","/assets/images/home/offre-1.3.svg",1.3,"## Et l'éco-conception alors ?\n\nJe ne conçois pas l'éco-conception comme une offre. C'est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l'éco-conception sans accessibilité, j'applique donc ces méthodologies quelque soit le projet !","src/data/HP/013-offre.md","03e37f364ac27cb4",{"html":22,"metadata":23},"\u003Ch2 id=\"et-léco-conception-alors\">Et l’éco-conception alors ?\u003C/h2>\n\u003Cp>Je ne conçois pas l’éco-conception comme une offre. C’est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l’éco-conception sans accessibilité, j’applique donc ces méthodologies quelque soit le projet !\u003C/p>",{"headings":24,"imagePaths":29,"frontmatter":30},[25],{"depth":26,"slug":27,"text":28},2,"et-léco-conception-alors","Et l’éco-conception alors ?",[],{"type":14,"lang":15,"order":17,"image":16},"011-offre",{"id":31,"data":33,"body":40,"filePath":41,"digest":42,"rendered":43},{"type":14,"lang":15,"uid":34,"image":35,"order":36,"quickTitle":37,"quickImage":38,"reference":39},"offre","/assets/images/home/offre-1.1.svg",1.1,"Mes offres en freelance","/assets/images/home/icon-desktop.svg","parole-expression","## L'offre site web classique\n\nCette offre est destinée à un public souhaitant **se doter d'un site web**, sans forcément intégrer l'accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du [référentiel général d'amélioration de l'accessibilité](https://accessibilite.numerique.gouv.fr/) (\u003Cabbr>RGAA\u003C/abbr>).\n\nL'objectif principal de cette offre étant d'**établir une présence en ligne** pour le client. Que cette dernière ait un but informatif et/ou éditorial.\n\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->","src/data/HP/011-offre.md","290ecd1ed94a1087",{"html":44,"metadata":45},"\u003Ch2 id=\"loffre-site-web-classique\">L’offre site web classique\u003C/h2>\n\u003Cp>Cette offre est destinée à un public souhaitant \u003Cstrong>se doter d’un site web\u003C/strong>, sans forcément intégrer l’accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du \u003Ca href=\"https://accessibilite.numerique.gouv.fr/\">référentiel général d’amélioration de l’accessibilité\u003C/a> (\u003Cabbr>RGAA\u003C/abbr>).\u003C/p>\n\u003Cp>L’objectif principal de cette offre étant d’\u003Cstrong>établir une présence en ligne\u003C/strong> pour le client. Que cette dernière ait un but informatif et/ou éditorial.\u003C/p>\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->",{"headings":46,"imagePaths":50,"frontmatter":51},[47],{"depth":26,"slug":48,"text":49},"loffre-site-web-classique","L’offre site web classique",[],{"type":14,"uid":34,"lang":15,"image":35,"order":36,"quickTitle":37,"quickImage":38,"reference":39},"020-methodo",{"id":52,"data":54,"body":59,"filePath":60,"digest":61,"rendered":62},{"type":14,"lang":15,"uid":55,"image":56,"order":26,"quickTitle":57,"quickImage":58},"methodology","/assets/images/home/methodo.svg","Ma méthodologie","/assets/images/home/icon-methodo.svg","## Méthodologie\n\n### Accessibilité par défaut\n\nEngagé pour un web plus accessible, je crée des **sites web** en m'appuyant sur le [référentiel général d'amélioration de l'accessibilité (RGAA)](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) ainsi que sur les bonnes pratiques [Opquast.](https://www.opquast.com/rendre-le-web-meilleur/)\n\n### Sobriété par choix\n\nJe privilégie le développement de **sites statiques** en adoptant une approche [d'éco-conception numérique.](https://eco-conception.designersethiques.org/guide/fr/) \nC'est-à-dire que le site est pensé pour n'embarquer que les fonctionnalités nécessaires à son utilisation.\n\nCette approche présente de **nombreux avantages :**\n\n- chargement rapide des pages ;\n- sécurité renforcée ;\n- coûts serveur réduits ;\n- maintenance facilitée.\n\nLorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l'interface. Cela permet de garantir que **le site reste en ligne** même si le CMS venait à ne plus fonctionner.","src/data/HP/020-methodo.md","75a09b4e0b1e926b",{"html":63,"metadata":64},"\u003Ch2 id=\"méthodologie\">Méthodologie\u003C/h2>\n\u003Ch3 id=\"accessibilité-par-défaut\">Accessibilité par défaut\u003C/h3>\n\u003Cp>Engagé pour un web plus accessible, je crée des \u003Cstrong>sites web\u003C/strong> en m’appuyant sur le \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité (RGAA)\u003C/a> ainsi que sur les bonnes pratiques \u003Ca href=\"https://www.opquast.com/rendre-le-web-meilleur/\">Opquast.\u003C/a>\u003C/p>\n\u003Ch3 id=\"sobriété-par-choix\">Sobriété par choix\u003C/h3>\n\u003Cp>Je privilégie le développement de \u003Cstrong>sites statiques\u003C/strong> en adoptant une approche \u003Ca href=\"https://eco-conception.designersethiques.org/guide/fr/\">d’éco-conception numérique.\u003C/a>\u003Cbr>\nC’est-à-dire que le site est pensé pour n’embarquer que les fonctionnalités nécessaires à son utilisation.\u003C/p>\n\u003Cp>Cette approche présente de \u003Cstrong>nombreux avantages :\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>chargement rapide des pages ;\u003C/li>\n\u003Cli>sécurité renforcée ;\u003C/li>\n\u003Cli>coûts serveur réduits ;\u003C/li>\n\u003Cli>maintenance facilitée.\u003C/li>\n\u003C/ul>\n\u003Cp>Lorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l’interface. Cela permet de garantir que \u003Cstrong>le site reste en ligne\u003C/strong> même si le CMS venait à ne plus fonctionner.\u003C/p>",{"headings":65,"imagePaths":76,"frontmatter":77},[66,69,73],{"depth":26,"slug":67,"text":68},"méthodologie","Méthodologie",{"depth":70,"slug":71,"text":72},3,"accessibilité-par-défaut","Accessibilité par défaut",{"depth":70,"slug":74,"text":75},"sobriété-par-choix","Sobriété par choix",[],{"type":14,"uid":55,"lang":15,"image":56,"order":26,"quickTitle":57,"quickImage":58},"012-offre",{"id":78,"data":80,"body":84,"filePath":85,"digest":86,"rendered":87},{"type":14,"lang":15,"image":81,"order":82,"reference":83},"/assets/images/home/offre-1.2.svg",1.2,"rose-primaire","## L'offre accessibilité avancée\n\nCette offre s'adresse plus spécifiquement aux entités pour lesquelles **l'accessibilité du site est un critère majeur.** Qu'il s'agisse d'une création ou d'une mise en conformité après un audit d'accessibilité.\n\nLorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\n\n- [Rose Primaire](https://roseprimaire.com/) pour le conseil et l'accompagnement du projet ;\n- [Sylvain Plantier](https://jedessinebien.com/) et/ou [Benoît Etchevery](http://ben-etche.com/) pour l'illustration et la direction artistique.\n\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->","src/data/HP/012-offre.md","2a3bf3411b3c171b",{"html":88,"metadata":89},"\u003Ch2 id=\"loffre-accessibilité-avancée\">L’offre accessibilité avancée\u003C/h2>\n\u003Cp>Cette offre s’adresse plus spécifiquement aux entités pour lesquelles \u003Cstrong>l’accessibilité du site est un critère majeur.\u003C/strong> Qu’il s’agisse d’une création ou d’une mise en conformité après un audit d’accessibilité.\u003C/p>\n\u003Cp>Lorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://roseprimaire.com/\">Rose Primaire\u003C/a> pour le conseil et l’accompagnement du projet ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://jedessinebien.com/\">Sylvain Plantier\u003C/a> et/ou \u003Ca href=\"http://ben-etche.com/\">Benoît Etchevery\u003C/a> pour l’illustration et la direction artistique.\u003C/li>\n\u003C/ul>\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->",{"headings":90,"imagePaths":94,"frontmatter":95},[91],{"depth":26,"slug":92,"text":93},"loffre-accessibilité-avancée","L’offre accessibilité avancée",[],{"type":14,"lang":15,"order":82,"image":81,"reference":83},"030-about",{"id":96,"data":98,"body":103,"filePath":104,"digest":105,"rendered":106},{"type":14,"lang":15,"uid":99,"image":100,"order":70,"quickTitle":101,"quickImage":102},"about","/assets/images/home/about.svg","Moi","/assets/images/home/icon-heart.svg","## À propos\n\n### Formations personnelles\n\nAfin de solidifier mes compétences, j'ai suivi les formations et passé les certifications suivantes :\n\n- [Opquast](https://directory.opquast.com/fr/certificat/CTQSKP/) - Maîtrise de la qualité en projet web ;\n- Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\n\n### Formations des autres\n\nDepuis plusieurs années, j'interviens dans différents campus afin de dispenser des cours de développement web.\n\n### Temps libre\n\nJ’essaie de contribuer à des [projets open source](https://git.nardu.in/explore/repos) qui me tiennent à cœur et je m'engage localement avec le collectif [good-it!](https://www.good-it.org/)\n\nAh et j’écris [des articles](/articles) aussi ! Des articles sur le design, le développement web et l’informatique.","src/data/HP/030-about.md","a7abff6d744406ce",{"html":107,"metadata":108},"\u003Ch2 id=\"à-propos\">À propos\u003C/h2>\n\u003Ch3 id=\"formations-personnelles\">Formations personnelles\u003C/h3>\n\u003Cp>Afin de solidifier mes compétences, j’ai suivi les formations et passé les certifications suivantes :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://directory.opquast.com/fr/certificat/CTQSKP/\">Opquast\u003C/a> - Maîtrise de la qualité en projet web ;\u003C/li>\n\u003Cli>Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"formations-des-autres\">Formations des autres\u003C/h3>\n\u003Cp>Depuis plusieurs années, j’interviens dans différents campus afin de dispenser des cours de développement web.\u003C/p>\n\u003Ch3 id=\"temps-libre\">Temps libre\u003C/h3>\n\u003Cp>J’essaie de contribuer à des \u003Ca href=\"https://git.nardu.in/explore/repos\">projets open source\u003C/a> qui me tiennent à cœur et je m’engage localement avec le collectif \u003Ca href=\"https://www.good-it.org/\">good-it!\u003C/a>\u003C/p>\n\u003Cp>Ah et j’écris \u003Ca href=\"/articles\">des articles\u003C/a> aussi ! Des articles sur le design, le développement web et l’informatique.\u003C/p>",{"headings":109,"imagePaths":122,"frontmatter":123},[110,113,116,119],{"depth":26,"slug":111,"text":112},"à-propos","À propos",{"depth":70,"slug":114,"text":115},"formations-personnelles","Formations personnelles",{"depth":70,"slug":117,"text":118},"formations-des-autres","Formations des autres",{"depth":70,"slug":120,"text":121},"temps-libre","Temps libre",[],{"type":14,"uid":99,"lang":15,"image":100,"order":70,"quickTitle":101,"quickImage":102},"references",["Map",126,127,139,140,39,153,83,163],"3w",{"id":126,"data":128,"filePath":135,"digest":136,"rendered":137},{"title":126,"subtitle":129,"url":130,"lang":15,"slug":126,"tags":131,"createdAt":134},"J'ai fait de la doc!","https://3-w.fr",[132,133],"Front-end","documentation",["Date","2022-10-19T18:02:00.000Z"],"src/content/references/3w.md","0d3d94c8af754e1b",{"html":138},"","natureo",{"id":139,"data":141,"filePath":150,"digest":151,"rendered":152},{"title":142,"subtitle":143,"url":144,"lang":15,"slug":139,"tags":145,"createdAt":149},"Nature en Occitanie","La sobriété au naturel.","https://www.natureo.org/",[132,146,147,148],"accessibilité","éco-conception","CMS",["Date","2023-04-19T18:02:00.000Z"],"src/content/references/natureo.md","6a7169b855b57024",{"html":138},{"id":39,"data":154,"filePath":160,"digest":161,"rendered":162},{"title":155,"subtitle":156,"url":157,"lang":15,"slug":39,"tags":158,"createdAt":159},"Parole Expression","Un nouveau site pour l'association.","https://www.paroleexpression.fr/",[132,147,148],["Date","2022-04-19T17:11:00.000Z"],"src/content/references/parole-expression.md","ec95a408f8c3e99c",{"html":138},{"id":83,"data":164,"filePath":170,"digest":171,"rendered":172},{"title":165,"subtitle":166,"url":167,"lang":15,"slug":83,"tags":168,"createdAt":169},"Rose Primaire","Une agence comme on l'aime.","https://roseprimaire.com/",[132,146,147,148],["Date","2023-04-19T17:11:00.000Z"],"src/content/references/rose-primaire.md","a0133200cf1bee58",{"html":138},"articles",["Map",175,176,188,189,225,226,238,239,270,271,288,289,318,319,347,348,363,364,376,377,387,388,398,399,415,416,432,433,483,484,493,494],"en-after-effects-expressions",{"id":175,"data":177,"body":185,"filePath":186,"digest":187,"deferredRender":184},{"title":178,"subtitle":179,"lang":180,"tags":181,"type":173,"slug":175,"createdAt":183,"code":184},"After Effects Expressions","Animation on steroïds.","en",[182],"Design",["Date","2019-04-24T09:00:00.000Z"],true,"import AstroImage from '../../../components/AstroImage.astro'\n\n## An ever lasting battle\n\nThere is very little documentation and the existing one is hard to find or very old. Very often I just don't have the time to dive into expression learning while animating even though it could help the entire project on the long term.\nSo the last time I had to do a complex animation, **I took the damn time!**\n\n## The begining of the end (of keyframes).\n\nEveryone uses expressions whether they know it or not. Most of the time it's a rather transparent process for the animator. For example: when parenting a property to another one, After Effects creates an expression for us.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/basic_expression_d81b12f1ac.jpeg'\n\twidth='728'\n\theight='80'\n\talt='Parenting the position of the form to a null creates an expression.'\n/>\n\nOver the last updates, Adobe has made an effort to make expressions more accessible to everyone. For example, the expression box is now resembling a code editor thanks to code-coloring and auto-completion features. After Effects expression feel like JavaScript with custom functions.\n\nThose custom functions can be called through a menu once you enabled the expressions on a property. It offers organized shortcut and proper syntax to all of AE native functions and a bunch of JavaScript standard ones.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/shortcut_39cc19d383.jpeg'\n\twidth='728'\n\theight='322'\n\talt='Alt + Click the stopwatch to access the shortcuts.'\n/>\n\n## So I need to learn javascript to do motion design now?\n\n### Why bother?\n\nI know that most animators don't have any kind of development background. However, if Adobe thought it best to let us use expressions, I think we ought to, at least, try.\n\n> A lot of incredible professionals like [Mt Mograph](https://www.mtmograph.com/) and [Video Copilot](https://videocopilot.net/) use expressions.\n\nLike every optimization process, building an expressions knowledge takes time. However, like all optimization process, you will benefit from it afterwards.\n\n### Where to learn\n\nI've gathered a list of my favourite learning grounds. Plenty more exist, **go get'em!**\n\n- [Adobe official expression starter guide (FR)](https://helpx.adobe.com/fr/after-effects/using/expression-language-reference.html)\n- [Adobe official expression basic (EN)](https://helpx.adobe.com/after-effects/using/expression-basics.html)\n- [Adobe forums for expressions](https://community.adobe.com/t5/after-effects/bd-p/after-effects?page=1&sort=latest_replies&filter=all&topics=label-expressions)\n- [Creative Cow expressions forums](https://creativecow.net/forums/forum/adobe-after-effects-expressions/)\n- [Youtube channel about expressions](https://www.youtube.com/playlist?list=PLvr5U5ZSt6IzHyvSL9fo0M9NRPsTvra31)\n- [All expressions explained](http://aescript.jecool.net/reference/)\n- [All expressions explained again](http://expressions.aenhancers.com/index.html)\n- [Nice examples of basic expressions](https://www.schoolofmotion.com/tutorials/amazing-expressions-in-after-effects)\n\n## Real world example\n\n### Number counter\n\nLet's say you need to animate a rather simple counter from 0% to 100%.\n\n- Start by creating a text layer. Define your typographic choices, colours, etc.\n- On the effect menu add expression options > slider control\n- Alt + Click the Source text property\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/alt-counter.mp4' type='video/mp4' />\n\u003C/video>\n\n- Parent the source text to the slider control through the pickwhip.\n\n\u003Cvideo width='462' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/pickwhip.mp4' type='video/mp4' />\n\u003C/video>\n\nYou should get something like this in the expressions panel:\n\n```javascript\neffect(\"Slider Control\")(\"Slider\")​\n```\n\n- Set two keyframes on the slider from 0 to 100. The text should update accordingly.\n- By default, After Effects does not round numbers. In the expression panel, wrap your expression with the `Math.round()` function.\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/round.mp4' type='video/mp4' />\n\u003C/video>\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\"))​\n```\n\nGreat! We have a working counter. But we wanted a percentage counter. We could add a % glyph in another text layer but let's not.\n\nStill in the expression panel, we're going to add a string containing the % glyph, using basic JavaScript concatenation: `+ '%'`\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\")) + '%'​\n```\n\n\u003Cvideo width='538' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/percent.mp4' type='video/mp4' />\n\u003C/video>\n\n**And there we go!** A fully functioning and customizable counter using a slider controller and expressions.","src/content/articles/en/after-effects-expressions.mdx","3b6f88fbf35af1a4","en-2023",{"id":188,"data":190,"body":197,"filePath":198,"digest":199,"rendered":200},{"title":191,"subtitle":192,"lang":180,"tags":193,"type":173,"slug":188,"createdAt":195,"updatedAt":196},"Nico v2.5","Update 2023.",[194],"Freelance",["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"This article will be updated when I have something new to share during the year 2023.\n\n## The website\n\n### Technologies\n\nOops... I (re)did it again.\n\nI have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself [in 2022 !](/en/articles/2022/#the-website)\n\nI will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\n\nMy \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I'm back to a solid **95/100** without any particular optimization. With some small efforts, I've reached the good old 100/100.\n\nI then did a work of modernization of the codebase. Hello CSS variables and goodbye `media queries`. In no particular order, here are some of the improvements I made:\n\n- `flexbox` and `grid` to adapt the layout to different screen sizes;\n- CSS variables for colors, font sizes and margins;\n- some `container queries`, just to try;\n- logical CSS properties (`inline` and `block` instead of `width` and `height` for example).\n\nI took this opportunity to publish [the source code](https://git.nardu.in/nardu.in/website-astro) on my git repository.\n\n**Update #1:** I've added [an RSS feed](/en/rss.xml) as I find myself using it more and more on other websites.\n\n### Analytics\n\nI removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\n\nIt's nice to see that your site is consulted, but if there is no other purpose behind it, it's an extra resource loaded for nothing by visitors. Maybe I'll reactivate the tracking when I have a use for it (other than flattering my ego).\n\nPrevious visit reports can be found at [this link.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Content\n\n- I've added a [work](/en/work/) page to list some of my projects.\n- I've also added [a page](/en/veille/) where I list some interesting things from around the web.\n\n## Additional projects\n\nI'm still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at [3-w.fr](https://3-w.fr/) (an address I am very proud of).\n\nI have to update it more regularly but I hope that the platform will help students progress!\n\n**More to come soon!**","src/content/articles/en/2023.md","489c650e66cced63",{"html":201,"metadata":202},"\u003Cp>This article will be updated when I have something new to share during the year 2023.\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oops… I (re)did it again.\u003C/p>\n\u003Cp>I have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself \u003Ca href=\"/en/articles/2022/#the-website\">in 2022 !\u003C/a>\u003C/p>\n\u003Cp>I will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\u003C/p>\n\u003Cp>My \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I’m back to a solid \u003Cstrong>95/100\u003C/strong> without any particular optimization. With some small efforts, I’ve reached the good old 100/100.\u003C/p>\n\u003Cp>I then did a work of modernization of the codebase. Hello CSS variables and goodbye \u003Ccode>media queries\u003C/code>. In no particular order, here are some of the improvements I made:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> and \u003Ccode>grid\u003C/code> to adapt the layout to different screen sizes;\u003C/li>\n\u003Cli>CSS variables for colors, font sizes and margins;\u003C/li>\n\u003Cli>some \u003Ccode>container queries\u003C/code>, just to try;\u003C/li>\n\u003Cli>logical CSS properties (\u003Ccode>inline\u003C/code> and \u003Ccode>block\u003C/code> instead of \u003Ccode>width\u003C/code> and \u003Ccode>height\u003C/code> for example).\u003C/li>\n\u003C/ul>\n\u003Cp>I took this opportunity to publish \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">the source code\u003C/a> on my git repository.\u003C/p>\n\u003Cp>\u003Cstrong>Update #1:\u003C/strong> I’ve added \u003Ca href=\"/en/rss.xml\">an RSS feed\u003C/a> as I find myself using it more and more on other websites.\u003C/p>\n\u003Ch3 id=\"analytics\">Analytics\u003C/h3>\n\u003Cp>I removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\u003C/p>\n\u003Cp>It’s nice to see that your site is consulted, but if there is no other purpose behind it, it’s an extra resource loaded for nothing by visitors. Maybe I’ll reactivate the tracking when I have a use for it (other than flattering my ego).\u003C/p>\n\u003Cp>Previous visit reports can be found at \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">this link.\u003C/a>\u003C/p>\n\u003Ch3 id=\"content\">Content\u003C/h3>\n\u003Cul>\n\u003Cli>I’ve added a \u003Ca href=\"/en/work/\">work\u003C/a> page to list some of my projects.\u003C/li>\n\u003Cli>I’ve also added \u003Ca href=\"/en/veille/\">a page\u003C/a> where I list some interesting things from around the web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"additional-projects\">Additional projects\u003C/h2>\n\u003Cp>I’m still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (an address I am very proud of).\u003C/p>\n\u003Cp>I have to update it more regularly but I hope that the platform will help students progress!\u003C/p>\n\u003Cp>\u003Cstrong>More to come soon!\u003C/strong>\u003C/p>",{"headings":203,"imagePaths":219,"frontmatter":220},[204,207,210,213,216],{"depth":26,"slug":205,"text":206},"the-website","The website",{"depth":70,"slug":208,"text":209},"technologies","Technologies",{"depth":70,"slug":211,"text":212},"analytics","Analytics",{"depth":70,"slug":214,"text":215},"content","Content",{"depth":26,"slug":217,"text":218},"additional-projects","Additional projects",[],{"title":191,"subtitle":192,"lang":180,"slug":188,"excerpt":221,"tags":222,"type":173,"createdAt":223,"updatedAt":224},"New changes.",[194],"2023-02-03T17:41:00.000Z","2023-05-17T17:41:00.000Z","en-sci-hub-unblock",{"id":225,"data":227,"body":235,"filePath":236,"digest":237,"deferredRender":184},{"title":228,"subtitle":229,"lang":180,"tags":230,"type":173,"slug":225,"createdAt":233,"updatedAt":234},"Access blocked Sci-hub","The science of sharing.",[231,232],"Internet","Science",["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nThe current sci-hub address is: \u003Ca href=\"https://www.sci-hub.st/\" rel=\"noreferer noopener\">sci-hub.st\u003C/a>\n\n## What is this about?\n\nNot being a researcher myself, here’s an [extremely well done explanatory video](https://youtu.be/rcgxY__YXEc) on the subject of scientific publication (french audio with auto subtitle).\n\n> “This is outrageous!”​\n\nI noticed that my ISP was indeed blocking access. I have not yet been able to check for the other suppliers, but I imagine that they have all complied with the court decision.\nThe restriction in place is quite basic. This is a “DNS” block. A DNS is a server that is used to link a domain name: **www.sci-hub.tw** to an IP address: **186.2.163.90**\nIt is, in a way, the Internet phone book. Without the address, it is impossible to contact the domain. What ISPs have certainly done: block requests to the [sci-hub.se.](http://sci-hub.se/) domain name. As a result, no IP address is returned and the site is not accessible.\n\n## How to bypass this?\n\n- Either by using a VPN\n- Either by modifying the DNS servers of your computers/Internet box\n\nI would recommend the second solution because it allows you to protect yourself against future blockages/filtering/censorship from your ISP and does not require any financial compensation.\nI will focus on change from a computer because it will be effective wherever you are and not only from your home.\n\n### MacOs\n\nGo to:\n\n1. System Preferences\n1. Network\n1. (wi-fi and/or ethernet)\n1. Advanced\n1. DNS\n\nFrom there, you can add DNS servers by clicking the + icon. Click ok and apply the new settings. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS network and DNS settings'\n/>\n\n### Windows (10)\n\nGo to:\n\n1. System Settings\n1. Network & Internet\n1. Change adapter options\n1. Right click your adapter then “properties”\n1. Select “internet protocol version 4” (and/or 6)\n1. Properties\n1. Use the following DNS server addresses\n\nFrom there, you can add DNS servers. Click save. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Windows system settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows network settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows network connections settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows network adapter settings'\n/>\n\n## Which DNS?\n\nThere are many DNS servers available. The best known are Google, Cloudflare and OpenDNS. If you really want to use Google’s, I’ll let you look up their address. Here are my recommendations in order of preference.\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMy favorite since it is a [french association](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net)\n\nQuand9 is a non-profit foundation offering free public DNS servers. Their classic servers offer filtering of identified malicious domains. They do not collect data and are \u003Cabbr title=\"General Data Protection Regulation\">GDPR\u003C/abbr>-compliant.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## That's it.\n\nBy changing these settings, you are free from your ISPs and their content filtering rules.\n\nFor the moment, these restrictions are almost symbolic because if Sci-hub were to change its url, the block would no longer work. But the publishers’ victory in court shows that they have not had their last word. We are therefore not immune to a wider and stronger block in the future.\n\nIf you want to learn more about the struggle of the people who fight to ensure that research is not a paid commodity, I recommend [this documentary](https://youtu.be/y_CQATGOX2w) on Aaron Shwartz. Or [this article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) about the founder of Sci-hub.\n\nIn the meantime, good readings to all of you. We stand with you!","src/content/articles/en/sci-hub-blocage.mdx","af48e8c0c3b463bf","en-2022",{"id":238,"data":240,"body":245,"filePath":246,"digest":247,"rendered":248},{"title":241,"subtitle":242,"lang":180,"tags":243,"type":173,"slug":238,"createdAt":244},"Nico v2.0","2022 update of many things.",[194],["Date","2022-06-08T14:24:06.000Z"],"After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\n\n## Services\n\n### No more print\n\nEven though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for \"classic\" graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\n\n### Internet all the way\n\nOn the other hand, I spend my time **doing web stuff.** A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer **more specific web offerings,** in which I have specialised.\n\nThus, **accessibility** and **eco-design** become integrated expertises in my practice. They are no longer options on a quote but **my core business.**\n\n## The website\n\nI have reworked my website, especially the homepage and its content, to better reflect these decisions.\n\nI have also made several behavioural changes:\n\n- external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven't found a good reason to continue using this behaviour;\n- I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu);\n- \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\n- I only trigger animations if the user has not asked the system to reduce the amount motion [(reference)](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).\n\nI am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello [astro](https://astro.build/) 👀).\n\n## Le Nico\n\nOn a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\n\nI have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.","src/content/articles/en/2022.md","7b98592763cb0929",{"html":249,"metadata":250},"\u003Cp>After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\u003C/p>\n\u003Ch2 id=\"services\">Services\u003C/h2>\n\u003Ch3 id=\"no-more-print\">No more print\u003C/h3>\n\u003Cp>Even though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for “classic” graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\u003C/p>\n\u003Ch3 id=\"internet-all-the-way\">Internet all the way\u003C/h3>\n\u003Cp>On the other hand, I spend my time \u003Cstrong>doing web stuff.\u003C/strong> A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer \u003Cstrong>more specific web offerings,\u003C/strong> in which I have specialised.\u003C/p>\n\u003Cp>Thus, \u003Cstrong>accessibility\u003C/strong> and \u003Cstrong>eco-design\u003C/strong> become integrated expertises in my practice. They are no longer options on a quote but \u003Cstrong>my core business.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Cp>I have reworked my website, especially the homepage and its content, to better reflect these decisions.\u003C/p>\n\u003Cp>I have also made several behavioural changes:\u003C/p>\n\u003Cul>\n\u003Cli>external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven’t found a good reason to continue using this behaviour;\u003C/li>\n\u003Cli>I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a>;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\u003C/li>\n\u003Cli>I only trigger animations if the user has not asked the system to reduce the amount motion \u003Ca href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion\">(reference)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>I am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello \u003Ca href=\"https://astro.build/\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>On a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\u003C/p>\n\u003Cp>I have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.\u003C/p>",{"headings":251,"imagePaths":265,"frontmatter":266},[252,255,258,261,262],{"depth":26,"slug":253,"text":254},"services","Services",{"depth":70,"slug":256,"text":257},"no-more-print","No more print",{"depth":70,"slug":259,"text":260},"internet-all-the-way","Internet all the way",{"depth":26,"slug":205,"text":206},{"depth":26,"slug":263,"text":264},"le-nico","Le Nico",[],{"title":241,"subtitle":242,"lang":180,"slug":238,"excerpt":267,"tags":268,"type":173,"createdAt":269},"Changes in my services, the website and myself.",[194],"2022-06-08T14:24:06.000Z","en-gratuiste",{"id":270,"data":272,"body":277,"filePath":278,"digest":279,"rendered":280},{"title":273,"subtitle":274,"lang":180,"tags":275,"type":173,"slug":270,"createdAt":276,"draft":184},"Gratuiste","Translation in progress, stay tuned ;)",[182,194],["Date","2017-05-27T07:47:36.000Z"],"[Go back to available articles](/en/articles)","src/content/articles/en/gratuiste.md","ebec75d19f0ff741",{"html":281,"metadata":282},"\u003Cp>\u003Ca href=\"/en/articles\">Go back to available articles\u003C/a>\u003C/p>",{"headings":283,"imagePaths":284,"frontmatter":285},[],[],{"title":273,"subtitle":274,"lang":180,"slug":270,"draft":184,"excerpt":274,"tags":286,"type":173,"createdAt":287},[182,194],"2017-05-27T07:47:36.000Z","2022",{"id":288,"data":290,"body":294,"filePath":295,"digest":296,"rendered":297},{"title":241,"subtitle":291,"lang":15,"tags":292,"type":173,"slug":288,"createdAt":293},"Mise à jour 2022 de plein de trucs.",[194],["Date","2022-06-08T14:24:06.000Z"],"Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\n\n## Les services\n\n### J’arrête le print\n\nMême si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\n\n### J’internet à fond\n\nÀ l’inverse, je passe mon temps à **faire du web.** Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer **des offres web plus précises,** dans lesquelles je me suis spécialisé.\n\nAinsi, **l’accessibilité numérique** et **l’éco-conception** deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien **mon cœur de métier.**\n\n## Le site\n\nJ’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\n\nJ’ai également fait plusieurs changements de comportements :\n\n- les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\n- j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec [cette analyse](https://twitter.com/HTeuMeuLeu/status/1370310316496728065) de [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu) ;\n- [idem pour la favicon](https://twitter.com/HTeuMeuLeu/status/1370310312214339586) ;\n- je ne déclenche les animations que si l'utilisateur n'a pas demandé au système de minimiser la quantité d'animation ou de mouvement [(référence de l'option)](https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion).\n\nJe suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> 👀).\n\n## Le Nico\n\nD’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif [Good-it!](https://www.good-it.org/) et en participant activement à son développement.\n\nJ’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.","src/content/articles/fr/2022.md","2589166172138721",{"html":298,"metadata":299},"\u003Cp>Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\u003C/p>\n\u003Ch2 id=\"les-services\">Les services\u003C/h2>\n\u003Ch3 id=\"jarrête-le-print\">J’arrête le print\u003C/h3>\n\u003Cp>Même si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\u003C/p>\n\u003Ch3 id=\"jinternet-à-fond\">J’internet à fond\u003C/h3>\n\u003Cp>À l’inverse, je passe mon temps à \u003Cstrong>faire du web.\u003C/strong> Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer \u003Cstrong>des offres web plus précises,\u003C/strong> dans lesquelles je me suis spécialisé.\u003C/p>\n\u003Cp>Ainsi, \u003Cstrong>l’accessibilité numérique\u003C/strong> et \u003Cstrong>l’éco-conception\u003C/strong> deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien \u003Cstrong>mon cœur de métier.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Cp>J’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\u003C/p>\n\u003Cp>J’ai également fait plusieurs changements de comportements :\u003C/p>\n\u003Cul>\n\u003Cli>les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\u003C/li>\n\u003Cli>j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\">cette analyse\u003C/a> de \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a> ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\">idem pour la favicon\u003C/a> ;\u003C/li>\n\u003Cli>je ne déclenche les animations que si l’utilisateur n’a pas demandé au système de minimiser la quantité d’animation ou de mouvement \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion\">(référence de l’option)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>Je suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>D’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif \u003Ca href=\"https://www.good-it.org/\">Good-it!\u003C/a> et en participant activement à son développement.\u003C/p>\n\u003Cp>J’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.\u003C/p>",{"headings":300,"imagePaths":314,"frontmatter":315},[301,304,307,310,313],{"depth":26,"slug":302,"text":303},"les-services","Les services",{"depth":70,"slug":305,"text":306},"jarrête-le-print","J’arrête le print",{"depth":70,"slug":308,"text":309},"jinternet-à-fond","J’internet à fond",{"depth":26,"slug":311,"text":312},"le-site","Le site",{"depth":26,"slug":263,"text":264},[],{"title":241,"subtitle":291,"lang":15,"slug":288,"excerpt":316,"tags":317,"type":173,"createdAt":269},"Évolution des services, du site et de moi-même.",[194],"2023",{"id":318,"data":320,"body":325,"filePath":326,"digest":327,"rendered":328},{"title":191,"subtitle":321,"lang":15,"tags":322,"type":173,"slug":318,"createdAt":323,"updatedAt":324},"Mise à jour 2023.",[194],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"Cet article sera mis à jour lorsque j'aurai des nouveautés à partager au cours de l'année 2023.\n\n## Le site\n\n### Technologies\n\nOups… je l'ai encore (re)fait.\n\nJ'ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même [en 2022 !](/articles/2022/#le-site)\n\nJe ferai certainement un ou deux articles/fragments sur Astro et les extensions que j'ai utilisées. En tout cas c'était super comme expérience. Nuxt v2 n'étant plus vraiment à jour, les performances n'étaient plus au rendez-vous. Astro a complètement corrigé ça.\n\nMon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide **95/100** sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\n\nJ'ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les `media queries`. En vrac, voici certaines améliorations que j'ai mises en place :\n\n- `flexbox` et `grid` pour adapter la mise en page aux différentes tailles d'écran ;\n- variables CSS pour les couleurs, les tailles de polices et les marges ;\n- quelques \u003Cspan lang=\"en\">`container queries`\u003C/span> pour essayer ;\n- propriétés logiques CSS (\u003Cspan lang=\"en\">`inline`\u003C/span> et \u003Cspan lang=\"en\">`block`\u003C/span> à la place de \u003Cspan lang=\"en\">`width`\u003C/span> et \u003Cspan lang=\"en\">`height`\u003C/span> par exemple).\n\nJ'en ai profité pour publier [le code source](https://git.nardu.in/nardu.in/website-astro) sur mon dépôt git.\n\n**Mise à jour #1 :** J'ai ajouté [un flux RSS](/rss.xml) car j'utilise de plus en plus le RSS sur d'autres sites web.\n\n### Suivi des visites\n\nJ’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n'était collectée et je consultais rarement les rapports.\n\nC'est sympa de voir que son site est visité, mais s'il n'y a aucun autre but derrière, c'est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j'en aurai l'utilité (autre que flatter mon égo).\n\nLes rapports de visites précédents sont consultables sur [ce lien.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Contenu\n\n- J'ai ajouté une page [références](/references/) pour lister certains de mes projets.\n- J'ai également ajouté [une page](/veille/) où je répertorie des choses intéressantes trouvées sur le web.\n\n## Projets annexes\n\nJe continue d'enseigner le développement web cette année. Afin d'étoffer mes supports de cours, j'ai mis en place un mini site de documentation disponible à l'adresse [3-w.fr](https://3-w.fr/) (adresse dont je suis très fier).\n\nIl faut que j'arrive à être plus régulier dans sa mise à jour mais j'ai bon espoir que la plateforme aide les élèves à progresser !\n\n**Plus de trucs bientôt!**","src/content/articles/fr/2023.md","d97f4a5af975333f",{"html":329,"metadata":330},"\u003Cp>Cet article sera mis à jour lorsque j’aurai des nouveautés à partager au cours de l’année 2023.\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oups… je l’ai encore (re)fait.\u003C/p>\n\u003Cp>J’ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même \u003Ca href=\"/articles/2022/#le-site\">en 2022 !\u003C/a>\u003C/p>\n\u003Cp>Je ferai certainement un ou deux articles/fragments sur Astro et les extensions que j’ai utilisées. En tout cas c’était super comme expérience. Nuxt v2 n’étant plus vraiment à jour, les performances n’étaient plus au rendez-vous. Astro a complètement corrigé ça.\u003C/p>\n\u003Cp>Mon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide \u003Cstrong>95/100\u003C/strong> sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\u003C/p>\n\u003Cp>J’ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les \u003Ccode>media queries\u003C/code>. En vrac, voici certaines améliorations que j’ai mises en place :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> et \u003Ccode>grid\u003C/code> pour adapter la mise en page aux différentes tailles d’écran ;\u003C/li>\n\u003Cli>variables CSS pour les couleurs, les tailles de polices et les marges ;\u003C/li>\n\u003Cli>quelques \u003Cspan lang=\"en\">\u003Ccode>container queries\u003C/code>\u003C/span> pour essayer ;\u003C/li>\n\u003Cli>propriétés logiques CSS (\u003Cspan lang=\"en\">\u003Ccode>inline\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>block\u003C/code>\u003C/span> à la place de \u003Cspan lang=\"en\">\u003Ccode>width\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>height\u003C/code>\u003C/span> par exemple).\u003C/li>\n\u003C/ul>\n\u003Cp>J’en ai profité pour publier \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">le code source\u003C/a> sur mon dépôt git.\u003C/p>\n\u003Cp>\u003Cstrong>Mise à jour #1 :\u003C/strong> J’ai ajouté \u003Ca href=\"/rss.xml\">un flux RSS\u003C/a> car j’utilise de plus en plus le RSS sur d’autres sites web.\u003C/p>\n\u003Ch3 id=\"suivi-des-visites\">Suivi des visites\u003C/h3>\n\u003Cp>J’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n’était collectée et je consultais rarement les rapports.\u003C/p>\n\u003Cp>C’est sympa de voir que son site est visité, mais s’il n’y a aucun autre but derrière, c’est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j’en aurai l’utilité (autre que flatter mon égo).\u003C/p>\n\u003Cp>Les rapports de visites précédents sont consultables sur \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">ce lien.\u003C/a>\u003C/p>\n\u003Ch3 id=\"contenu\">Contenu\u003C/h3>\n\u003Cul>\n\u003Cli>J’ai ajouté une page \u003Ca href=\"/references/\">références\u003C/a> pour lister certains de mes projets.\u003C/li>\n\u003Cli>J’ai également ajouté \u003Ca href=\"/veille/\">une page\u003C/a> où je répertorie des choses intéressantes trouvées sur le web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"projets-annexes\">Projets annexes\u003C/h2>\n\u003Cp>Je continue d’enseigner le développement web cette année. Afin d’étoffer mes supports de cours, j’ai mis en place un mini site de documentation disponible à l’adresse \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (adresse dont je suis très fier).\u003C/p>\n\u003Cp>Il faut que j’arrive à être plus régulier dans sa mise à jour mais j’ai bon espoir que la plateforme aide les élèves à progresser !\u003C/p>\n\u003Cp>\u003Cstrong>Plus de trucs bientôt!\u003C/strong>\u003C/p>",{"headings":331,"imagePaths":343,"frontmatter":344},[332,333,334,337,340],{"depth":26,"slug":311,"text":312},{"depth":70,"slug":208,"text":209},{"depth":70,"slug":335,"text":336},"suivi-des-visites","Suivi des visites",{"depth":70,"slug":338,"text":339},"contenu","Contenu",{"depth":26,"slug":341,"text":342},"projets-annexes","Projets annexes",[],{"title":191,"subtitle":321,"lang":15,"slug":318,"excerpt":345,"tags":346,"type":173,"createdAt":223,"updatedAt":224},"Suite des évolutions.",[194],"en-faq",{"id":347,"data":349,"body":277,"filePath":353,"digest":354,"rendered":355},{"title":350,"subtitle":274,"lang":180,"tags":351,"type":173,"slug":347,"createdAt":352,"draft":184},"Accessibility and sobriety",[194],["Date","2022-06-22T15:34:45.000Z"],"src/content/articles/en/faq.md","82d516449896f6ca",{"html":281,"metadata":356},{"headings":357,"imagePaths":358,"frontmatter":359},[],[],{"title":350,"subtitle":274,"lang":180,"slug":347,"draft":184,"excerpt":360,"tags":361,"type":173,"createdAt":362},"Why, how et and especially what.",[194],"2022-06-22T15:34:45.000Z","en-the-day-I-jamd",{"id":363,"data":365,"body":373,"filePath":374,"digest":375,"deferredRender":184},{"title":366,"subtitle":367,"lang":180,"tags":368,"type":173,"slug":363,"createdAt":371,"updatedAt":372},"The day I Jam’d","A story of unusual tools and fun gambles.",[369,370],"Dev","Jamstack",["Date","2020-10-08T09:00:00.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## The not so easy choice\n\nWhen I was still using Wordpress for my personal website, I thought it would be nice to try [OpenLiteSpeed](https://openlitespeed.org) webserver. Being a designer, I always like to have a graphical interface and I heard OLS had very nice caching and overall performances.\n\n## FIGHT!\n\nA few years later, I learned about Jamstack and its incredible potential. Not being impulsive at all, I chose to entirely remake my website with tools like [11ty](https://www.11ty.dev/) and [Strapi](https://strapi.io/).\n\nI remember Strapi still being in alpha/beta and colleagues telling me it was a risky gamble, especially since I was pretty new to the node.js world.\n\n> Open source and french? Sign me up!\n\nSo I started recreating my website identically with 11ty and Strapi. Same hosting on a Digital Ocean droplet, same webserver, same content. I had done a fair amout of performance optimizations on my wordpress install so I was eager to compare the results with the new static version.\n\nBoy did they exceed my expectations! With almost no optimization on the static side, I got the following results.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 53/100 on Wordpress.'\n/>\n\nDespite a lot of efforts I could not do better. I’m no expert in caching, do not use CDN and relied on plugins to achieve a lot of stuff (php not being my strongest skill 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 97/100 on jamstack.'\n/>\n\nAlmost **zero** special configuration (I was too anxious to test) and I reached an awesome score. I know lighthouse scores are not everything but hey, **53 vs 97**… I’ll take it!\n\n## Now kiss 🥰\n\nBoth of these approaches have their benefits and drawbacks. As a freelance, my clients often prefer or ask for Wordpress because of its reputation. I always present a Jamstack alternative when possible but it’s still scary to most compared to Wordpress. I feel however that it’s going to be easier to use Jamstack with time.\n\n## I did it again…\n\nHere we are now, a quarantine and a few months later and this website is running with… [Nuxt.js](https://nuxtjs.org/). I know, I’m sorry, I couldn’t resist the latest [nuxt content](https://content.nuxtjs.org/) functionnality.\n\nSo I re-did everything again… and let me just say: **wow**, what an experience!\nI **love** developing with Nuxt. Using nuxt content allowed me to focus on design and, well, content.\nNo more Apollo client and graphQL query, only markdown and a few promises.\n\nDon’t get me wrong, I really like working with Strapi and its graphQL capabilities but for the purpose of this website, nuxt content does it (extremely well).\n\nI’m still using Strapi as a way to upload, store and manage images, videos, gifs, etc. It might be too much for this use case but I like to know that I can still go back to it if I want to! Also, I spent quite a bit of time setting it up with OpenLiteSpeed and I’m still too attached to this accomplishment to let it go.\n\n## In the end\n\nWordpress, Jamstack, vanilla everything… Does it really matter? For me, the dev experience was far more enjoyable working with 11ty, nuxt.js and strapi than with Wordpress.\n\nOn the performance and accessibility side, it also seems to be the better/smarter choice. It might not be everytime! ¯\\\\\\_(ツ)\\_/¯\n\nCan’t wait to learn [astro](https://astro.build/) and start from scratch again!","src/content/articles/en/the-day-I-jamd.mdx","60b77e216e02f618","en-video-compression",{"id":376,"data":378,"body":384,"filePath":385,"digest":386,"deferredRender":184},{"title":379,"subtitle":380,"lang":180,"tags":381,"type":173,"slug":376,"createdAt":382,"updatedAt":383},"Video compression","Encode like you mean it.",[182],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Let's play.\n\nVideos are everywhere. **EVERYWHERE!** But videos can and will be huge when 4k becomes an internet standard. Currently, 1920x1080 is king and we usually have no problem hosting or playing this resolution.\n\n## Because we can doesn't mean we should.\n\nRight now, the (good) trend of web performance is on the rise. Everyone wants a blazing fast loading website, which might not be possible if we send requests to 100mb (or even more) videos.\n\nWith a good connection, users will not see the difference. But if we go down that path, nor will they with a 300mb one. So the goal is to make every asset as small as possible. It's already the case with images. But it's simpler and faster than video encoding.\n\n## Small size, best quality.\n\nLet's say we exported​ a 1920x1080 video from Premiere Pro with these basic settings:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-premiere-1.jpeg'\n\twidth='673'\n\theight='800'\n/>\n\nIt's gorgeous, it's Full HD, it's 1:30 minute of excellent editing but it's 50mb… What a shame.\n\n> We can already bring down the size from Premiere or Media Encoder by selecting CBR instead of VBR and using a low bitrate (like 2 or 3).\n\nLet's now use [Handbrake!](https://handbrake.fr/) It's free, open source and multi platform. You can also read this great article from [Ueno](https://loremipsum.ueno.co/dear-ueno-how-do-you-compress-videos-6657ebd9dd28?gi=930afecec398) on video encoding.\n\n**Please please PLEASE. Never export videos from within After Effects.**\n\n## Handbrake\n\n### Summary screen\n\nWhile it's not as nice as Premiere Pro, it has way more exporting capabilities. Follow these steps to use good standard settings:\n\n1. Open your source video\n1. Select a preset corresponding to your future usage like Fast 1080p30\n1. Check Web Optimized\n1. Keep MPEG-4 as the format\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-1.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Video screen\n\n1. Keep H.264 (x264) or use H.264 nvidia nvenc if you can (crazy fast encoding by nvidia)\n1. Choose Constant Quality and try a value between 20 and 30​ (higher = smaller size but lower quality)\n1. Choose Peak Framerate. If you don't know the framerate, keep the default setting\n1. Choose the type of video you are encoding (film, animation…)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-2.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Audio screen\n\nIf you don't have audio, be sure to set the audio channel to none.\nIf you have an audio channel, these settings are great and will not influence the size much​:\n\n1. Codec AAC\n1. Samplerate 44.1\n1. Bitrate 192 to 256 (your choice)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-3.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Export!\n\nI used a RF of 25 for this example and no audio.\n\n1. My Premiere Pro video was 50,6mb\n1. My Handbrake video is 5,5mb​\n\n> What a save!\n\n​I ended up dividing the original size by 10. Which is cool.\nI tried with a RF of 30. The video was still pretty good and only 3,3mb.\n\n## Exporting for the web\n\nNow that we know how to properly compress videos, let's go further. Say we have a website with a lot of videos on the same page. We still want to load the content as fast as possible. So our videos need to be as small as possible. We won't do better than previously seen using mp4/H.264. However, we can use **webm/VP9.**\nWebm is an html video format and VP9 is its latest codec.\n\nUsing Handbrake and webm/VP9, we can achieve really great compression without losing too much quality (or none at all depending on the settings). I was able to divide by 4 the size of a video using these presets:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-4.jpg'\n\twidth='728'\n\theight='313'\n\talt=''\n/>\n\nThe only down side is that it takes some time to encode. It will depend on the video length and your computing power.\n\nI tried various settings but I read [here](https://trac.ffmpeg.org/wiki/Encode/VP9) that VP9 is supposed to be used with two-pass encoding. You then have to find the right bitrate (here 1000) for your situation.","src/content/articles/en/video-compression.mdx","5bb9f69df6c651d1","sci-hub-blocage",{"id":387,"data":389,"body":395,"filePath":396,"digest":397,"deferredRender":184},{"title":390,"subtitle":391,"lang":15,"tags":392,"type":173,"slug":387,"createdAt":393,"updatedAt":394},"Sci-hub bloqué, comment contourner","La science du partage.",[231,232],["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nL'adresse actuelle de sci-hub est : \u003Ca href=\"https://www.sci-hub.st/\" rel=\"noreferer noopener\">sci-hub.st\u003C/a>\n\n## Résumé de la situation\n\nN’étant pas moi-même directement chercheur, je vous laisse regarder [cette vidéo](https://youtu.be/rcgxY__YXEc) explicative extrêmement bien faite sur le sujet de la publication scientifique.\n\n> “ Mais c’est scandaleux ! ”​\n\nJ’ai constaté que le blocage était actif chez SFR. Je n’ai pas encore pu vérifier pour les autres fournisseurs mais j’imagine qu’ils se sont tous conformés à la décision de justice.\nLe blocage mis en place est assez basique. Il s’agit d’un blocage “ DNS ”.\n\nUn DNS est un serveur qui sert à faire le lien entre un nom de domaine : **sci-hub.tw** et une adresse IP : **186.2.163.90**.\n\nC’est en quelque sorte l’annuaire d’internet. Sans l’adresse, impossible de contacter le domaine. Ce que les FAI ont certainement fait : bloquer les requêtes au nom de domaine [sci-hub.se.](http://sci-hub.se/) Ainsi, aucune adresse IP n’est renvoyée et le site n’est pas accessible.\n\n## Comment contourner ce blocage ?\n\n- Soit en utilisant un VPN\n- Soit en modifiant les serveurs DNS de vos ordinateurs/box internet\n\nJe recommande la deuxième solution car elle permet de se prémunir contre de futurs blocages/filtrages/censures de la part de votre FAI et ne nécessite pas de contrepartie financière.\nJe vais me focaliser sur le changement depuis un ordinateur car il sera effectif où que vous soyez.\n\n### Sur MacOs\n\nOuvrez :\n\n1. Préférences système\n1. Réseau\n1. Ethernet et/ou Wi-fi\n1. Avancé\n1. DNS\n1. Serveurs DNS\n\nDe là, vous pouvez ajouter des serveurs DNS en cliquant sur l'icône +. Cliquez sur ok et appliquez les nouveaux paramètres. Vous devrez peut-être redémarrer votre ordinateur pour que les changements fonctionnent.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS réglages réseau et DNS'\n/>\n\n### Sur Windows (ici 10)\n\nOuvrez :\n\n1. Réglages\n1. Réseau et internet\n1. Modifier les options de l'adaptateur\n1. Clic droit sur les propriétés de votre interface réseau\n1. Selectionnez « protocole Internet version 4 » (et/ou 6)\n1. Propriétés\n1. Utiliser l’adresse de serveur DNS suivante\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Réglages windows'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows réglages réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows régalges connections réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows options adaptateur réseau'\n/>\n\n## Quels serveurs DNS utiliser ?\n\nIl y a de nombreux serveurs DNS accessibles. Les plus connus étant ceux de Google, Cloudflare et OpenDNS. Si vous tenez vraiment à utiliser ceux de Google, je vous laisse chercher leur adresse. Voici mes recommandations par ordre de préférence.\n\nPlusieurs fournisseurs :\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMes favoris puisqu’il s’agit d’une [association française.](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net/fr)\n\nQuand9 est une fondation à but non lucratif proposant des serveurs DNS publics et gratuits. Leurs serveur classiques offrent un filtrage de domaines malveillants identifiés. Ils ne collectent pas de données et sont conforment au \u003Cabbr title=\"Règlement général sur la protection des données\">RGPD\u003C/abbr>.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## C'est tout.\n\nEn modifiant ces réglages, vous vous affranchissez de vos fournisseurs d’accès et de leurs règles de filtrage du contenu.\n\nPour l’instant, ces blocages sont presque symboliques car si Sci-hub venait à changer d’url, le blocage ne fonctionnerait plus. Mais la victoire des éditeurs au tribunal montre qu’ils n’ont pas dit leur dernier mot. Nous ne sommes donc pas à l’abri d’un futur blocage plus large et plus dur à contrer.\n\nSi vous voulez en apprendre plus sur le combat de ces gens qui se battent pour que la recherche ne soit pas une marchandise, je vous conseille [ce documentaire](https://youtu.be/y_CQATGOX2w) sur Aaron Shwartz. Ou plus simplement [cet article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) sur la fondatrice de Sci-hub.\n\nEn attendant, bonnes lectures à tou·te·s. On est avec vous !","src/content/articles/fr/sci-hub-blocage.mdx","3a003b105dcd5e24","after-effects-expressions",{"id":398,"data":400,"body":404,"filePath":405,"digest":406,"rendered":407},{"title":178,"subtitle":401,"lang":15,"tags":402,"type":173,"slug":398,"createdAt":403,"draft":184},"En cours de traduction, revenez bientôt ;)",[182],["Date","2019-04-24T09:00:00.000Z"],"[Retour aux articles](/articles)","src/content/articles/fr/after-effects-expressions.md","884d725859a7bab5",{"html":408,"metadata":409},"\u003Cp>\u003Ca href=\"/articles\">Retour aux articles\u003C/a>\u003C/p>",{"headings":410,"imagePaths":411,"frontmatter":412},[],[],{"title":178,"subtitle":401,"lang":15,"draft":184,"slug":398,"excerpt":401,"tags":413,"type":173,"createdAt":414},[182],"2019-04-24T09:00:00.000Z","video-compression",{"id":415,"data":417,"body":404,"filePath":422,"digest":423,"rendered":424},{"title":418,"subtitle":401,"lang":15,"tags":419,"type":173,"slug":415,"createdAt":420,"updatedAt":421,"draft":184},"Compression vidéo",[182],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"src/content/articles/fr/video-compression.md","2296c41874b23b3d",{"html":408,"metadata":425},{"headings":426,"imagePaths":427,"frontmatter":428},[],[],{"title":418,"subtitle":401,"lang":15,"draft":184,"slug":415,"excerpt":429,"tags":430,"type":173,"createdAt":431,"updatedAt":269},"Pas encore traduit",[182],"2021-05-05T09:00:00.000Z","faq",{"id":432,"data":434,"body":439,"filePath":440,"digest":441,"rendered":442},{"title":435,"subtitle":436,"lang":15,"tags":437,"type":173,"slug":432,"createdAt":438},"Accessibilité, sobriété et F.A.Q.","Explications sur ma vision et mon fonctionnement.",[194],["Date","2022-06-22T15:34:45.000Z"],"## l'Accessibilité\n\n### Quèsaco ?\n\nD'après [access42 :](https://access42.net)\n\n> L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\n\nAinsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que **n'importe quel visiteur** puisse l'utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais **ce n'est pas le cas !**\n\nLorsqu'un site est pensé et conçu avec l'accessibilité en tête, il ne prend **pas plus de temps** qu'un projet qui ne le fait pas. En revanche, **corriger** un site existant qui n'a pas bénéficié de cette réflexion en amont **demande beaucoup plus d'efforts.**\n\n### Pourquoi c'est important ?\n\nAprès avoir été sensibilisé à l'accessibilité et aux [situations frustrantes voire bloquantes](https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles) que rencontrent les personnes handicapées sur le web, j'ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m'a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\n\n## l'Éco-conception\n\n### Quèsaco ?\n\nD'après le collectif [\u003Cspan lang=\"en\">green it\u003C/span> :](https://www.greenit.fr)\n\n> L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\n\nIl s'agit ici pour moi de créer des produits les plus sobres possibles. C'est-à-dire de développer ou d'utiliser une fonctionnalité uniquement si elle est indispensable.\n\nPar exemple, mettre en place **un formulaire de contact** sur un site web implique plusieurs choses :\n\n- développer un formulaire\n- envoyer les données au serveur\n- vérifier les données envoyées\n- envoyer les données par mail\n- confirmer l'envoi du mail (en fournissant une copie)\n- gérer les erreurs à chaque étape\n\nUn site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d'effectuer ces opérations (ou un prestataire qui s'en charge). C'est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu'un formulaire. Dans le cas d'un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\n\n### Pourquoi c'est important ?\n\nL'éco-conception fait beaucoup de bien à la qualité globale d'un site et à l'expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\n\n## F.A.Q.\n\n### Cette démarche est-elle opportuniste ?\n\n**Non.** Il est vrai que l'accessibilité et, surtout, l'éco-conception, commencent à être « tendance ». On pourrait donc croire que j'en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c'est ma responsabilité de créer des sites web accessibles et éco-conçus **par défaut.**\n\n### Un site accessible est-il plus cher ?\n\n**Oui et non.** Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l'accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j'augmente mes tarifs suite à l'obtention de certifications relatives à mon activité.\n\n### Mon site sera-t-il 100 % accessible ?\n\n**Non,** je ne suis pas en mesure de garantir ou de certifier la conformité totale d'un site au [référentiel général d'amélioration de l'accessibilité.](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d'un site. Cependant, je peux vous accompagner avant et après l'audit afin d'anticiper puis de corriger les critères d'accessibilité requis. [Access42](https://access42.net/) et [Tanaguru](https://www.tanaguru.com/) font parties de ces entreprises spécialisées.\n\n### Pourquoi ne pas utiliser un outil automatique ?\n\nCar ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom [sous peine de procès](https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/)), ne sont pas des solutions micracles. Lisez [cet article](https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/) d'une experte en accessibilité et/ou [ce test](https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/) de différents outils pour en savoir plus.\n\n### Un site éco-conçu et accessible peut-il être beau ?\n\n**Oui, évidemment.** Je vous laisse juger par vous-même avec [cette liste](https://lowww.directory/) de sites éco-conçus. En ce qui concerne l'accessibilité, elle n'impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d'un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l'utilisation d'un produit.","src/content/articles/fr/faq.md","65e9e60bcd00806c",{"html":443,"metadata":444},"\u003Ch2 id=\"laccessibilité\">l’Accessibilité\u003C/h2>\n\u003Ch3 id=\"quèsaco\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après \u003Ca href=\"https://access42.net\">access42 :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Ainsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que \u003Cstrong>n’importe quel visiteur\u003C/strong> puisse l’utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais \u003Cstrong>ce n’est pas le cas !\u003C/strong>\u003C/p>\n\u003Cp>Lorsqu’un site est pensé et conçu avec l’accessibilité en tête, il ne prend \u003Cstrong>pas plus de temps\u003C/strong> qu’un projet qui ne le fait pas. En revanche, \u003Cstrong>corriger\u003C/strong> un site existant qui n’a pas bénéficié de cette réflexion en amont \u003Cstrong>demande beaucoup plus d’efforts.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>Après avoir été sensibilisé à l’accessibilité et aux \u003Ca href=\"https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles\">situations frustrantes voire bloquantes\u003C/a> que rencontrent les personnes handicapées sur le web, j’ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m’a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\u003C/p>\n\u003Ch2 id=\"léco-conception\">l’Éco-conception\u003C/h2>\n\u003Ch3 id=\"quèsaco-1\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après le collectif \u003Ca href=\"https://www.greenit.fr\">\u003Cspan lang=\"en\">green it\u003C/span> :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Il s’agit ici pour moi de créer des produits les plus sobres possibles. C’est-à-dire de développer ou d’utiliser une fonctionnalité uniquement si elle est indispensable.\u003C/p>\n\u003Cp>Par exemple, mettre en place \u003Cstrong>un formulaire de contact\u003C/strong> sur un site web implique plusieurs choses :\u003C/p>\n\u003Cul>\n\u003Cli>développer un formulaire\u003C/li>\n\u003Cli>envoyer les données au serveur\u003C/li>\n\u003Cli>vérifier les données envoyées\u003C/li>\n\u003Cli>envoyer les données par mail\u003C/li>\n\u003Cli>confirmer l’envoi du mail (en fournissant une copie)\u003C/li>\n\u003Cli>gérer les erreurs à chaque étape\u003C/li>\n\u003C/ul>\n\u003Cp>Un site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d’effectuer ces opérations (ou un prestataire qui s’en charge). C’est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu’un formulaire. Dans le cas d’un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important-1\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>L’éco-conception fait beaucoup de bien à la qualité globale d’un site et à l’expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\u003C/p>\n\u003Ch2 id=\"faq\">F.A.Q.\u003C/h2>\n\u003Ch3 id=\"cette-démarche-est-elle-opportuniste\">Cette démarche est-elle opportuniste ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non.\u003C/strong> Il est vrai que l’accessibilité et, surtout, l’éco-conception, commencent à être « tendance ». On pourrait donc croire que j’en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c’est ma responsabilité de créer des sites web accessibles et éco-conçus \u003Cstrong>par défaut.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"un-site-accessible-est-il-plus-cher\">Un site accessible est-il plus cher ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui et non.\u003C/strong> Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l’accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j’augmente mes tarifs suite à l’obtention de certifications relatives à mon activité.\u003C/p>\n\u003Ch3 id=\"mon-site-sera-t-il-100-accessible\">Mon site sera-t-il 100 % accessible ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non,\u003C/strong> je ne suis pas en mesure de garantir ou de certifier la conformité totale d’un site au \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité.\u003C/a> Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d’un site. Cependant, je peux vous accompagner avant et après l’audit afin d’anticiper puis de corriger les critères d’accessibilité requis. \u003Ca href=\"https://access42.net/\">Access42\u003C/a> et \u003Ca href=\"https://www.tanaguru.com/\">Tanaguru\u003C/a> font parties de ces entreprises spécialisées.\u003C/p>\n\u003Ch3 id=\"pourquoi-ne-pas-utiliser-un-outil-automatique\">Pourquoi ne pas utiliser un outil automatique ?\u003C/h3>\n\u003Cp>Car ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom \u003Ca href=\"https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/\">sous peine de procès\u003C/a>), ne sont pas des solutions micracles. Lisez \u003Ca href=\"https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/\">cet article\u003C/a> d’une experte en accessibilité et/ou \u003Ca href=\"https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/\">ce test\u003C/a> de différents outils pour en savoir plus.\u003C/p>\n\u003Ch3 id=\"un-site-éco-conçu-et-accessible-peut-il-être-beau\">Un site éco-conçu et accessible peut-il être beau ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui, évidemment.\u003C/strong> Je vous laisse juger par vous-même avec \u003Ca href=\"https://lowww.directory/\">cette liste\u003C/a> de sites éco-conçus. En ce qui concerne l’accessibilité, elle n’impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d’un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l’utilisation d’un produit.\u003C/p>",{"headings":445,"imagePaths":479,"frontmatter":480},[446,449,452,455,458,460,462,464,467,470,473,476],{"depth":26,"slug":447,"text":448},"laccessibilité","l’Accessibilité",{"depth":70,"slug":450,"text":451},"quèsaco","Quèsaco ?",{"depth":70,"slug":453,"text":454},"pourquoi-cest-important","Pourquoi c’est important ?",{"depth":26,"slug":456,"text":457},"léco-conception","l’Éco-conception",{"depth":70,"slug":459,"text":451},"quèsaco-1",{"depth":70,"slug":461,"text":454},"pourquoi-cest-important-1",{"depth":26,"slug":432,"text":463},"F.A.Q.",{"depth":70,"slug":465,"text":466},"cette-démarche-est-elle-opportuniste","Cette démarche est-elle opportuniste ?",{"depth":70,"slug":468,"text":469},"un-site-accessible-est-il-plus-cher","Un site accessible est-il plus cher ?",{"depth":70,"slug":471,"text":472},"mon-site-sera-t-il-100-accessible","Mon site sera-t-il 100 % accessible ?",{"depth":70,"slug":474,"text":475},"pourquoi-ne-pas-utiliser-un-outil-automatique","Pourquoi ne pas utiliser un outil automatique ?",{"depth":70,"slug":477,"text":478},"un-site-éco-conçu-et-accessible-peut-il-être-beau","Un site éco-conçu et accessible peut-il être beau ?",[],{"title":435,"subtitle":436,"lang":15,"slug":432,"excerpt":481,"tags":482,"type":173,"createdAt":362},"Pourquoi, comment et surtout quèsaco.",[194],"the-day-I-jamd",{"id":483,"data":485,"body":490,"filePath":491,"digest":492,"deferredRender":184},{"title":366,"subtitle":486,"lang":15,"tags":487,"type":173,"slug":483,"createdAt":488,"updatedAt":489},"Des paris, des outils et du fun.",[369,370],["Date","2020-10-08T07:47:36.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## La solution de non facilité\n\nLorsque j’utilisais encore Wordpress pour mon site web personnel, j’ai voulu essayer le serveur web \u003Ca href=\"https://openlitespeed.org\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">OpenLiteSpeed (en anglais)\u003C/a>. En tant que designer, j’ai toujours aimé avoir une interface graphique et j’avais entendu dire qu’OLS jouissait de bonnes performances en général et de cache en particulier.\n\n## Battez-vous!\n\nQuelques années plus tard, je découvrais l’univers Jamstack et son incroyable potentiel. N’étant pas du tout impulsif, j’ai choisi de refaire entièrement mon site web avec des outils comme \u003Ca href=\"https://www.11ty.dev/\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">11ty (en anglais)\u003C/a> et \u003Ca href=\"https://strapi.io/\" hreflang=\"en\">Strapi (en anglais)\u003C/a>.\n\nJe me souviens que Strapi était encore en alpha/beta et que certains collègues me disaient que c’était un pari risqué, surtout que je découvrais à peine le monde de node.js.\n\n> Open source et français ? Je dis banco !\n\nJ’ai donc commencé à recréer mon site web à l’identique avec 11ty et Strapi. Même hébergement chez Digital Ocean, même serveur web, même contenu. J’avais fait pas mal d’optimisations de performances sur mon installation wordpress, j’étais donc impatient de comparer les résultats avec la nouvelle version statique.\n\nJ’en suis resté pantois ! Quasiment sans optimisation du côté statique, j’ai obtenu les résultats ci-dessous.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 53/100 sur Wordpress.'\n/>\n\nMalgré beaucoup d’efforts, je n’ai pas pu faire mieux. Je ne suis pas un expert en cache, je n’utilise pas de CDN et je me suis appuyé sur des plugins pour réaliser beaucoup de choses (php n’étant pas ma spécialité 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 97/100 en Jamstack.'\n/>\n\nPresque **zéro** configuration spéciale (j’étais trop impatient de tester) et j’ai atteint un score impressionnant. Je sais que les scores lighthouse ne font pas tout mais **53 contre 97**… Ça me va !\n\n## Embrassez-vous 🥰\n\nCes deux approches ont leurs avantages et leurs inconvénients. En tant que freelance, mes clients préfèrent ou demandent souvent Wordpress en raison de sa réputation. Je présente toujours une alternative Jamstack lorsque c’est possible, mais cela reste effrayant la plupart du temps par rapport à Wordpress. Je pense cependant qu’il sera plus facile d’utiliser la Jamstack avec le temps.\n\n## Encore et encore…\n\nNous voici maintenant une quarantaine et quelques mois plus tard et ce site fonctionne avec… [Nuxt.js](https://fr.nuxtjs.org/). Je sais, je suis désolé, je n’ai pas pu résister à la dernière fonctionnalité [\u003Cspan lang=\"en\">nuxt content\u003C/span>](https://content.nuxtjs.org/fr) de Nuxt.\n\nDu coup j’ai tout refait… et laissez-moi vous dire : **wow**, quelle expérience !\nJ’adore développer avec Nuxt. L’utilisation de \u003Cspan lang=\"en\">nuxt content\u003C/span> m’a permis de me concentrer sur le design et, évidemment, sur le contenu.\nPlus de client Apollo ni de requête graphQL, seulement du \u003Cspan lang=\"en\">markdown\u003C/span> et quelques promesses.\n\nAttention, j’aime beaucoup travailler avec Strapi et son interface graphQL mais pour les besoins de ce site, \u003Cspan lang=\"en\">nuxt content\u003C/span> fait le \u003Cspan lang=\"en\">job\u003C/span> (extrêmement bien).\n\nJ’utilise toujours Strapi pour téléverser, stocker et gérer les images, vidéos, gifs, etc. C’est peut-être trop pour ce que j’en fait mais j’aime savoir que je peux toujours y revenir si j’ai envie ! De plus, j’ai passé pas mal de temps à le mettre en place avec \u003Cspan lang=\"en\">OpenLiteSpeed\u003C/span> et je suis encore trop attaché à cette réussite pour la laisser tomber.\n\n## Et en fait à la fin\n\nWordpress, Jamstack, fait main… Est-ce vraiment important ? Pour moi, l’expérience de développement a été bien plus agréable en travaillant avec 11ty, nuxt.js et strapi qu’avec Wordpress.\n\nDu point de vue de la performance et de l’accessibilité, il semble également que ce soit le choix le plus judicieux. Ce n’est peut-être pas le cas à chaque fois ! ¯\\\\\\_(ツ)\\_/¯\n\nJ’ai hâte d’apprendre \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> et de tout recommencer à zéro !","src/content/articles/fr/the-day-I-jamd.mdx","57bd292bda8b6632","gratuiste",{"id":493,"data":495,"body":501,"filePath":502,"digest":503,"rendered":504},{"title":273,"subtitle":496,"lang":15,"tags":497,"type":173,"slug":493,"createdAt":499,"updatedAt":500},"Ou le travail gratuit.",[498,194],"Graphisme",["Date","2017-05-27T07:47:36.000Z"],["Date","2022-12-27T15:36:06.000Z"],"## Gratuiste, qu’est-ce que c’est ?\n\nDans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc. \nDe plus en plus, la communauté s’élève contre ces pratiques et les [dénonce.](https://twitter.com/PayeTonAffiche)\n\n> “ On n’est pas des gratuistes ! ”\n\nComprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez [cette vidéo](https://youtu.be/essNmNOrQto) qui transpose ces pratiques à des métiers “ standards ” et [celle-ci](https://youtu.be/DsstOs-K7gk) qui explique en détails le processus actuel.\n\n## T’es débile du coup ?\n\nJ’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\n\nÉtant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre. \nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\n\n## Le concept\n\nJe compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux. \nCe type de prestation porte le nom de “ **pro bono publico** ” – “ **pour le bien public** ”.\n\nCette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\n\n> Graphiste pro bono, pourquoi pas ?\n\n## Quels genres de services ?\n\nEn toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\n\n### En résumé :\n\n- maquette de site web\n- intégration front-end (en dur ou via wordpress) du site\n- gestion de la mise en ligne du site\n- newsletter (design et/ou intégration)\n- flyers\n- autres petites demandes\n\nVous pouvez avoir un aperçu de mon travail [sur ce même site.](/) J’ai déjà eu l’occasion de travailler pour :\n\n- [Cygnal](/projets/cygnal)\n- [OpenMole](https://openmole.org/)\n- [Good-it](https://good-it.org)\n\n## Dans quelles conditions ?\n\n- l’association doit être active\n- elle doit porter des valeurs que je partage\n- elle doit pouvoir me montrer ses actions\n- elle ne doit pas avoir les moyens de se payer un graphiste\n\n## C’est un peu trop beau pour être vrai ton truc…\n\nIl faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\n\nSi vous êtes intéressés, [envoyez-moi un mail !](mailto:contac@nardu.in)\n\n## Qu’est-ce que t’y gagnes toi ?\n\nSimplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.","src/content/articles/fr/gratuiste.md","80c20493583a842c",{"html":505,"metadata":506},"\u003Ch2 id=\"gratuiste-quest-ce-que-cest\">Gratuiste, qu’est-ce que c’est ?\u003C/h2>\n\u003Cp>Dans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc.\u003Cbr>\nDe plus en plus, la communauté s’élève contre ces pratiques et les \u003Ca href=\"https://twitter.com/PayeTonAffiche\">dénonce.\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“ On n’est pas des gratuistes ! ”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Comprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez \u003Ca href=\"https://youtu.be/essNmNOrQto\">cette vidéo\u003C/a> qui transpose ces pratiques à des métiers “ standards ” et \u003Ca href=\"https://youtu.be/DsstOs-K7gk\">celle-ci\u003C/a> qui explique en détails le processus actuel.\u003C/p>\n\u003Ch2 id=\"tes-débile-du-coup\">T’es débile du coup ?\u003C/h2>\n\u003Cp>J’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\u003C/p>\n\u003Cp>Étant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre.\u003Cbr>\nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\u003C/p>\n\u003Ch2 id=\"le-concept\">Le concept\u003C/h2>\n\u003Cp>Je compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux.\u003Cbr>\nCe type de prestation porte le nom de “ \u003Cstrong>pro bono publico\u003C/strong> ” – “ \u003Cstrong>pour le bien public\u003C/strong> ”.\u003C/p>\n\u003Cp>Cette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Graphiste pro bono, pourquoi pas ?\u003C/p>\n\u003C/blockquote>\n\u003Ch2 id=\"quels-genres-de-services\">Quels genres de services ?\u003C/h2>\n\u003Cp>En toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\u003C/p>\n\u003Ch3 id=\"en-résumé\">En résumé :\u003C/h3>\n\u003Cul>\n\u003Cli>maquette de site web\u003C/li>\n\u003Cli>intégration front-end (en dur ou via wordpress) du site\u003C/li>\n\u003Cli>gestion de la mise en ligne du site\u003C/li>\n\u003Cli>newsletter (design et/ou intégration)\u003C/li>\n\u003Cli>flyers\u003C/li>\n\u003Cli>autres petites demandes\u003C/li>\n\u003C/ul>\n\u003Cp>Vous pouvez avoir un aperçu de mon travail \u003Ca href=\"/\">sur ce même site.\u003C/a> J’ai déjà eu l’occasion de travailler pour :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"/projets/cygnal\">Cygnal\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://openmole.org/\">OpenMole\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://good-it.org\">Good-it\u003C/a>\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"dans-quelles-conditions\">Dans quelles conditions ?\u003C/h2>\n\u003Cul>\n\u003Cli>l’association doit être active\u003C/li>\n\u003Cli>elle doit porter des valeurs que je partage\u003C/li>\n\u003Cli>elle doit pouvoir me montrer ses actions\u003C/li>\n\u003Cli>elle ne doit pas avoir les moyens de se payer un graphiste\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"cest-un-peu-trop-beau-pour-être-vrai-ton-truc\">C’est un peu trop beau pour être vrai ton truc…\u003C/h2>\n\u003Cp>Il faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\u003C/p>\n\u003Cp>Si vous êtes intéressés, \u003Ca href=\"mailto:contac@nardu.in\">envoyez-moi un mail !\u003C/a>\u003C/p>\n\u003Ch2 id=\"quest-ce-que-ty-gagnes-toi\">Qu’est-ce que t’y gagnes toi ?\u003C/h2>\n\u003Cp>Simplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.\u003C/p>",{"headings":507,"imagePaths":532,"frontmatter":533},[508,511,514,517,520,523,526,529],{"depth":26,"slug":509,"text":510},"gratuiste-quest-ce-que-cest","Gratuiste, qu’est-ce que c’est ?",{"depth":26,"slug":512,"text":513},"tes-débile-du-coup","T’es débile du coup ?",{"depth":26,"slug":515,"text":516},"le-concept","Le concept",{"depth":26,"slug":518,"text":519},"quels-genres-de-services","Quels genres de services ?",{"depth":70,"slug":521,"text":522},"en-résumé","En résumé :",{"depth":26,"slug":524,"text":525},"dans-quelles-conditions","Dans quelles conditions ?",{"depth":26,"slug":527,"text":528},"cest-un-peu-trop-beau-pour-être-vrai-ton-truc","C’est un peu trop beau pour être vrai ton truc…",{"depth":26,"slug":530,"text":531},"quest-ce-que-ty-gagnes-toi","Qu’est-ce que t’y gagnes toi ?",[],{"title":273,"subtitle":496,"lang":15,"slug":493,"excerpt":534,"tags":535,"type":173,"createdAt":287,"updatedAt":536},"J’ai cherché un moyen de mettre mes compétences au service d’autrui et je pense avoir trouvé: je vais travailler gratuitement pour des associations.",[498,194],"2022-12-27T15:36:06.000Z","veille",["Map",318,539],{"id":318,"data":540,"body":542,"filePath":543,"digest":544,"rendered":545},{"lang":15,"title":318,"updatedAt":541},["Date","2023-04-20T17:12:06.000Z"],"- [mmm.page](https://build.mmm.page/) - Éditeur de sites web très simples, en glisser-déposer, pour n'importe quoi.\n- [Color.io](https://www.color.io/) - Éditeur photo en ligne.\n- [Addy's toolkit](https://toolkit.addy.codes/) - Outils et ressources pour les designers et développeurs sites web.\n- [L’accessibilité n’est pas une variable d’ajustement](https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/) — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n > L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\n- [3D en CSS (english)](https://garden.bradwoods.io/notes/css/3d) – Explications et exemples des propriétés 3D en CSS.\n- [Climat : Comment ne pas déprimer ?](https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html) – Podcast.\n- [Fable (english)](https://fable.app) – Application de motion design.\n- [Rive (english)](https://rive.app) – Application de motion design.\n- [Cake Desk](https://cakedesk.app/) – Application de facturation.\n- [Ombre fluide en CSS](https://shadows.brumm.af/) – Générateur.\n- [Smol CSS](https://smolcss.dev/) – Collection de fragments CSS.\n- [Ajustement optique](https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/) (english) – Aligner visuellement plutôt que techniquement.\n- [Datawrapper](https://blog.datawrapper.de/category/datavis-dos-and-donts/) (english) – Conseils pour montrer de la donnée.\n- [Assistivlabs](https://assistivlabs.com/) (english) – Service de test des technologies d'assistance (browserstack mais pour l'accessibilité).\n- [Les caractères fantaisistes et l'accessibilité](https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/) – Explications et exemples de l'enfer que sont les caractères Unicode pour les technologies d'assistance.\n- [Créer un champ `time` sur le web](https://adamsilver.io/blog/designing-a-time-input-backed-by-research/) (english) – Article.\n- [La cascade](https://la-cascade.io) – Collection d'articles sur le CSS.\n- [Tabby](https://tabby.sh) (english) – An alternative terminal app.\n- [Newglyph](https://newglyph.com/) – Fonderie indépendante.\n- [\u003Cspan lang=\"en\">Headless UI\u003C/span>](https://headlessui.com/vue/dialog) (english) – Librairie de composants vue et react.\n- [Vie privée sexy](https://privacy.sexy) (english) – Outils de confidentialité pour windows et macos.\n- [33 concepts JavaScript](https://github.com/leonardomso/33-js-concepts) (english) – Articles.\n- [Formbricks](https://formbricks.com/) (english) – Alternative open source à google form/typeform.\n- [Animations de chargement SVG](https://github.com/n3r4zzurr0/svg-spinners) – Collection.\n- [a11yphant](https://a11yphant.com/) (english) – Challenges de code pour apprendre l'accessibilité.\n- [CSS moderne](https://moderncss.dev/) (english) – Fragments CSS.\n- [Conteneur moderne en CSS](https://twitter.com/KevinJPowell/status/1501555193799925761) (english) – Tweet de Kevin Powell ❤️","src/data/veille/2023.md","1135beec386f207f",{"html":546,"metadata":547},"\u003Cul>\n\u003Cli>\u003Ca href=\"https://build.mmm.page/\">mmm.page\u003C/a> - Éditeur de sites web très simples, en glisser-déposer, pour n’importe quoi.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.color.io/\">Color.io\u003C/a> - Éditeur photo en ligne.\u003C/li>\n\u003Cli>\u003Ca href=\"https://toolkit.addy.codes/\">Addy’s toolkit\u003C/a> - Outils et ressources pour les designers et développeurs sites web.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/\">L’accessibilité n’est pas une variable d’ajustement\u003C/a> — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n\u003Cblockquote>\n\u003Cp>L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\u003C/p>\n\u003C/blockquote>\n\u003C/li>\n\u003Cli>\u003Ca href=\"https://garden.bradwoods.io/notes/css/3d\">3D en CSS (english)\u003C/a> – Explications et exemples des propriétés 3D en CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html\">Climat : Comment ne pas déprimer ?\u003C/a> – Podcast.\u003C/li>\n\u003Cli>\u003Ca href=\"https://fable.app\">Fable (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://rive.app\">Rive (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://cakedesk.app/\">Cake Desk\u003C/a> – Application de facturation.\u003C/li>\n\u003Cli>\u003Ca href=\"https://shadows.brumm.af/\">Ombre fluide en CSS\u003C/a> – Générateur.\u003C/li>\n\u003Cli>\u003Ca href=\"https://smolcss.dev/\">Smol CSS\u003C/a> – Collection de fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/\">Ajustement optique\u003C/a> (english) – Aligner visuellement plutôt que techniquement.\u003C/li>\n\u003Cli>\u003Ca href=\"https://blog.datawrapper.de/category/datavis-dos-and-donts/\">Datawrapper\u003C/a> (english) – Conseils pour montrer de la donnée.\u003C/li>\n\u003Cli>\u003Ca href=\"https://assistivlabs.com/\">Assistivlabs\u003C/a> (english) – Service de test des technologies d’assistance (browserstack mais pour l’accessibilité).\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/\">Les caractères fantaisistes et l’accessibilité\u003C/a> – Explications et exemples de l’enfer que sont les caractères Unicode pour les technologies d’assistance.\u003C/li>\n\u003Cli>\u003Ca href=\"https://adamsilver.io/blog/designing-a-time-input-backed-by-research/\">Créer un champ \u003Ccode>time\u003C/code> sur le web\u003C/a> (english) – Article.\u003C/li>\n\u003Cli>\u003Ca href=\"https://la-cascade.io\">La cascade\u003C/a> – Collection d’articles sur le CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://tabby.sh\">Tabby\u003C/a> (english) – An alternative terminal app.\u003C/li>\n\u003Cli>\u003Ca href=\"https://newglyph.com/\">Newglyph\u003C/a> – Fonderie indépendante.\u003C/li>\n\u003Cli>\u003Ca href=\"https://headlessui.com/vue/dialog\">\u003Cspan lang=\"en\">Headless UI\u003C/span>\u003C/a> (english) – Librairie de composants vue et react.\u003C/li>\n\u003Cli>\u003Ca href=\"https://privacy.sexy\">Vie privée sexy\u003C/a> (english) – Outils de confidentialité pour windows et macos.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/leonardomso/33-js-concepts\">33 concepts JavaScript\u003C/a> (english) – Articles.\u003C/li>\n\u003Cli>\u003Ca href=\"https://formbricks.com/\">Formbricks\u003C/a> (english) – Alternative open source à google form/typeform.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/n3r4zzurr0/svg-spinners\">Animations de chargement SVG\u003C/a> – Collection.\u003C/li>\n\u003Cli>\u003Ca href=\"https://a11yphant.com/\">a11yphant\u003C/a> (english) – Challenges de code pour apprendre l’accessibilité.\u003C/li>\n\u003Cli>\u003Ca href=\"https://moderncss.dev/\">CSS moderne\u003C/a> (english) – Fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/KevinJPowell/status/1501555193799925761\">Conteneur moderne en CSS\u003C/a> (english) – Tweet de Kevin Powell ❤️\u003C/li>\n\u003C/ul>",{"headings":548,"imagePaths":549,"frontmatter":550},[],[],{"lang":15,"title":318,"updatedAt":551},"2023-04-20T17:12:06.000Z","fragments",["Map",554,555,566,567,584,585,601,602,612,613,667,668,677,678,688,689,699,700,712,713,747,748,771,772,813,814,853,854,887,888,951,952],"en-image-full",{"id":554,"data":556,"body":563,"filePath":564,"digest":565,"deferredRender":184},{"title":557,"subtitle":274,"lang":180,"tags":558,"type":560,"slug":554,"createdAt":561,"updatedAt":562,"draft":184},"Full width image",[559],"CSS","snippets",["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"[Go back to available snippets](/en/snippets)","src/content/fragments/en/image-full.mdx","2e3dddf593f6d72f","array-vs-array",{"id":566,"data":568,"body":574,"filePath":575,"digest":576,"rendered":577},{"title":569,"subtitle":570,"lang":15,"tags":571,"type":552,"slug":566,"createdAt":573,"draft":184},"Filtrer un array avec un autre array","En cours de traduction.",[572],"nuxt.js",["Date","2022-06-08T14:24:06.000Z"],"[Voir les fragments disponibles](/fragments)","src/content/fragments/fr/array-vs-array.md","7321d444177c3841",{"html":578,"metadata":579},"\u003Cp>\u003Ca href=\"/fragments\">Voir les fragments disponibles\u003C/a>\u003C/p>",{"headings":580,"imagePaths":581,"frontmatter":582},[],[],{"title":569,"subtitle":570,"lang":15,"draft":184,"slug":566,"createdAt":269,"excerpt":570,"tags":583,"type":552},[572],"en-visited-links",{"id":584,"data":586,"body":563,"filePath":590,"digest":591,"rendered":592},{"title":587,"subtitle":274,"lang":180,"tags":588,"type":560,"slug":584,"createdAt":589,"draft":184},"Visited links and visuel aid",[132],["Date","2023-06-06T18:34:00.000Z"],"src/content/fragments/en/visited-links.md","cb7c11c12c25067e",{"html":593,"metadata":594},"\u003Cp>\u003Ca href=\"/en/snippets\">Go back to available snippets\u003C/a>\u003C/p>",{"headings":595,"imagePaths":596,"frontmatter":597},[],[],{"title":587,"subtitle":274,"lang":180,"draft":184,"slug":584,"excerpt":598,"tags":599,"type":560,"createdAt":600},"Petit hack CSS",[132],"2023-06-06T18:34:00.000Z","en-super-cookies",{"id":601,"data":603,"body":609,"filePath":610,"digest":611,"deferredRender":184},{"title":604,"subtitle":605,"lang":180,"tags":606,"type":560,"slug":601,"createdAt":608},"The best cookies","Consentless biscuits.",[607],"food",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 tablespoon of baking powder\n- 3/4 of aquafaba from 400g of chickpea (chickpea water)\n- 125 grams of coconut oil\n- 2 teaspoons of maple syrup\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- if necessary, melt the coconut oil over low heat\n- meanwhile, mix all the dry ingredients\n- add all liquid ingredients (oil, aquafaba, maple syrup)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Non vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 table spoon of baking powder\n- 1 egg\n- 125 grams of melted butter\n- 2 teaspoons of honey\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- melt butter over low heat\n- meanwhile, mix all dry ingredients\n- add all liquid ingredients (melted butter, egg, honey)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Notes\n\nChocolate can be replaced by anything like nuts, raisins, legos... (don't eat legos be reasonable).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='All ingredients mixed together to form a brown paste.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='The cookies are round and soft after baking.'\n/>","src/content/fragments/en/super-cookies.mdx","b0c67adad40c177c","en-toulouse-fun",{"id":612,"data":614,"body":620,"filePath":621,"digest":622,"rendered":623},{"title":615,"subtitle":616,"lang":180,"tags":617,"type":560,"slug":612,"createdAt":619},"Toulouse yourself","Only the bestest",[618],"lifestyle",["Date","2022-06-22T15:34:45.000Z"],"Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite. \n**It's always a good idea to make a reservation!**\n\n## Restaurants\n\n### French cuisine\n\n- [Solides](https://www.solides.fr/) — semi-gastronomic\n- [Les impulsifs](https://les-impulsifs-toulouse.eatbu.com/?lang=en) — semi-gastronomic\n- [Sixta](https://sixta-toulouse.fr/) — vege/vegan/gluten friendly\n- [Attila](https://attila.site-solocal.com/) — great **fish restaurant,** just above the Victor Hugo market\n- [Chez Emile](https://www.restaurant-emile.com/) - best [cassoulet](https://en.wikipedia.org/wiki/Cassoulet) in town (or so I'm told)\n\n### Korean\n\n- [Le ptit Louis](https://leptitlouis.fr/) — best of its kind, **only for lunch**\n- [Kongbap](https://kong-bap.com/) — street-food like\n\n### Japanese\n\n- [Iori](https://www.iori.fr/) — best ramen\n- [Japoyaki](https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402) — best sushi/sashimis\n\n## Drinks and snacks\n\n### Bars\n\n- [Le Bièrographe](https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327) — all time favourite, **check out the typical toulouse basement**\n- [A Taula](https://www.facebook.com/ataulatolosa/) — all time favourite in summer, **amazing terrace,** also: great tapas\n- [The Hopscotch Pub](https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385) — good beers, good whiskies, good cocktials, good food\n\n### Cafés & tea rooms\n\n- [Bapz](https://www.bapz.fr/contact) — Excellent pastries / hot beverages\n- [Ô thé divin](https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/) — nice lunch options\n- [Les Rêveries d’Hercule](https://www.lesreveriesdhercule.com/) — Pottery Café, relaxing activity (ceramics need to be baked, there'll be a delay to get them back)\n- Bonus: the best bakeries in [Carmes](https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872) and [Saint-Aubin](https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694) — croissants, baguettes **traditions**, chocolatines and more\n\n### Wine shops\n\n- [l'envie du sud](https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930) — amazing selection of wines and other spirits, excellent advice from the staff\n- [enoteca](https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952) — smaller selection but more beers and great advice from the staff as well\n\n## Other delights\n\n### Ice creams\n\n- [Forno gusto](https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450) — only in the summer\n- [Moustache](https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540) — lots of flavours\n\n### Cheese shop\n\n- [Xavier](https://xavier.fr/) — one of the **best of the country**, two shops in Toulouse, including one at Victor Hugo market\n- [Massembea](https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490) — a serious contender in Toulouse (weird hours)\n\n### Delicatessen\n\n- [Café Bacquié](http://cafe-bacquie.com/) — stock up on fine foods, coffees, teas and other great quality products","src/content/fragments/en/toulouse-fun.md","370491cc68079e8c",{"html":624,"metadata":625},"\u003Cp>Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite.\u003Cbr>\n\u003Cstrong>It’s always a good idea to make a reservation!\u003C/strong>\u003C/p>\n\u003Ch2 id=\"restaurants\">Restaurants\u003C/h2>\n\u003Ch3 id=\"french-cuisine\">French cuisine\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.solides.fr/\">Solides\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://les-impulsifs-toulouse.eatbu.com/?lang=en\">Les impulsifs\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://sixta-toulouse.fr/\">Sixta\u003C/a> — vege/vegan/gluten friendly\u003C/li>\n\u003Cli>\u003Ca href=\"https://attila.site-solocal.com/\">Attila\u003C/a> — great \u003Cstrong>fish restaurant,\u003C/strong> just above the Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.restaurant-emile.com/\">Chez Emile\u003C/a> - best \u003Ca href=\"https://en.wikipedia.org/wiki/Cassoulet\">cassoulet\u003C/a> in town (or so I’m told)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"korean\">Korean\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://leptitlouis.fr/\">Le ptit Louis\u003C/a> — best of its kind, \u003Cstrong>only for lunch\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://kong-bap.com/\">Kongbap\u003C/a> — street-food like\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"japanese\">Japanese\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.iori.fr/\">Iori\u003C/a> — best ramen\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402\">Japoyaki\u003C/a> — best sushi/sashimis\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"drinks-and-snacks\">Drinks and snacks\u003C/h2>\n\u003Ch3 id=\"bars\">Bars\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327\">Le Bièrographe\u003C/a> — all time favourite, \u003Cstrong>check out the typical toulouse basement\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.facebook.com/ataulatolosa/\">A Taula\u003C/a> — all time favourite in summer, \u003Cstrong>amazing terrace,\u003C/strong> also: great tapas\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385\">The Hopscotch Pub\u003C/a> — good beers, good whiskies, good cocktials, good food\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cafés--tea-rooms\">Cafés & tea rooms\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.bapz.fr/contact\">Bapz\u003C/a> — Excellent pastries / hot beverages\u003C/li>\n\u003Cli>\u003Ca href=\"https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/\">Ô thé divin\u003C/a> — nice lunch options\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lesreveriesdhercule.com/\">Les Rêveries d’Hercule\u003C/a> — Pottery Café, relaxing activity (ceramics need to be baked, there’ll be a delay to get them back)\u003C/li>\n\u003Cli>Bonus: the best bakeries in \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872\">Carmes\u003C/a> and \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694\">Saint-Aubin\u003C/a> — croissants, baguettes \u003Cstrong>traditions\u003C/strong>, chocolatines and more\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"wine-shops\">Wine shops\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930\">l’envie du sud\u003C/a> — amazing selection of wines and other spirits, excellent advice from the staff\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952\">enoteca\u003C/a> — smaller selection but more beers and great advice from the staff as well\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"other-delights\">Other delights\u003C/h2>\n\u003Ch3 id=\"ice-creams\">Ice creams\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450\">Forno gusto\u003C/a> — only in the summer\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540\">Moustache\u003C/a> — lots of flavours\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cheese-shop\">Cheese shop\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://xavier.fr/\">Xavier\u003C/a> — one of the \u003Cstrong>best of the country\u003C/strong>, two shops in Toulouse, including one at Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490\">Massembea\u003C/a> — a serious contender in Toulouse (weird hours)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"delicatessen\">Delicatessen\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"http://cafe-bacquie.com/\">Café Bacquié\u003C/a> — stock up on fine foods, coffees, teas and other great quality products\u003C/li>\n\u003C/ul>",{"headings":626,"imagePaths":663,"frontmatter":664},[627,630,633,636,639,642,645,648,651,654,657,660],{"depth":26,"slug":628,"text":629},"restaurants","Restaurants",{"depth":70,"slug":631,"text":632},"french-cuisine","French cuisine",{"depth":70,"slug":634,"text":635},"korean","Korean",{"depth":70,"slug":637,"text":638},"japanese","Japanese",{"depth":26,"slug":640,"text":641},"drinks-and-snacks","Drinks and snacks",{"depth":70,"slug":643,"text":644},"bars","Bars",{"depth":70,"slug":646,"text":647},"cafés--tea-rooms","Cafés & tea rooms",{"depth":70,"slug":649,"text":650},"wine-shops","Wine shops",{"depth":26,"slug":652,"text":653},"other-delights","Other delights",{"depth":70,"slug":655,"text":656},"ice-creams","Ice creams",{"depth":70,"slug":658,"text":659},"cheese-shop","Cheese shop",{"depth":70,"slug":661,"text":662},"delicatessen","Delicatessen",[],{"title":615,"subtitle":616,"lang":180,"slug":612,"excerpt":665,"tags":666,"type":560,"createdAt":362},"Gonna have to trust me on this ¯\\_(ツ)_/¯",[618],"buttons",{"id":667,"data":669,"body":674,"filePath":675,"digest":676,"deferredRender":184},{"title":670,"subtitle":671,"lang":15,"tags":672,"type":552,"slug":667,"createdAt":673,"code":184,"draft":184},"Effets de survol de boutons","Simples mais efficaces.",[559],["Date","2020-10-08T09:00:00.000Z"],"## Styles généraux\n\nTous les boutons présents utilisent ces styles comme base en guise de « reset » :\n\n> N'oubliez pas de préfixer si besoin !\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Ajout d'icône\n\n\u003Cbutton role='none' class='btn btn-icon'>\n\t\u003Cspan>Icône\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('./assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double volet\n\n\u003Cbutton role='none' class='btn btn-rideau'>\n\t\u003Cspan>Volet\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Dégradé animé\n\n\u003Cbutton role='none' class='btn btn-gradient'>\n\t\u003Cspan>Dégradé\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Échelle non desctructrice\n\n\u003Cbutton role='none' class='btn btn-scale'>\n\t\u003Cspan>Échelle\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/fr/buttons.mdx","f5d7b03520f96b04","image-full",{"id":677,"data":679,"body":685,"filePath":686,"digest":687,"deferredRender":184},{"title":680,"subtitle":681,"lang":15,"tags":682,"type":552,"slug":677,"createdAt":683,"updatedAt":684},"Image pleine largeur","Casser le conteneur.",[559],["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Image inline\n\nOn est parfois obligé d'utiliser des images dans des balises `img` plutôt que dans un `background` en css. Comment faire alors pour que l'image sorte de son conteneur pour en faire une bannière ? Exemple pratique à partir de ce même site.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_container_9e3939b3ae.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Contexte\n\nConsidérons le html suivant :\n\n```html\n\u003C!-- index.html -->\n\u003Csection class=\"container\">\n\t\u003Cdiv class=\"hero\">\n\t\t\u003Cimg class=\"hero__image\" src=\"hero.img\" />\n\t\u003C/div>\n\u003C/section>\n```\n\nEt le style suivant :\n\n```css\n/* style.css */\n.container {\n\tpadding: 0 14px;\n\tmargin-inline: auto;\n\tmax-inline-size: 1040px;\n}\nimg {\n\tmax-inline-size: 100%;\n\tblock-size: auto;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_original_d49f0d11bf.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Déborder du conteneur\n\nAfin de faire prendre à l'image toute la largeur, on agit sur son conteneur :\n\n```css\n/* style.css */\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_full_2a902f9539.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Faire une bannière\n\nOn peut alors réduire la hauteur du conteneur pour obtenir une bannière plutôt que l'image entière et faire correspondre la hauteur de l'image à la hauteur du conteneur :\n\n```css title='style.css' ins={5, 7-9}\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n\tblock-size: 200px;\n}\n.hero__image {\n\tblock-size: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_height_81b4ce969a.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nIl faut ensuite forcer l'image à prendre toute la largeur du conteneur :\n\n```css title='style.css' ins={3}\n.hero__image {\n\tblock-size: 100%;\n\tinline-size: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_deformed_479046d2cb.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nPas top…\n\n### J'ai cassé l'image…\n\n**ENFIN** le code magique pour redonner son ratio à l'image sans la déformer :\n\n```css title='style.css' ins={4,5}\n.hero__image {\n\tblock-size: 100%;\n\tinline-size: 100%;\n\tobject-fit: cover;\n\tobject-position: center; /* à positionner comme on veut */\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_6c164e82b3.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nCette technique s'apparente à l'utilisation d'une image de background.\n\n## TL;DR\n\nLe code complet :\n\n```css\n/* style.css */\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n\tblock-size: 200px;\n}\n.hero__image {\n\tinline-size: 100%;\n\tblock-size: 100%;\n\t-o-object-fit: cover;\n\tobject-fit: cover;\n\t-o-object-position: center;\n\tobject-position: center;\n}\n```","src/content/fragments/fr/image-full.mdx","585dcfae92fb08fb","super-cookies",{"id":688,"data":690,"body":696,"filePath":697,"digest":698,"deferredRender":184},{"title":691,"subtitle":692,"lang":15,"tags":693,"type":552,"slug":688,"createdAt":695},"Les meilleurs cookies","Des gâteaux sans consentement.",[694],"cuisine",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Version végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 3/4 de l'aquafaba de 400g de pois chiche (l'eau des pois chiche)\n- 125 grammes d'huile de noix de coco\n- 2 cuillères à café de sirop d'érable\n- 1 plaquette de chocolat (noir) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre si besoin l'huile de noix de coco à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (huile, aquafaba, sirop d'érable)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Version non végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 1 œuf\n- 125 grammes de beurre fondu\n- 2 cuillères à café de miel\n- 1 plaquette de chocolat (noir/blanc/les deux) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre le beurre à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (beurre fondu, œuf, miel)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Notes\n\nLe chocolat peut-être remplacé par n'importe quoi comme des noix, des raisins secs, des légos… (mangez pas des légos soyez sérieux).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Tous les ingrédients mélangés forment une pâte marron.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Les cookies cuits sont bombés et très moelleux.'\n/>","src/content/fragments/fr/super-cookies.mdx","f7a802e0b68cb04a","toulouse-fun",{"id":699,"data":701,"body":574,"filePath":704,"digest":705,"rendered":706},{"title":615,"subtitle":570,"lang":15,"tags":702,"type":552,"slug":699,"createdAt":703,"draft":184},[618],["Date","2022-06-22T15:34:45.000Z"],"src/content/fragments/fr/toulouse-fun.md","a0c25b438b34c05e",{"html":578,"metadata":707},{"headings":708,"imagePaths":709,"frontmatter":710},[],[],{"title":615,"subtitle":570,"lang":15,"draft":184,"slug":699,"createdAt":362,"excerpt":570,"tags":711,"type":552},[618],"visited-links",{"id":712,"data":714,"body":720,"filePath":721,"digest":722,"rendered":723},{"title":715,"subtitle":716,"lang":15,"tags":717,"type":560,"slug":712,"createdAt":718,"draft":719},"Liens visités et indication visuelle","Comment différencier les liens déjà cliqués",[132],["Date","2023-06-06T18:34:00.000Z"],false,"## La théorie\n\nIl est possible sur le web d'appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu'un lien visité est violet.\n\nGénéralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L'information qu'un lien a déjà été visité ne semble pas indispensable à la navigation. C'est sûrement vrai, mais personnellement, je suis assez content d'avoir un rappel des pages que j'ai déjà consultées lorsque je navigue.\n\nUne information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J'ai alors cherché un moyen d'ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n'est certainement pas idéale, elle se rapproche plus d'une expérience, à priori inoffensive pour l'internaute.\n\n## La spécification\n\nQuand je me suis intéressé à ce qu'il était possible de faire avec les liens déjà visités, j'ai découvert qu'extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu'il était possible de récupérer l'historique de navigation d'un utilisateur grâce aux styles des liens visités. Le sélecteur `:visited` a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. [Plus d'informations dans cet article.](https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector)\n\n## La pratique\n\nQue faire alors, en terme de style, quand on ne peut changer que des couleurs ?\n\nD'après MDN, les propriétés suivantes sont modifiables :\n\n- `color`\n- `background-color`\n- `border-color` (et les propriétés détaillées associées),\n- `column-rule-color`\n- `outline-color`\n- `text-decoration-color`\n- `text-emphasis-color`\n- Les composantes de couleur liées aux attributs SVG `fill` et `stroke`.\n\nChanger la couleur d'un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\n\nEn revanche, il est possible de \" masquer \" un élément en modifiant sa couleur pour qu'elle corresponde à la couleur du fond de la page ou de l'élément parent. On pourrait ainsi imaginer masquer une `border` ou un `outline`.\n\nJ'ai personnellement choisi de faire différemment. J'ai décidé d'utiliser un pseudo-élément `::before` sur l'état non visité du lien puis de le masquer quand celui-ci devient visité.\n\n### Le code\n\n```css {5,16} title=\"style.css\"\na {\n\tposition: relative;\n\ttext-decoration: none;\n}\na::before {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 0;\n\tinline-size: 2px;\n\tblock-size: 2px;\n\tborder-radius: 4px;\n\ttransform: translate(-6px, 0);\n\tbackground-color: grey;\n}\na:visited::before {\n\tbackground-color: white;\n}\n```\n\nCes règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\n\n### Accessibilité\n\nOn pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété `content` mais les lecteurs d'écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d'écrans annoncent déjà si un lien est visité avant de lire son intitulé.\n\n## Aller plus loin\n\nAfin de pousser l'expérience un peu plus loin, j'ai tenté d'utiliser des éléments plus explicites pour signifier l'état visité du lien. Bien qu'encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\n\nL'idée est d'avoir un `::before` et un `::after`, chacun contenant une icône en base 64 blanche en tant qu'image de fond. Quand le lien est non visité, le `::before` contient un fond coloré qui fait apparaître l'icône. Quand le lien passe en visité, le fond du `::before` devient blanc et celui du `::after` devient coloré, ce qui masque la première icône et affiche la deuxième.\n\nIl est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l'une sur l'autre.\n\n[Voir la démo sur codepen.](https://codepen.io/narduin/pen/VwVwmrO)","src/content/fragments/fr/visited-links.md","c062a565e4c30dfe",{"html":724,"metadata":725},"\u003Ch2 id=\"la-théorie\">La théorie\u003C/h2>\n\u003Cp>Il est possible sur le web d’appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu’un lien visité est violet.\u003C/p>\n\u003Cp>Généralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L’information qu’un lien a déjà été visité ne semble pas indispensable à la navigation. C’est sûrement vrai, mais personnellement, je suis assez content d’avoir un rappel des pages que j’ai déjà consultées lorsque je navigue.\u003C/p>\n\u003Cp>Une information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J’ai alors cherché un moyen d’ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n’est certainement pas idéale, elle se rapproche plus d’une expérience, à priori inoffensive pour l’internaute.\u003C/p>\n\u003Ch2 id=\"la-spécification\">La spécification\u003C/h2>\n\u003Cp>Quand je me suis intéressé à ce qu’il était possible de faire avec les liens déjà visités, j’ai découvert qu’extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu’il était possible de récupérer l’historique de navigation d’un utilisateur grâce aux styles des liens visités. Le sélecteur \u003Ccode>:visited\u003C/code> a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector\">Plus d’informations dans cet article.\u003C/a>\u003C/p>\n\u003Ch2 id=\"la-pratique\">La pratique\u003C/h2>\n\u003Cp>Que faire alors, en terme de style, quand on ne peut changer que des couleurs ?\u003C/p>\n\u003Cp>D’après MDN, les propriétés suivantes sont modifiables :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>background-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>border-color\u003C/code> (et les propriétés détaillées associées),\u003C/li>\n\u003Cli>\u003Ccode>column-rule-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>outline-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-decoration-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-emphasis-color\u003C/code>\u003C/li>\n\u003Cli>Les composantes de couleur liées aux attributs SVG \u003Ccode>fill\u003C/code> et \u003Ccode>stroke\u003C/code>.\u003C/li>\n\u003C/ul>\n\u003Cp>Changer la couleur d’un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\u003C/p>\n\u003Cp>En revanche, il est possible de ” masquer ” un élément en modifiant sa couleur pour qu’elle corresponde à la couleur du fond de la page ou de l’élément parent. On pourrait ainsi imaginer masquer une \u003Ccode>border\u003C/code> ou un \u003Ccode>outline\u003C/code>.\u003C/p>\n\u003Cp>J’ai personnellement choisi de faire différemment. J’ai décidé d’utiliser un pseudo-élément \u003Ccode>::before\u003C/code> sur l’état non visité du lien puis de le masquer quand celui-ci devient visité.\u003C/p>\n\u003Ch3 id=\"le-code\">Le code\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">style.css\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">relative\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-decoration: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line highlight mark\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#eca3a8\">a\u003C/span>\u003Cspan style=\"--0:#73c3cc\">::before\u003C/span>\u003Cspan style=\"--0:#b0b6c3\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">inline-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">block-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">4\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-6\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: grey;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line highlight mark\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#eca3a8\">a\u003C/span>\u003Cspan style=\"--0:#73c3cc\">:visited::before\u003C/span>\u003Cspan style=\"--0:#b0b6c3\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"a { position: relative; text-decoration: none;}a::before { content: ''; position: absolute; top: 50%; left: 0; inline-size: 2px; block-size: 2px; border-radius: 4px; transform: translate(-6px, 0); background-color: grey;}a:visited::before { background-color: white;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Ces règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\u003C/p>\n\u003Ch3 id=\"accessibilité\">Accessibilité\u003C/h3>\n\u003Cp>On pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété \u003Ccode>content\u003C/code> mais les lecteurs d’écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d’écrans annoncent déjà si un lien est visité avant de lire son intitulé.\u003C/p>\n\u003Ch2 id=\"aller-plus-loin\">Aller plus loin\u003C/h2>\n\u003Cp>Afin de pousser l’expérience un peu plus loin, j’ai tenté d’utiliser des éléments plus explicites pour signifier l’état visité du lien. Bien qu’encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\u003C/p>\n\u003Cp>L’idée est d’avoir un \u003Ccode>::before\u003C/code> et un \u003Ccode>::after\u003C/code>, chacun contenant une icône en base 64 blanche en tant qu’image de fond. Quand le lien est non visité, le \u003Ccode>::before\u003C/code> contient un fond coloré qui fait apparaître l’icône. Quand le lien passe en visité, le fond du \u003Ccode>::before\u003C/code> devient blanc et celui du \u003Ccode>::after\u003C/code> devient coloré, ce qui masque la première icône et affiche la deuxième.\u003C/p>\n\u003Cp>Il est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l’une sur l’autre.\u003C/p>\n\u003Cp>\u003Ca href=\"https://codepen.io/narduin/pen/VwVwmrO\">Voir la démo sur codepen.\u003C/a>\u003C/p>",{"headings":726,"imagePaths":744,"frontmatter":745},[727,730,733,736,739,741],{"depth":26,"slug":728,"text":729},"la-théorie","La théorie",{"depth":26,"slug":731,"text":732},"la-spécification","La spécification",{"depth":26,"slug":734,"text":735},"la-pratique","La pratique",{"depth":70,"slug":737,"text":738},"le-code","Le code",{"depth":70,"slug":146,"text":740},"Accessibilité",{"depth":26,"slug":742,"text":743},"aller-plus-loin","Aller plus loin",[],{"title":715,"subtitle":716,"lang":15,"draft":719,"slug":712,"excerpt":598,"tags":746,"type":560,"createdAt":600},[132],"en-array-vs-array",{"id":747,"data":749,"body":754,"filePath":755,"digest":756,"rendered":757},{"title":750,"subtitle":751,"lang":180,"tags":752,"type":560,"slug":747,"createdAt":753},"Filter an array against another array","Array vs Array.",[572],["Date","2022-06-08T14:24:06.000Z"],"## Context\n\nFor a project, I had to come up with a way to filter an array of objects based on another array of strings.\n\nIn other words, I needed to include every object which `user` property was found in the second array.\n\nHere is an example:\n\n```javascript\nconst skills = [\n\t{\n\t\tname: 'Be awesome',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Great jokes',\n\t\tuser: 'Jacques'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Beatriz'\n\t}\n]\n\nconst selectedUsers = ['Jean', 'Beatriz']\n```\n\nI thought it would be pretty easy but I guess I'm not familiar enough with javascript 😬\n\n## My solution\n\nAfter a bit of thinking, I came up with the following statement:\n\n> I need to filter the skills based on which users are selected. So I need to loop over the `selectedUsers` array and filter the skills according to their `user` value.\n\nAfter a bit more trials and errors, this is the code I ended up using in a `computed property`:\n\n```javascript\n// index.vue\nconst filteredSkills = selectedUsers.map((user) => {\n\treturn skills.filter((skill) => {\n\t\treturn skill.user === user\n\t})\n})\n```\n\nI used `map()` in order to loop on the second array and used its string value to only include the corresponding skills with `filter()`.\n\nI'm pretty sure there is a better way to do it though…","src/content/fragments/en/array-vs-array.md","c63ba57b1049cf4c",{"html":758,"metadata":759},"\u003Ch2 id=\"context\">Context\u003C/h2>\n\u003Cp>For a project, I had to come up with a way to filter an array of objects based on another array of strings.\u003C/p>\n\u003Cp>In other words, I needed to include every object which \u003Ccode>user\u003C/code> property was found in the second array.\u003C/p>\n\u003Cp>Here is an example:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Be awesome'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Great jokes'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jacques'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Beatriz'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">selectedUsers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> [\u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#98C379\">'Beatriz'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const skills = [ { name: 'Be awesome', user: 'Jean' }, { name: 'Great jokes', user: 'Jacques' }, { name: 'Heavy sleeper', user: 'Jean' }, { name: 'Heavy sleeper', user: 'Beatriz' }]const selectedUsers = ['Jean', 'Beatriz']\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>I thought it would be pretty easy but I guess I’m not familiar enough with javascript 😬\u003C/p>\n\u003Ch2 id=\"my-solution\">My solution\u003C/h2>\n\u003Cp>After a bit of thinking, I came up with the following statement:\u003C/p>\n\u003Cblockquote>\n\u003Cp>I need to filter the skills based on which users are selected. So I need to loop over the \u003Ccode>selectedUsers\u003C/code> array and filter the skills according to their \u003Ccode>user\u003C/code> value.\u003C/p>\n\u003C/blockquote>\n\u003Cp>After a bit more trials and errors, this is the code I ended up using in a \u003Ccode>computed property\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">filteredSkills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">selectedUsers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">map\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">((\u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) \u003C/span>\u003Cspan style=\"--0:#CD89E1\">=>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">filter\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">((\u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">skill\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) \u003C/span>\u003Cspan style=\"--0:#CD89E1\">=>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skill\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">===\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const filteredSkills = selectedUsers.map((user) => { return skills.filter((skill) => { return skill.user === user })})\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>I used \u003Ccode>map()\u003C/code> in order to loop on the second array and used its string value to only include the corresponding skills with \u003Ccode>filter()\u003C/code>.\u003C/p>\n\u003Cp>I’m pretty sure there is a better way to do it though…\u003C/p>",{"headings":760,"imagePaths":767,"frontmatter":768},[761,764],{"depth":26,"slug":762,"text":763},"context","Context",{"depth":26,"slug":765,"text":766},"my-solution","My solution",[],{"title":750,"subtitle":751,"lang":180,"slug":747,"createdAt":269,"excerpt":769,"tags":770,"type":560},"My peak javascript",[572],"en-nuxt-graphql-static",{"id":771,"data":773,"body":779,"filePath":780,"digest":781,"rendered":782},{"title":774,"subtitle":775,"lang":180,"tags":776,"type":560,"slug":771,"createdAt":777,"updatedAt":778},"Static website and GraphQL queries with Nuxt.js","Graphql client is king.",[572],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## The problem\n\nI encountered a nasty bug while using static generation with Nuxt and [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (new tab)') client.\nI found [the issue](https://github.com/nuxt-community/apollo-module/issues/339 'Github issue on nuxt/apollo repository (new tab)') already reported on github.\n\nIt seems the module doesn't handle static generation correctly with `nuxt generate`.\n\nI could find request to my local API url after the static generation. Moreover, it also seemed like `\u003Cnuxt-link>` navigation was broken.\n\n## The solution 🙌\n\nFortunately, there is another Nuxt module that handles GraphQL requests!\n\n[Nuxt graphql request to the rescue!](https://github.com/gomah/nuxt-graphql-request)\n\n### The conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### The request\n\nThe best approach so far is to use `asyncData` in pages and `fetch` in components. Using `fetch` in pages does not work well at all with `nuxt generate`.\n\nI also install the `graphql-tag` package (only in `devDependencies`) to be able to import directly `.gql` files.\n\nQuery example:\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Inside a page\n\n```vue\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n\tasync asyncData({ $graphql }) {\n\t\tconst data = await $graphql.default.request(homepageQuery)\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```\n\n#### Inside a component\n\nIt is safer to wait until `fetch` has received a response before displaying anything. You can use `$fetchState` to be sure ([documentation](https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation on the fetch hook (new tab)')).\n\n```vue\n// Header.vue\n\u003Ctemplate>\n\t\u003Cheader v-if=\"!$fetchState.pending\">…\u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tdata: {}\n\t\t}\n\t},\n\tasync fetch() {\n\t\ttry {\n\t\t\tconst data = await this.$graphql.default.request(headerQuery)\n\t\t\tthis.data = data\n\t\t} catch (error) {\n\t\t\tconsole.error(JSON.stringify(error, undefined, 2))\n\t\t}\n\t}\n}\n\u003C/script>\n```\n\n### Options\n\nTo pass options to the request, for example for a multilingual version with [nuxt/i18n](https://i18n.nuxtjs.org/) and/or a url parameter in a dynamic page:\n\n```vue\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n\tasync asyncData({ $graphql, app, params }) {\n\t\tconst locale = app.i18n.localeProperties.iso\n\t\tconst data = await $graphql.default.request(articleQuery, {\n\t\t\tcode: locale,\n\t\t\tslug: params.slug\n\t\t})\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```","src/content/fragments/en/nuxt-graphql-static.md","c5d4f0dd6ca0e1c2",{"html":783,"metadata":784},"\u003Ch2 id=\"the-problem\">The problem\u003C/h2>\n\u003Cp>I encountered a nasty bug while using static generation with Nuxt and \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (new tab)\">nuxt apollo\u003C/a> client.\nI found \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Github issue on nuxt/apollo repository (new tab)\">the issue\u003C/a> already reported on github.\u003C/p>\n\u003Cp>It seems the module doesn’t handle static generation correctly with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I could find request to my local API url after the static generation. Moreover, it also seemed like \u003Ccode><nuxt-link>\u003C/code> navigation was broken.\u003C/p>\n\u003Ch2 id=\"the-solution\">The solution 🙌\u003C/h2>\n\u003Cp>Fortunately, there is another Nuxt module that handles GraphQL requests!\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\">Nuxt graphql request to the rescue!\u003C/a>\u003C/p>\n\u003Ch3 id=\"the-conf\">The conf\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">nuxt.config.js\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">buildModules\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">clients\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">endpoint\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">options\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">authorization\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"buildModules: [ 'nuxt-graphql-request',],graphql: { clients: { default: { endpoint: 'http://API_URL/graphql', options: { headers: { authorization: 'Bearer API_TOKEN', }, }, }, },},\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"the-request\">The request\u003C/h3>\n\u003Cp>The best approach so far is to use \u003Ccode>asyncData\u003C/code> in pages and \u003Ccode>fetch\u003C/code> in components. Using \u003Ccode>fetch\u003C/code> in pages does not work well at all with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I also install the \u003Ccode>graphql-tag\u003C/code> package (only in \u003Ccode>devDependencies\u003C/code>) to be able to import directly \u003Ccode>.gql\u003C/code> files.\u003C/p>\n\u003Cp>Query example:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">homepage.gql\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"graphql\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">query\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepage\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">subtitle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">hero\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">id\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">alt\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"query { homepage { title subtitle hero { id alt } }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"inside-a-page\">Inside a page\u003C/h4>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/homepage'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import homepageQuery from '~/graphql/queries/singles/homepage'export default { async asyncData({ $graphql }) { const data = await $graphql.default.request(homepageQuery) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"inside-a-component\">Inside a component\u003C/h4>\n\u003Cp>It is safer to wait until \u003Ccode>fetch\u003C/code> has received a response before displaying anything. You can use \u003Ccode>$fetchState\u003C/code> to be sure (\u003Ca href=\"https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation on the fetch hook (new tab)\">documentation\u003C/a>).\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">Header.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">v-if\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#56B6C2\">!\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$fetchState\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">pending\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>…</\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/header'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">fetch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">try\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">} \u003C/span>\u003Cspan style=\"--0:#CD89E1\">catch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> (\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">console\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E5C07B\">JSON\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">stringify\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">undefined\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">))\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ctemplate> \u003Cheader v-if="!$fetchState.pending">…\u003C/header>\u003C/template>\u003Cscript>import headerQuery from '~/graphql/queries/singles/header'export default { data() { return { data: {} } }, async fetch() { try { const data = await this.$graphql.default.request(headerQuery) this.data = data } catch (error) { console.error(JSON.stringify(error, undefined, 2)) } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"options\">Options\u003C/h3>\n\u003Cp>To pass options to the request, for example for a multilingual version with \u003Ca href=\"https://i18n.nuxtjs.org/\">nuxt/i18n\u003C/a> and/or a url parameter in a dynamic page:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">_slug.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/articles'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">i18n\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">localeProperties\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">iso\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">code\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E6888F\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E5C07B\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import articleQuery from '~/graphql/queries/articles'export default { async asyncData({ $graphql, app, params }) { const locale = app.i18n.localeProperties.iso const data = await $graphql.default.request(articleQuery, { code: locale, slug: params.slug }) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":785,"imagePaths":808,"frontmatter":809},[786,789,792,795,798,802,805],{"depth":26,"slug":787,"text":788},"the-problem","The problem",{"depth":26,"slug":790,"text":791},"the-solution","The solution 🙌",{"depth":70,"slug":793,"text":794},"the-conf","The conf",{"depth":70,"slug":796,"text":797},"the-request","The request",{"depth":799,"slug":800,"text":801},4,"inside-a-page","Inside a page",{"depth":799,"slug":803,"text":804},"inside-a-component","Inside a component",{"depth":70,"slug":806,"text":807},"options","Options",[],{"title":774,"subtitle":775,"lang":180,"slug":771,"createdAt":269,"updatedAt":810,"excerpt":811,"tags":812,"type":560},"2022-09-08T13:43:33.000Z","When the most used gql module doesn't work…",[572],"nuxt-graphql-static",{"id":813,"data":815,"body":821,"filePath":822,"digest":823,"rendered":824},{"title":816,"subtitle":817,"lang":15,"tags":818,"type":552,"slug":813,"createdAt":819,"updatedAt":820},"Site statique et requêtes GraphQL avec Nuxt.js","Le client graphql est roi.",[572],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## Le problème\n\nJe me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (nouvel onglet)').\nAprès quelques recherches, voici [le bug constaté par quelqu'un d'autre](https://github.com/nuxt-community/apollo-module/issues/339 'Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)') sur github.\n\nIl semblerait que le module en l'état ne gère pas correctement la génération statique avec `nuxt generate`.\n\nJe trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les `\u003Cnuxt-link>` ne fonctionnait pas.\n\n## La solution 🙌\n\nHeureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\n\n[Nuxt graphql request à la rescousse !](https://github.com/gomah/nuxt-graphql-request 'Dépôt github du module (nouvel onglet)')\n\n### La conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### La requête\n\nLa meilleure méthode à ce jour est d'utiliser `asyncData` dans les pages et `fetch` dans les composants. Utiliser `fetch` dans les pages ne fonctionne pas bien du tout avec `nuxt generate`.\n\nJ'installe également le paquet `graphql-tag` (uniquement en `devDependencies`) afin de pouvoir importer directement des fichiers `.gql`\n\nExemple de fichier :\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Dans une page\n\n```vue\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n\tasync asyncData({ $graphql }) {\n\t\tconst data = await $graphql.default.request(homepageQuery)\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```\n\n#### Dans un composant\n\nIl est plus prudent d'attendre que `fetch` ait reçu une réponse avant d'afficher quoi que ce soit. On peut utiliser `$fetchState` afin d'être tranquille ([documentation](https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation sur la méthode fetch (nouvel onglet)')).\n\n```vue\n// Header.vue\n\u003Ctemplate>\n\t\u003Cheader v-if=\"!$fetchState.pending\">…\u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tdata: {}\n\t\t}\n\t},\n\tasync fetch() {\n\t\ttry {\n\t\t\tconst data = await this.$graphql.default.request(headerQuery)\n\t\t\tthis.data = data\n\t\t} catch (error) {\n\t\t\tconsole.error(JSON.stringify(error, undefined, 2))\n\t\t}\n\t}\n}\n\u003C/script>\n```\n\n### Les options\n\nPour passer des options à la requête, par exemple pour une version multilingue avec [nuxt/i18n](https://i18n.nuxtjs.org/ 'Documentation de nuxt i18n (nouvel onglet)') et/ou un paramètre d'url dans le cadre d'une page dynamique :\n\n```vue\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n\tasync asyncData({ $graphql, app, params }) {\n\t\tconst locale = app.i18n.localeProperties.iso\n\t\tconst data = await $graphql.default.request(articleQuery, {\n\t\t\tcode: locale,\n\t\t\tslug: params.slug\n\t\t})\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```","src/content/fragments/fr/nuxt-graphql-static.md","6304f174b83f0078",{"html":825,"metadata":826},"\u003Ch2 id=\"le-problème\">Le problème\u003C/h2>\n\u003Cp>Je me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (nouvel onglet)\">nuxt apollo\u003C/a>.\nAprès quelques recherches, voici \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)\">le bug constaté par quelqu’un d’autre\u003C/a> sur github.\u003C/p>\n\u003Cp>Il semblerait que le module en l’état ne gère pas correctement la génération statique avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>Je trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les \u003Ccode><nuxt-link>\u003C/code> ne fonctionnait pas.\u003C/p>\n\u003Ch2 id=\"la-solution\">La solution 🙌\u003C/h2>\n\u003Cp>Heureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\" title=\"Dépôt github du module (nouvel onglet)\">Nuxt graphql request à la rescousse !\u003C/a>\u003C/p>\n\u003Ch3 id=\"la-conf\">La conf\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">nuxt.config.js\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">buildModules\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">clients\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">endpoint\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">options\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">authorization\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"buildModules: [ 'nuxt-graphql-request',],graphql: { clients: { default: { endpoint: 'http://API_URL/graphql', options: { headers: { authorization: 'Bearer API_TOKEN', }, }, }, },},\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"la-requête\">La requête\u003C/h3>\n\u003Cp>La meilleure méthode à ce jour est d’utiliser \u003Ccode>asyncData\u003C/code> dans les pages et \u003Ccode>fetch\u003C/code> dans les composants. Utiliser \u003Ccode>fetch\u003C/code> dans les pages ne fonctionne pas bien du tout avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>J’installe également le paquet \u003Ccode>graphql-tag\u003C/code> (uniquement en \u003Ccode>devDependencies\u003C/code>) afin de pouvoir importer directement des fichiers \u003Ccode>.gql\u003C/code>\u003C/p>\n\u003Cp>Exemple de fichier :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">homepage.gql\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"graphql\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">query\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepage\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">subtitle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">hero\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">id\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">alt\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"query { homepage { title subtitle hero { id alt } }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"dans-une-page\">Dans une page\u003C/h4>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/homepage'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import homepageQuery from '~/graphql/queries/singles/homepage'export default { async asyncData({ $graphql }) { const data = await $graphql.default.request(homepageQuery) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"dans-un-composant\">Dans un composant\u003C/h4>\n\u003Cp>Il est plus prudent d’attendre que \u003Ccode>fetch\u003C/code> ait reçu une réponse avant d’afficher quoi que ce soit. On peut utiliser \u003Ccode>$fetchState\u003C/code> afin d’être tranquille (\u003Ca href=\"https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation sur la méthode fetch (nouvel onglet)\">documentation\u003C/a>).\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">Header.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">v-if\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#56B6C2\">!\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$fetchState\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">pending\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>…</\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/header'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">fetch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">try\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">} \u003C/span>\u003Cspan style=\"--0:#CD89E1\">catch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> (\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">console\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E5C07B\">JSON\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">stringify\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">undefined\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">))\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ctemplate> \u003Cheader v-if="!$fetchState.pending">…\u003C/header>\u003C/template>\u003Cscript>import headerQuery from '~/graphql/queries/singles/header'export default { data() { return { data: {} } }, async fetch() { try { const data = await this.$graphql.default.request(headerQuery) this.data = data } catch (error) { console.error(JSON.stringify(error, undefined, 2)) } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"les-options\">Les options\u003C/h3>\n\u003Cp>Pour passer des options à la requête, par exemple pour une version multilingue avec \u003Ca href=\"https://i18n.nuxtjs.org/\" title=\"Documentation de nuxt i18n (nouvel onglet)\">nuxt/i18n\u003C/a> et/ou un paramètre d’url dans le cadre d’une page dynamique :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">_slug.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/articles'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">i18n\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">localeProperties\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">iso\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">code\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E6888F\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E5C07B\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import articleQuery from '~/graphql/queries/articles'export default { async asyncData({ $graphql, app, params }) { const locale = app.i18n.localeProperties.iso const data = await $graphql.default.request(articleQuery, { code: locale, slug: params.slug }) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":827,"imagePaths":849,"frontmatter":850},[828,831,834,837,840,843,846],{"depth":26,"slug":829,"text":830},"le-problème","Le problème",{"depth":26,"slug":832,"text":833},"la-solution","La solution 🙌",{"depth":70,"slug":835,"text":836},"la-conf","La conf",{"depth":70,"slug":838,"text":839},"la-requête","La requête",{"depth":799,"slug":841,"text":842},"dans-une-page","Dans une page",{"depth":799,"slug":844,"text":845},"dans-un-composant","Dans un composant",{"depth":70,"slug":847,"text":848},"les-options","Les options",[],{"title":816,"subtitle":817,"lang":15,"slug":813,"createdAt":269,"updatedAt":810,"excerpt":851,"tags":852,"type":552},"Quand le module gql le plus utilisé ne fonctionne pas…",[572],"en-buttons",{"id":853,"data":855,"body":860,"filePath":861,"digest":862,"rendered":863},{"title":856,"subtitle":857,"lang":180,"tags":858,"type":560,"slug":853,"createdAt":859,"code":184,"draft":184},"Buttons hover","Simple, but nice.",[559],["Date","2020-10-08T09:00:00.000Z"],"## General rules\n\nAll the buttons use these styles as a “reset”:\n\n> Don't forget to prefix if necessary!\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Add an icon\n\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('~assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double shutter down\n\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Animated gradient\n\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Non destructive scale\n\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/en/buttons.md","ea9a5513a5a4cef4",{"html":864,"metadata":865},"\u003Ch2 id=\"general-rules\">General rules\u003C/h2>\n\u003Cp>All the buttons use these styles as a “reset”:\u003C/p>\n\u003Cblockquote>\n\u003Cp>Don’t forget to prefix if necessary!\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">margin: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">padding: \u003C/span>\u003Cspan style=\"--0:#D19A66\">12\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">26\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">relative\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">display: \u003C/span>\u003Cspan style=\"--0:#D19A66\">inline-block\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">overflow: \u003C/span>\u003Cspan style=\"--0:#D19A66\">hidden\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">font-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">rem\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">; \u003C/span>\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\">/* 20px */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">line-height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">1.6\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-align: \u003C/span>\u003Cspan style=\"--0:#D19A66\">center\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-decoration: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">font-weight: \u003C/span>\u003Cspan style=\"--0:#D19A66\">bold\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">cursor: \u003C/span>\u003Cspan style=\"--0:#D19A66\">pointer\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">-moz-appearance\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">-webkit-appearance\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: background-color \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn { margin: 20px 0; padding: 12px 26px; position: relative; display: inline-block; overflow: hidden; font-size: 20rem; /* 20px */ line-height: 1.6; text-align: center; text-decoration: none; font-weight: bold; cursor: pointer; border: none; border-radius: 2px; -moz-appearance: none; -webkit-appearance: none; color: white; background-color: hotpink; transition: background-color 0.3s ease;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"add-an-icon\">Add an icon\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">url\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#98C379\">'~assets/svg/arrow-right-white.svg'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">right: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">40\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">-50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: darkorchid;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-10\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">-50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">display: \u003C/span>\u003Cspan style=\"--0:#D19A66\">inline-block\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">27\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">28\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">29\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translateX\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-10\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">30\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-icon { background-color: hotpink;}.btn-icon::before { content: url('~assets/svg/arrow-right-white.svg'); position: absolute; width: 20px; top: 50%; right: 0; transform: translate(40px, -50%); transition: transform ease 0.3s;}.btn-icon:hover,.btn-icon:focus { background-color: darkorchid;}.btn-icon:hover::before,.btn-icon:focus::before { transform: translate(-10px, -50%);}.btn-icon > span { display: inline-block; width: 100%; height: 100%; transition: transform 0.3s ease;}.btn-icon:hover > span,.btn-icon:focus > span { transform: translateX(-10px);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"double-shutter-down\">Double shutter down\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">solid\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">transparent\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: \u003C/span>\u003Cspan style=\"--0:#D19A66\">color\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: darkorchid;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">bottom: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">z-index: \u003C/span>\u003Cspan style=\"--0:#D19A66\">-1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-timing-function: \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">27\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-timing-function: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">cubic-bezier\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">0.75\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.125\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">28\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">29\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">30\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">31\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">32\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">33\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translateY\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">34\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">35\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">36\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">37\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-delay: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.175\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">38\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-rideau { border: 2px solid #10113a; color: #10113a; background-color: transparent; transition: color 0.3s ease;}.btn-rideau:hover { color: white;}.btn-rideau::before { background: hotpink;}.btn-rideau::after { background: darkorchid;}.btn-rideau::before,.btn-rideau::after { content: ''; position: absolute; height: 100%; width: 100%; bottom: 100%; left: 0; z-index: -1; transition: transform 0.3s; transition-timing-function: ease; transition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);}.btn-rideau:hover::before,.btn-rideau:hover::after,.btn-rideau:focus::before,.btn-rideau:focus::after { transform: translateY(100%);}.btn-rideau:hover::after,.btn-rideau:focus::after { transition-delay: 0.175s;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"animated-gradient\">Animated gradient\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">linear-gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-45\u003C/span>\u003Cspan style=\"--0:#E6888F\">deg\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#ee7752\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#e73c7e\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#23a6d5\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#23d5ab\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">400\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">400\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">animation: GradientReverse \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.5\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">normal\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">forwards\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">animation: Gradient \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.5\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">normal\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">forwards\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">@keyframes\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">Gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">0% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">100% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">@keyframes\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">GradientReverse\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">0% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">100% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-gradient { background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); background-size: 400% 400%; background-position: 0% 50%; animation: GradientReverse 0.5s ease 1 normal forwards;}.btn-gradient:hover,.btn-gradient:focus { animation: Gradient 0.5s ease 1 normal forwards;}@keyframes Gradient { 0% { background-position: 0% 50%; } 100% { background-position: 100% 100%; }}@keyframes GradientReverse { 0% { background-position: 100% 100%; } 100% { background-position: 0% 50%; }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"non-destructive-scale\">Non destructive scale\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">overflow: \u003C/span>\u003Cspan style=\"--0:#D19A66\">visible\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">transparent\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">bottom: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">solid\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">scale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">1.1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-scale { overflow: visible; color: #10113a; background-color: transparent;}.btn-scale::after { content: ''; position: absolute; top: 0; left: 0; bottom: 0; width: 100%; border: 2px solid #10113a; border-radius: 2px; transition: transform 0.3s ease;}.btn-scale:hover::after,.btn-scale:focus::after { transform: scale(1.1);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":866,"imagePaths":882,"frontmatter":883},[867,870,873,876,879],{"depth":26,"slug":868,"text":869},"general-rules","General rules",{"depth":26,"slug":871,"text":872},"add-an-icon","Add an icon",{"depth":26,"slug":874,"text":875},"double-shutter-down","Double shutter down",{"depth":26,"slug":877,"text":878},"animated-gradient","Animated gradient",{"depth":26,"slug":880,"text":881},"non-destructive-scale","Non destructive scale",[],{"title":856,"subtitle":857,"lang":180,"slug":853,"draft":184,"excerpt":884,"tags":885,"code":184,"type":560,"createdAt":886},"Easy to grab and use hover effects.",[559],"2020-10-08T09:00:00.000Z","en-acme-sh-tls-cert",{"id":887,"data":889,"body":895,"filePath":896,"digest":897,"rendered":898},{"title":890,"subtitle":891,"lang":180,"tags":892,"type":560,"slug":887,"createdAt":894},"Strong TLS certificates with acme.sh","384-bit of https",[893],"security",["Date","2022-06-08T14:24:06.000Z"],"## Disclaimer\n\nI'm, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs. \nThis is why I've switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nYou can learn (far) more by reading [this topic](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) and its linked resources.\n\n## Requirements\n\n### Installing acme.sh\n\nFor automation and ease of use purposes, I'm using [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# for using standalone mode, you might have to install as sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changing default authority\n\nBy default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let's Encrypt because according to acme.sh, they're the only ones offering ECC capabilities.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Using your DNS api\n\nIf available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports [a lot](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) of DNS providers.\n\n### Define an api key\n\nFollow the [docs](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) for your DNS provider, usually:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Issue the cert\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Using standalone mode\n\nIf you don't have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\n\nPort `80` must be free.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Examples\n\n### Multi domains standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domain DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Next steps\n\nThe ECC certificate alone will not grant you a high/perfect score.\n\n### TLS version\n\nLimit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a [5% compatibility gap](https://caniuse.com/?search=tls%201.) with 1.2).\n\n### HSTS\n\nUse the [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/) header.\n\n```http\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Cipher suite\n\nUse recent and strong ciphers. This is where my knowledge hits its limit… I'm having a really hard time understanding what to use and why.\n\nI've based my initial choices of ciphers on [this list](https://tls.imirhil.fr/ciphers), cross referencing it with (older?) [browser compatibility](https://tls.imirhil.fr/suite).\n\nI then asked [Aeris](https://twitter.com/aeris22), the creator of [tls.imirhil.fr](https://tls.imirhil.fr), about it and he advised me to use the following:\n\n```cypher\nECDHE+AES:ECDHE+CHACHA20\n```\n\nIn order to achieve a perfect score, we can be a little more restrictive with:\n\n```cypher\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/en/acme-sh-tls-cert.md","4dc80f1d0e800d6f",{"html":899,"metadata":900},"\u003Ch2 id=\"disclaimer\">Disclaimer\u003C/h2>\n\u003Cp>I’m, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs.\u003Cbr>\nThis is why I’ve switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>You can learn (far) more by reading \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">this topic\u003C/a> and its linked resources.\u003C/p>\n\u003Ch2 id=\"requirements\">Requirements\u003C/h2>\n\u003Ch3 id=\"installing-acmesh\">Installing acme.sh\u003C/h3>\n\u003Cp>For automation and ease of use purposes, I’m using \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\"># for using standalone mode, you might have to install as sudo\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">curl\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">https://get.acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> | \u003C/span>\u003Cspan style=\"--0:#61AFEF\">sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">email=mail@domain.tld\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl https://get.acme.sh | sh -s email=mail@domain.tld\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"changing-default-authority\">Changing default authority\u003C/h3>\n\u003Cp>By default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let’s Encrypt because according to acme.sh, they’re the only ones offering ECC capabilities.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--set-default-ca\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--server\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">letsencrypt\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --set-default-ca --server letsencrypt\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"using-your-dns-api\">Using your DNS api\u003C/h2>\n\u003Cp>If available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">a lot\u003C/a> of DNS providers.\u003C/p>\n\u003Ch3 id=\"define-an-api-key\">Define an api key\u003C/h3>\n\u003Cp>Follow the \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">docs\u003C/a> for your DNS provider, usually:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">PROVIDER_Key\u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#98C379\">\"YOUR_API_KEY\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export PROVIDER_Key="YOUR_API_KEY"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"issue-the-cert\">Issue the cert\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"using-standalone-mode\">Using standalone mode\u003C/h2>\n\u003Cp>If you don’t have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\u003C/p>\n\u003Cp>Port \u003Ccode>80\u003C/code> must be free.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"examples\">Examples\u003C/h2>\n\u003Ch3 id=\"multi-domains-standalone\">Multi domains standalone\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">www.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">subdomain.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"wildcard-domain-dns\">Wildcard domain DNS\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'*.domain.tld'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"next-steps\">Next steps\u003C/h2>\n\u003Cp>The ECC certificate alone will not grant you a high/perfect score.\u003C/p>\n\u003Ch3 id=\"tls-version\">TLS version\u003C/h3>\n\u003Cp>Limit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a \u003Ca href=\"https://caniuse.com/?search=tls%201.\">5% compatibility gap\u003C/a> with 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Use the \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a> header.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">Strict-Transport-Security\u003C/span>\u003Cspan style=\"--0:#CD89E1\">:\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">max-age=31536000; includeSubDomains\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Strict-Transport-Security: max-age=31536000; includeSubDomains\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"cipher-suite\">Cipher suite\u003C/h3>\n\u003Cp>Use recent and strong ciphers. This is where my knowledge hits its limit… I’m having a really hard time understanding what to use and why.\u003C/p>\n\u003Cp>I’ve based my initial choices of ciphers on \u003Ca href=\"https://tls.imirhil.fr/ciphers\">this list\u003C/a>, cross referencing it with (older?) \u003Ca href=\"https://tls.imirhil.fr/suite\">browser compatibility\u003C/a>.\u003C/p>\n\u003Cp>I then asked \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, the creator of \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, about it and he advised me to use the following:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>In order to achieve a perfect score, we can be a little more restrictive with:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES256\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES256:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":901,"imagePaths":947,"frontmatter":948},[902,905,908,911,914,917,920,923,926,929,932,935,938,941,944],{"depth":26,"slug":903,"text":904},"disclaimer","Disclaimer",{"depth":26,"slug":906,"text":907},"requirements","Requirements",{"depth":70,"slug":909,"text":910},"installing-acmesh","Installing acme.sh",{"depth":70,"slug":912,"text":913},"changing-default-authority","Changing default authority",{"depth":26,"slug":915,"text":916},"using-your-dns-api","Using your DNS api",{"depth":70,"slug":918,"text":919},"define-an-api-key","Define an api key",{"depth":70,"slug":921,"text":922},"issue-the-cert","Issue the cert",{"depth":26,"slug":924,"text":925},"using-standalone-mode","Using standalone mode",{"depth":26,"slug":927,"text":928},"examples","Examples",{"depth":70,"slug":930,"text":931},"multi-domains-standalone","Multi domains standalone",{"depth":70,"slug":933,"text":934},"wildcard-domain-dns","Wildcard domain DNS",{"depth":26,"slug":936,"text":937},"next-steps","Next steps",{"depth":70,"slug":939,"text":940},"tls-version","TLS version",{"depth":70,"slug":942,"text":943},"hsts","HSTS",{"depth":70,"slug":945,"text":946},"cipher-suite","Cipher suite",[],{"title":890,"subtitle":891,"lang":180,"slug":887,"createdAt":269,"excerpt":949,"tags":950,"type":560},"Real cert have curves.",[893],"acme-sh-tls-cert",{"id":951,"data":953,"body":959,"filePath":960,"digest":961,"rendered":962},{"title":954,"subtitle":955,"lang":15,"tags":956,"type":552,"slug":951,"createdAt":958},"Certificates TLS robustes avec acme.sh","384-bit de https",[957],"sécurité",["Date","2022-06-08T14:24:06.000Z"],"## Attention\n\nJe ne suis pas du tout un expert en sécurité. J'aime juste les trucs nouveaux et stylés des internets. \nC'est pourquoi j'ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J'ai maintenant un joli 100/100 sur [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nVous pouvez en apprendre (beaucoup) plus [ici](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) et sur les liens cités (en anglais).\n\n## Prérequis\n\n### Installer acme.sh\n\nPour des raisons de simplicité et d'automatisation, j'utilise [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changer l'authorité par défaut\n\nPar défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let's Encrypt car, d'après acme.sh, ils sont les seuls à proposer des certificats ECC.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Utiliser l'api DNS\n\nSi vous en avez la possibilité, la façon la plus simple de générer un certificat est via l'api de votre fournisseur DNS. acme.sh supporte [énormément](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) de fournisseurs DNS.\n\n### Definir la clé api\n\nSuivez la [documentation](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) pour votre fournisseur DNS, généralement:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Émettre le certificat\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Utiliser le mode standalone\n\nSi vous n'avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s'occupe de toutes les vérifications.\n\nLe port `80` doit être disponible.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Exemples\n\n### Multi domaines standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domaine DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Étapes supplémentaires\n\nLe certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\n\n### Version TLS\n\nLimiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu [la différence de compatibilité de 5%](https://caniuse.com/?search=tls%201.) avec 1.2).\n\n### HSTS\n\nUtiliser le header [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/).\n\n```http\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Suite cryptographique\n\nUtiliser une suite cryptographique récente et robuste. C'est ici que mes connaissances deviennent limitées… J'ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\n\nJ'avais basé ma première suite sur [cette liste](https://tls.imirhil.fr/ciphers), en la comparant avec celle de la compatibilité (d'anciens ?) [navigateurs](https://tls.imirhil.fr/suite).\n\nJ'ai ensuite demandé à [Aeris](https://twitter.com/aeris22), le créateur de [tls.imirhil.fr](https://tls.imirhil.fr), ses conseils sur cette suite. Il m'a recommandé d'utiliser :\n\n```cypher\nECDHE+AES:ECDHE+CHACHA20\n```\n\nAfin d'atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\n\n```cypher\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/fr/acme-sh-tls-cert.md","018b0c09d1fdd6cc",{"html":963,"metadata":964},"\u003Ch2 id=\"attention\">Attention\u003C/h2>\n\u003Cp>Je ne suis pas du tout un expert en sécurité. J’aime juste les trucs nouveaux et stylés des internets.\u003Cbr>\nC’est pourquoi j’ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J’ai maintenant un joli 100/100 sur \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>Vous pouvez en apprendre (beaucoup) plus \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">ici\u003C/a> et sur les liens cités (en anglais).\u003C/p>\n\u003Ch2 id=\"prérequis\">Prérequis\u003C/h2>\n\u003Ch3 id=\"installer-acmesh\">Installer acme.sh\u003C/h3>\n\u003Cp>Pour des raisons de simplicité et d’automatisation, j’utilise \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\"># pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">curl\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">https://get.acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> | \u003C/span>\u003Cspan style=\"--0:#61AFEF\">sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">email=mail@domain.tld\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl https://get.acme.sh | sh -s email=mail@domain.tld\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"changer-lauthorité-par-défaut\">Changer l’authorité par défaut\u003C/h3>\n\u003Cp>Par défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let’s Encrypt car, d’après acme.sh, ils sont les seuls à proposer des certificats ECC.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--set-default-ca\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--server\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">letsencrypt\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --set-default-ca --server letsencrypt\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"utiliser-lapi-dns\">Utiliser l’api DNS\u003C/h2>\n\u003Cp>Si vous en avez la possibilité, la façon la plus simple de générer un certificat est via l’api de votre fournisseur DNS. acme.sh supporte \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">énormément\u003C/a> de fournisseurs DNS.\u003C/p>\n\u003Ch3 id=\"definir-la-clé-api\">Definir la clé api\u003C/h3>\n\u003Cp>Suivez la \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">documentation\u003C/a> pour votre fournisseur DNS, généralement:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">PROVIDER_Key\u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#98C379\">\"YOUR_API_KEY\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export PROVIDER_Key="YOUR_API_KEY"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"émettre-le-certificat\">Émettre le certificat\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"utiliser-le-mode-standalone\">Utiliser le mode standalone\u003C/h2>\n\u003Cp>Si vous n’avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s’occupe de toutes les vérifications.\u003C/p>\n\u003Cp>Le port \u003Ccode>80\u003C/code> doit être disponible.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"exemples\">Exemples\u003C/h2>\n\u003Ch3 id=\"multi-domaines-standalone\">Multi domaines standalone\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">www.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">subdomain.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"wildcard-domaine-dns\">Wildcard domaine DNS\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'*.domain.tld'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"étapes-supplémentaires\">Étapes supplémentaires\u003C/h2>\n\u003Cp>Le certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\u003C/p>\n\u003Ch3 id=\"version-tls\">Version TLS\u003C/h3>\n\u003Cp>Limiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu \u003Ca href=\"https://caniuse.com/?search=tls%201.\">la différence de compatibilité de 5%\u003C/a> avec 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Utiliser le header \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a>.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">Strict-Transport-Security\u003C/span>\u003Cspan style=\"--0:#CD89E1\">:\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">max-age=31536000; includeSubDomains\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Strict-Transport-Security: max-age=31536000; includeSubDomains\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"suite-cryptographique\">Suite cryptographique\u003C/h3>\n\u003Cp>Utiliser une suite cryptographique récente et robuste. C’est ici que mes connaissances deviennent limitées… J’ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\u003C/p>\n\u003Cp>J’avais basé ma première suite sur \u003Ca href=\"https://tls.imirhil.fr/ciphers\">cette liste\u003C/a>, en la comparant avec celle de la compatibilité (d’anciens ?) \u003Ca href=\"https://tls.imirhil.fr/suite\">navigateurs\u003C/a>.\u003C/p>\n\u003Cp>J’ai ensuite demandé à \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, le créateur de \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, ses conseils sur cette suite. Il m’a recommandé d’utiliser :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Afin d’atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES256\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES256:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":965,"imagePaths":1009,"frontmatter":1010},[966,969,972,975,978,981,984,987,990,993,996,999,1002,1005,1006],{"depth":26,"slug":967,"text":968},"attention","Attention",{"depth":26,"slug":970,"text":971},"prérequis","Prérequis",{"depth":70,"slug":973,"text":974},"installer-acmesh","Installer acme.sh",{"depth":70,"slug":976,"text":977},"changer-lauthorité-par-défaut","Changer l’authorité par défaut",{"depth":26,"slug":979,"text":980},"utiliser-lapi-dns","Utiliser l’api DNS",{"depth":70,"slug":982,"text":983},"definir-la-clé-api","Definir la clé api",{"depth":70,"slug":985,"text":986},"émettre-le-certificat","Émettre le certificat",{"depth":26,"slug":988,"text":989},"utiliser-le-mode-standalone","Utiliser le mode standalone",{"depth":26,"slug":991,"text":992},"exemples","Exemples",{"depth":70,"slug":994,"text":995},"multi-domaines-standalone","Multi domaines standalone",{"depth":70,"slug":997,"text":998},"wildcard-domaine-dns","Wildcard domaine DNS",{"depth":26,"slug":1000,"text":1001},"étapes-supplémentaires","Étapes supplémentaires",{"depth":70,"slug":1003,"text":1004},"version-tls","Version TLS",{"depth":70,"slug":942,"text":943},{"depth":70,"slug":1007,"text":1008},"suite-cryptographique","Suite cryptographique",[],{"title":954,"subtitle":955,"lang":15,"slug":951,"createdAt":269,"excerpt":1011,"tags":1012,"type":552},"La sécurité avec des courbes.",[957]] \ No newline at end of file +[["Map",1,2,9,10,124,125,173,174,189,190,655,656],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.1.1","content-config-digest","8021b3469f132349","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"site\":\"https://www.nardu.in\",\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[\"assets.nardu.in\"],\"remotePatterns\":[{\"protocol\":\"https\"}]},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":false,\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[[null,{\"theme\":\"one-dark-pro\",\"plugins\":[{\"name\":\"Line numbers\",\"styleSettings\":{\"defaultValues\":{\"lineNumbers\":{\"foreground\":\"inherit\",\"highlightForeground\":\"inherit\"}},\"cssVarExclusions\":[],\"cssVarReplacements\":[]},\"hooks\":{}},{\"name\":\"astro-expressive-code\",\"hooks\":{}}],\"defaultProps\":{\"showLineNumbers\":false,\"overridesByLang\":{\"css,html,js,ts,vue\":{\"showLineNumbers\":true}}}}]],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"responsiveImages\":false},\"legacy\":{\"collections\":false}}","HPsections",["Map",11,12,35,36,53,54,70,71,96,97],"011-offre",{"id":11,"data":13,"body":22,"filePath":23,"digest":24,"rendered":25},{"type":14,"lang":15,"uid":16,"image":17,"order":18,"quickTitle":19,"quickImage":20,"reference":21},"section","fr","offre","/assets/images/home/offre-1.1.svg",1.1,"Mes offres en freelance","/assets/images/home/icon-desktop.svg","parole-expression","## L'offre site web classique\n\nCette offre est destinée à un public souhaitant **se doter d'un site web**, sans forcément intégrer l'accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du [référentiel général d'amélioration de l'accessibilité](https://accessibilite.numerique.gouv.fr/) (\u003Cabbr>RGAA\u003C/abbr>).\n\nL'objectif principal de cette offre étant d'**établir une présence en ligne** pour le client. Que cette dernière ait un but informatif et/ou éditorial.\n\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->","src/data/HP/011-offre.md","290ecd1ed94a1087",{"html":26,"metadata":27},"\u003Ch2 id=\"loffre-site-web-classique\">L’offre site web classique\u003C/h2>\n\u003Cp>Cette offre est destinée à un public souhaitant \u003Cstrong>se doter d’un site web\u003C/strong>, sans forcément intégrer l’accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du \u003Ca href=\"https://accessibilite.numerique.gouv.fr/\">référentiel général d’amélioration de l’accessibilité\u003C/a> (\u003Cabbr>RGAA\u003C/abbr>).\u003C/p>\n\u003Cp>L’objectif principal de cette offre étant d’\u003Cstrong>établir une présence en ligne\u003C/strong> pour le client. Que cette dernière ait un but informatif et/ou éditorial.\u003C/p>\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->",{"headings":28,"imagePaths":33,"frontmatter":34},[29],{"depth":30,"slug":31,"text":32},2,"loffre-site-web-classique","L’offre site web classique",[],{"type":14,"uid":16,"lang":15,"image":17,"order":18,"quickTitle":19,"quickImage":20,"reference":21},"012-offre",{"id":35,"data":37,"body":41,"filePath":42,"digest":43,"rendered":44},{"type":14,"lang":15,"image":38,"order":39,"reference":40},"/assets/images/home/offre-1.2.svg",1.2,"rose-primaire","## L'offre accessibilité avancée\n\nCette offre s'adresse plus spécifiquement aux entités pour lesquelles **l'accessibilité du site est un critère majeur.** Qu'il s'agisse d'une création ou d'une mise en conformité après un audit d'accessibilité.\n\nLorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\n\n- [Rose Primaire](https://roseprimaire.com/) pour le conseil et l'accompagnement du projet ;\n- [Sylvain Plantier](https://jedessinebien.com/) et/ou [Benoît Etchevery](http://ben-etche.com/) pour l'illustration et la direction artistique.\n\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->","src/data/HP/012-offre.md","2a3bf3411b3c171b",{"html":45,"metadata":46},"\u003Ch2 id=\"loffre-accessibilité-avancée\">L’offre accessibilité avancée\u003C/h2>\n\u003Cp>Cette offre s’adresse plus spécifiquement aux entités pour lesquelles \u003Cstrong>l’accessibilité du site est un critère majeur.\u003C/strong> Qu’il s’agisse d’une création ou d’une mise en conformité après un audit d’accessibilité.\u003C/p>\n\u003Cp>Lorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://roseprimaire.com/\">Rose Primaire\u003C/a> pour le conseil et l’accompagnement du projet ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://jedessinebien.com/\">Sylvain Plantier\u003C/a> et/ou \u003Ca href=\"http://ben-etche.com/\">Benoît Etchevery\u003C/a> pour l’illustration et la direction artistique.\u003C/li>\n\u003C/ul>\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->",{"headings":47,"imagePaths":51,"frontmatter":52},[48],{"depth":30,"slug":49,"text":50},"loffre-accessibilité-avancée","L’offre accessibilité avancée",[],{"type":14,"lang":15,"order":39,"image":38,"reference":40},"013-offre",{"id":53,"data":55,"body":58,"filePath":59,"digest":60,"rendered":61},{"type":14,"lang":15,"image":56,"order":57},"/assets/images/home/offre-1.3.svg",1.3,"## Et l'éco-conception alors ?\n\nJe ne conçois pas l'éco-conception comme une offre. C'est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l'éco-conception sans accessibilité, j'applique donc ces méthodologies quelque soit le projet !","src/data/HP/013-offre.md","03e37f364ac27cb4",{"html":62,"metadata":63},"\u003Ch2 id=\"et-léco-conception-alors\">Et l’éco-conception alors ?\u003C/h2>\n\u003Cp>Je ne conçois pas l’éco-conception comme une offre. C’est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l’éco-conception sans accessibilité, j’applique donc ces méthodologies quelque soit le projet !\u003C/p>",{"headings":64,"imagePaths":68,"frontmatter":69},[65],{"depth":30,"slug":66,"text":67},"et-léco-conception-alors","Et l’éco-conception alors ?",[],{"type":14,"lang":15,"order":57,"image":56},"020-methodo",{"id":70,"data":72,"body":77,"filePath":78,"digest":79,"rendered":80},{"type":14,"lang":15,"uid":73,"image":74,"order":30,"quickTitle":75,"quickImage":76},"methodology","/assets/images/home/methodo.svg","Ma méthodologie","/assets/images/home/icon-methodo.svg","## Méthodologie\n\n### Accessibilité par défaut\n\nEngagé pour un web plus accessible, je crée des **sites web** en m'appuyant sur le [référentiel général d'amélioration de l'accessibilité (RGAA)](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) ainsi que sur les bonnes pratiques [Opquast.](https://www.opquast.com/rendre-le-web-meilleur/)\n\n### Sobriété par choix\n\nJe privilégie le développement de **sites statiques** en adoptant une approche [d'éco-conception numérique.](https://eco-conception.designersethiques.org/guide/fr/) \nC'est-à-dire que le site est pensé pour n'embarquer que les fonctionnalités nécessaires à son utilisation.\n\nCette approche présente de **nombreux avantages :**\n\n- chargement rapide des pages ;\n- sécurité renforcée ;\n- coûts serveur réduits ;\n- maintenance facilitée.\n\nLorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l'interface. Cela permet de garantir que **le site reste en ligne** même si le CMS venait à ne plus fonctionner.","src/data/HP/020-methodo.md","75a09b4e0b1e926b",{"html":81,"metadata":82},"\u003Ch2 id=\"méthodologie\">Méthodologie\u003C/h2>\n\u003Ch3 id=\"accessibilité-par-défaut\">Accessibilité par défaut\u003C/h3>\n\u003Cp>Engagé pour un web plus accessible, je crée des \u003Cstrong>sites web\u003C/strong> en m’appuyant sur le \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité (RGAA)\u003C/a> ainsi que sur les bonnes pratiques \u003Ca href=\"https://www.opquast.com/rendre-le-web-meilleur/\">Opquast.\u003C/a>\u003C/p>\n\u003Ch3 id=\"sobriété-par-choix\">Sobriété par choix\u003C/h3>\n\u003Cp>Je privilégie le développement de \u003Cstrong>sites statiques\u003C/strong> en adoptant une approche \u003Ca href=\"https://eco-conception.designersethiques.org/guide/fr/\">d’éco-conception numérique.\u003C/a>\u003Cbr>\nC’est-à-dire que le site est pensé pour n’embarquer que les fonctionnalités nécessaires à son utilisation.\u003C/p>\n\u003Cp>Cette approche présente de \u003Cstrong>nombreux avantages :\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>chargement rapide des pages ;\u003C/li>\n\u003Cli>sécurité renforcée ;\u003C/li>\n\u003Cli>coûts serveur réduits ;\u003C/li>\n\u003Cli>maintenance facilitée.\u003C/li>\n\u003C/ul>\n\u003Cp>Lorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l’interface. Cela permet de garantir que \u003Cstrong>le site reste en ligne\u003C/strong> même si le CMS venait à ne plus fonctionner.\u003C/p>",{"headings":83,"imagePaths":94,"frontmatter":95},[84,87,91],{"depth":30,"slug":85,"text":86},"méthodologie","Méthodologie",{"depth":88,"slug":89,"text":90},3,"accessibilité-par-défaut","Accessibilité par défaut",{"depth":88,"slug":92,"text":93},"sobriété-par-choix","Sobriété par choix",[],{"type":14,"uid":73,"lang":15,"image":74,"order":30,"quickTitle":75,"quickImage":76},"030-about",{"id":96,"data":98,"body":103,"filePath":104,"digest":105,"rendered":106},{"type":14,"lang":15,"uid":99,"image":100,"order":88,"quickTitle":101,"quickImage":102},"about","/assets/images/home/about.svg","Moi","/assets/images/home/icon-heart.svg","## À propos\n\n### Formations personnelles\n\nAfin de solidifier mes compétences, j'ai suivi les formations et passé les certifications suivantes :\n\n- [Opquast](https://directory.opquast.com/fr/certificat/CTQSKP/) - Maîtrise de la qualité en projet web ;\n- Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\n\n### Formations des autres\n\nDepuis plusieurs années, j'interviens dans différents campus afin de dispenser des cours de développement web.\n\n### Temps libre\n\nJ’essaie de contribuer à des [projets open source](https://git.nardu.in/explore/repos) qui me tiennent à cœur et je m'engage localement avec le collectif [good-it!](https://www.good-it.org/)\n\nAh et j’écris [des articles](/articles) aussi ! Des articles sur le design, le développement web et l’informatique.","src/data/HP/030-about.md","a7abff6d744406ce",{"html":107,"metadata":108},"\u003Ch2 id=\"à-propos\">À propos\u003C/h2>\n\u003Ch3 id=\"formations-personnelles\">Formations personnelles\u003C/h3>\n\u003Cp>Afin de solidifier mes compétences, j’ai suivi les formations et passé les certifications suivantes :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://directory.opquast.com/fr/certificat/CTQSKP/\">Opquast\u003C/a> - Maîtrise de la qualité en projet web ;\u003C/li>\n\u003Cli>Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"formations-des-autres\">Formations des autres\u003C/h3>\n\u003Cp>Depuis plusieurs années, j’interviens dans différents campus afin de dispenser des cours de développement web.\u003C/p>\n\u003Ch3 id=\"temps-libre\">Temps libre\u003C/h3>\n\u003Cp>J’essaie de contribuer à des \u003Ca href=\"https://git.nardu.in/explore/repos\">projets open source\u003C/a> qui me tiennent à cœur et je m’engage localement avec le collectif \u003Ca href=\"https://www.good-it.org/\">good-it!\u003C/a>\u003C/p>\n\u003Cp>Ah et j’écris \u003Ca href=\"/articles\">des articles\u003C/a> aussi ! Des articles sur le design, le développement web et l’informatique.\u003C/p>",{"headings":109,"imagePaths":122,"frontmatter":123},[110,113,116,119],{"depth":30,"slug":111,"text":112},"à-propos","À propos",{"depth":88,"slug":114,"text":115},"formations-personnelles","Formations personnelles",{"depth":88,"slug":117,"text":118},"formations-des-autres","Formations des autres",{"depth":88,"slug":120,"text":121},"temps-libre","Temps libre",[],{"type":14,"uid":99,"lang":15,"image":100,"order":88,"quickTitle":101,"quickImage":102},"references",["Map",126,127,139,140,21,153,40,163],"3w",{"id":126,"data":128,"filePath":135,"digest":136,"rendered":137},{"title":126,"subtitle":129,"url":130,"lang":15,"slug":126,"tags":131,"createdAt":134},"J'ai fait de la doc!","https://3-w.fr",[132,133],"Front-end","documentation",["Date","2022-10-19T18:02:00.000Z"],"src/content/references/3w.md","0d3d94c8af754e1b",{"html":138},"","natureo",{"id":139,"data":141,"filePath":150,"digest":151,"rendered":152},{"title":142,"subtitle":143,"url":144,"lang":15,"slug":139,"tags":145,"createdAt":149},"Nature en Occitanie","La sobriété au naturel.","https://www.natureo.org/",[132,146,147,148],"accessibilité","éco-conception","CMS",["Date","2023-04-19T18:02:00.000Z"],"src/content/references/natureo.md","6a7169b855b57024",{"html":138},{"id":21,"data":154,"filePath":160,"digest":161,"rendered":162},{"title":155,"subtitle":156,"url":157,"lang":15,"slug":21,"tags":158,"createdAt":159},"Parole Expression","Un nouveau site pour l'association.","https://www.paroleexpression.fr/",[132,147,148],["Date","2022-04-19T17:11:00.000Z"],"src/content/references/parole-expression.md","ec95a408f8c3e99c",{"html":138},{"id":40,"data":164,"filePath":170,"digest":171,"rendered":172},{"title":165,"subtitle":166,"url":167,"lang":15,"slug":40,"tags":168,"createdAt":169},"Rose Primaire","Une agence comme on l'aime.","https://roseprimaire.com/",[132,146,147,148],["Date","2023-04-19T17:11:00.000Z"],"src/content/references/rose-primaire.md","a0133200cf1bee58",{"html":138},"veille",["Map",175,176],"2023",{"id":175,"data":177,"body":179,"filePath":180,"digest":181,"rendered":182},{"lang":15,"title":175,"updatedAt":178},["Date","2023-04-20T17:12:06.000Z"],"- [mmm.page](https://build.mmm.page/) - Éditeur de sites web très simples, en glisser-déposer, pour n'importe quoi.\n- [Color.io](https://www.color.io/) - Éditeur photo en ligne.\n- [Addy's toolkit](https://toolkit.addy.codes/) - Outils et ressources pour les designers et développeurs sites web.\n- [L’accessibilité n’est pas une variable d’ajustement](https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/) — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n > L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\n- [3D en CSS (english)](https://garden.bradwoods.io/notes/css/3d) – Explications et exemples des propriétés 3D en CSS.\n- [Climat : Comment ne pas déprimer ?](https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html) – Podcast.\n- [Fable (english)](https://fable.app) – Application de motion design.\n- [Rive (english)](https://rive.app) – Application de motion design.\n- [Cake Desk](https://cakedesk.app/) – Application de facturation.\n- [Ombre fluide en CSS](https://shadows.brumm.af/) – Générateur.\n- [Smol CSS](https://smolcss.dev/) – Collection de fragments CSS.\n- [Ajustement optique](https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/) (english) – Aligner visuellement plutôt que techniquement.\n- [Datawrapper](https://blog.datawrapper.de/category/datavis-dos-and-donts/) (english) – Conseils pour montrer de la donnée.\n- [Assistivlabs](https://assistivlabs.com/) (english) – Service de test des technologies d'assistance (browserstack mais pour l'accessibilité).\n- [Les caractères fantaisistes et l'accessibilité](https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/) – Explications et exemples de l'enfer que sont les caractères Unicode pour les technologies d'assistance.\n- [Créer un champ `time` sur le web](https://adamsilver.io/blog/designing-a-time-input-backed-by-research/) (english) – Article.\n- [La cascade](https://la-cascade.io) – Collection d'articles sur le CSS.\n- [Tabby](https://tabby.sh) (english) – An alternative terminal app.\n- [Newglyph](https://newglyph.com/) – Fonderie indépendante.\n- [\u003Cspan lang=\"en\">Headless UI\u003C/span>](https://headlessui.com/vue/dialog) (english) – Librairie de composants vue et react.\n- [Vie privée sexy](https://privacy.sexy) (english) – Outils de confidentialité pour windows et macos.\n- [33 concepts JavaScript](https://github.com/leonardomso/33-js-concepts) (english) – Articles.\n- [Formbricks](https://formbricks.com/) (english) – Alternative open source à google form/typeform.\n- [Animations de chargement SVG](https://github.com/n3r4zzurr0/svg-spinners) – Collection.\n- [a11yphant](https://a11yphant.com/) (english) – Challenges de code pour apprendre l'accessibilité.\n- [CSS moderne](https://moderncss.dev/) (english) – Fragments CSS.\n- [Conteneur moderne en CSS](https://twitter.com/KevinJPowell/status/1501555193799925761) (english) – Tweet de Kevin Powell ❤️","src/data/veille/2023.md","1135beec386f207f",{"html":183,"metadata":184},"\u003Cul>\n\u003Cli>\u003Ca href=\"https://build.mmm.page/\">mmm.page\u003C/a> - Éditeur de sites web très simples, en glisser-déposer, pour n’importe quoi.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.color.io/\">Color.io\u003C/a> - Éditeur photo en ligne.\u003C/li>\n\u003Cli>\u003Ca href=\"https://toolkit.addy.codes/\">Addy’s toolkit\u003C/a> - Outils et ressources pour les designers et développeurs sites web.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/\">L’accessibilité n’est pas une variable d’ajustement\u003C/a> — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n\u003Cblockquote>\n\u003Cp>L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\u003C/p>\n\u003C/blockquote>\n\u003C/li>\n\u003Cli>\u003Ca href=\"https://garden.bradwoods.io/notes/css/3d\">3D en CSS (english)\u003C/a> – Explications et exemples des propriétés 3D en CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html\">Climat : Comment ne pas déprimer ?\u003C/a> – Podcast.\u003C/li>\n\u003Cli>\u003Ca href=\"https://fable.app\">Fable (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://rive.app\">Rive (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://cakedesk.app/\">Cake Desk\u003C/a> – Application de facturation.\u003C/li>\n\u003Cli>\u003Ca href=\"https://shadows.brumm.af/\">Ombre fluide en CSS\u003C/a> – Générateur.\u003C/li>\n\u003Cli>\u003Ca href=\"https://smolcss.dev/\">Smol CSS\u003C/a> – Collection de fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/\">Ajustement optique\u003C/a> (english) – Aligner visuellement plutôt que techniquement.\u003C/li>\n\u003Cli>\u003Ca href=\"https://blog.datawrapper.de/category/datavis-dos-and-donts/\">Datawrapper\u003C/a> (english) – Conseils pour montrer de la donnée.\u003C/li>\n\u003Cli>\u003Ca href=\"https://assistivlabs.com/\">Assistivlabs\u003C/a> (english) – Service de test des technologies d’assistance (browserstack mais pour l’accessibilité).\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/\">Les caractères fantaisistes et l’accessibilité\u003C/a> – Explications et exemples de l’enfer que sont les caractères Unicode pour les technologies d’assistance.\u003C/li>\n\u003Cli>\u003Ca href=\"https://adamsilver.io/blog/designing-a-time-input-backed-by-research/\">Créer un champ \u003Ccode>time\u003C/code> sur le web\u003C/a> (english) – Article.\u003C/li>\n\u003Cli>\u003Ca href=\"https://la-cascade.io\">La cascade\u003C/a> – Collection d’articles sur le CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://tabby.sh\">Tabby\u003C/a> (english) – An alternative terminal app.\u003C/li>\n\u003Cli>\u003Ca href=\"https://newglyph.com/\">Newglyph\u003C/a> – Fonderie indépendante.\u003C/li>\n\u003Cli>\u003Ca href=\"https://headlessui.com/vue/dialog\">\u003Cspan lang=\"en\">Headless UI\u003C/span>\u003C/a> (english) – Librairie de composants vue et react.\u003C/li>\n\u003Cli>\u003Ca href=\"https://privacy.sexy\">Vie privée sexy\u003C/a> (english) – Outils de confidentialité pour windows et macos.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/leonardomso/33-js-concepts\">33 concepts JavaScript\u003C/a> (english) – Articles.\u003C/li>\n\u003Cli>\u003Ca href=\"https://formbricks.com/\">Formbricks\u003C/a> (english) – Alternative open source à google form/typeform.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/n3r4zzurr0/svg-spinners\">Animations de chargement SVG\u003C/a> – Collection.\u003C/li>\n\u003Cli>\u003Ca href=\"https://a11yphant.com/\">a11yphant\u003C/a> (english) – Challenges de code pour apprendre l’accessibilité.\u003C/li>\n\u003Cli>\u003Ca href=\"https://moderncss.dev/\">CSS moderne\u003C/a> (english) – Fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/KevinJPowell/status/1501555193799925761\">Conteneur moderne en CSS\u003C/a> (english) – Tweet de Kevin Powell ❤️\u003C/li>\n\u003C/ul>",{"headings":185,"imagePaths":186,"frontmatter":187},[],[],{"lang":15,"title":175,"updatedAt":188},"2023-04-20T17:12:06.000Z","fragments",["Map",191,192,206,207,217,218,273,274,290,291,309,310,319,320,330,331,341,342,354,355,389,390,413,414,455,456,495,496,529,530,593,594],"en-image-full",{"id":191,"data":193,"body":203,"filePath":204,"digest":205,"deferredRender":202},{"title":194,"subtitle":195,"lang":196,"tags":197,"type":199,"slug":191,"createdAt":200,"updatedAt":201,"draft":202},"Full width image","Translation in progress, stay tuned ;)","en",[198],"CSS","snippets",["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],true,"[Go back to available snippets](/en/snippets)","src/content/fragments/en/image-full.mdx","2e3dddf593f6d72f","en-super-cookies",{"id":206,"data":208,"body":214,"filePath":215,"digest":216,"deferredRender":202},{"title":209,"subtitle":210,"lang":196,"tags":211,"type":199,"slug":206,"createdAt":213},"The best cookies","Consentless biscuits.",[212],"food",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 tablespoon of baking powder\n- 3/4 of aquafaba from 400g of chickpea (chickpea water)\n- 125 grams of coconut oil\n- 2 teaspoons of maple syrup\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- if necessary, melt the coconut oil over low heat\n- meanwhile, mix all the dry ingredients\n- add all liquid ingredients (oil, aquafaba, maple syrup)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Non vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 table spoon of baking powder\n- 1 egg\n- 125 grams of melted butter\n- 2 teaspoons of honey\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- melt butter over low heat\n- meanwhile, mix all dry ingredients\n- add all liquid ingredients (melted butter, egg, honey)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Notes\n\nChocolate can be replaced by anything like nuts, raisins, legos... (don't eat legos be reasonable).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='All ingredients mixed together to form a brown paste.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='The cookies are round and soft after baking.'\n/>","src/content/fragments/en/super-cookies.mdx","b0c67adad40c177c","en-toulouse-fun",{"id":217,"data":219,"body":225,"filePath":226,"digest":227,"rendered":228},{"title":220,"subtitle":221,"lang":196,"tags":222,"type":199,"slug":217,"createdAt":224},"Toulouse yourself","Only the bestest",[223],"lifestyle",["Date","2022-06-22T15:34:45.000Z"],"Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite. \n**It's always a good idea to make a reservation!**\n\n## Restaurants\n\n### French cuisine\n\n- [Solides](https://www.solides.fr/) — semi-gastronomic\n- [Les impulsifs](https://les-impulsifs-toulouse.eatbu.com/?lang=en) — semi-gastronomic\n- [Sixta](https://sixta-toulouse.fr/) — vege/vegan/gluten friendly\n- [Attila](https://attila.site-solocal.com/) — great **fish restaurant,** just above the Victor Hugo market\n- [Chez Emile](https://www.restaurant-emile.com/) - best [cassoulet](https://en.wikipedia.org/wiki/Cassoulet) in town (or so I'm told)\n\n### Korean\n\n- [Le ptit Louis](https://leptitlouis.fr/) — best of its kind, **only for lunch**\n- [Kongbap](https://kong-bap.com/) — street-food like\n\n### Japanese\n\n- [Iori](https://www.iori.fr/) — best ramen\n- [Japoyaki](https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402) — best sushi/sashimis\n\n## Drinks and snacks\n\n### Bars\n\n- [Le Bièrographe](https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327) — all time favourite, **check out the typical toulouse basement**\n- [A Taula](https://www.facebook.com/ataulatolosa/) — all time favourite in summer, **amazing terrace,** also: great tapas\n- [The Hopscotch Pub](https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385) — good beers, good whiskies, good cocktials, good food\n\n### Cafés & tea rooms\n\n- [Bapz](https://www.bapz.fr/contact) — Excellent pastries / hot beverages\n- [Ô thé divin](https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/) — nice lunch options\n- [Les Rêveries d’Hercule](https://www.lesreveriesdhercule.com/) — Pottery Café, relaxing activity (ceramics need to be baked, there'll be a delay to get them back)\n- Bonus: the best bakeries in [Carmes](https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872) and [Saint-Aubin](https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694) — croissants, baguettes **traditions**, chocolatines and more\n\n### Wine shops\n\n- [l'envie du sud](https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930) — amazing selection of wines and other spirits, excellent advice from the staff\n- [enoteca](https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952) — smaller selection but more beers and great advice from the staff as well\n\n## Other delights\n\n### Ice creams\n\n- [Forno gusto](https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450) — only in the summer\n- [Moustache](https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540) — lots of flavours\n\n### Cheese shop\n\n- [Xavier](https://xavier.fr/) — one of the **best of the country**, two shops in Toulouse, including one at Victor Hugo market\n- [Massembea](https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490) — a serious contender in Toulouse (weird hours)\n\n### Delicatessen\n\n- [Café Bacquié](http://cafe-bacquie.com/) — stock up on fine foods, coffees, teas and other great quality products","src/content/fragments/en/toulouse-fun.md","370491cc68079e8c",{"html":229,"metadata":230},"\u003Cp>Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite.\u003Cbr>\n\u003Cstrong>It’s always a good idea to make a reservation!\u003C/strong>\u003C/p>\n\u003Ch2 id=\"restaurants\">Restaurants\u003C/h2>\n\u003Ch3 id=\"french-cuisine\">French cuisine\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.solides.fr/\">Solides\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://les-impulsifs-toulouse.eatbu.com/?lang=en\">Les impulsifs\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://sixta-toulouse.fr/\">Sixta\u003C/a> — vege/vegan/gluten friendly\u003C/li>\n\u003Cli>\u003Ca href=\"https://attila.site-solocal.com/\">Attila\u003C/a> — great \u003Cstrong>fish restaurant,\u003C/strong> just above the Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.restaurant-emile.com/\">Chez Emile\u003C/a> - best \u003Ca href=\"https://en.wikipedia.org/wiki/Cassoulet\">cassoulet\u003C/a> in town (or so I’m told)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"korean\">Korean\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://leptitlouis.fr/\">Le ptit Louis\u003C/a> — best of its kind, \u003Cstrong>only for lunch\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://kong-bap.com/\">Kongbap\u003C/a> — street-food like\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"japanese\">Japanese\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.iori.fr/\">Iori\u003C/a> — best ramen\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402\">Japoyaki\u003C/a> — best sushi/sashimis\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"drinks-and-snacks\">Drinks and snacks\u003C/h2>\n\u003Ch3 id=\"bars\">Bars\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327\">Le Bièrographe\u003C/a> — all time favourite, \u003Cstrong>check out the typical toulouse basement\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.facebook.com/ataulatolosa/\">A Taula\u003C/a> — all time favourite in summer, \u003Cstrong>amazing terrace,\u003C/strong> also: great tapas\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385\">The Hopscotch Pub\u003C/a> — good beers, good whiskies, good cocktials, good food\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cafés--tea-rooms\">Cafés & tea rooms\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.bapz.fr/contact\">Bapz\u003C/a> — Excellent pastries / hot beverages\u003C/li>\n\u003Cli>\u003Ca href=\"https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/\">Ô thé divin\u003C/a> — nice lunch options\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lesreveriesdhercule.com/\">Les Rêveries d’Hercule\u003C/a> — Pottery Café, relaxing activity (ceramics need to be baked, there’ll be a delay to get them back)\u003C/li>\n\u003Cli>Bonus: the best bakeries in \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872\">Carmes\u003C/a> and \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694\">Saint-Aubin\u003C/a> — croissants, baguettes \u003Cstrong>traditions\u003C/strong>, chocolatines and more\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"wine-shops\">Wine shops\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930\">l’envie du sud\u003C/a> — amazing selection of wines and other spirits, excellent advice from the staff\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952\">enoteca\u003C/a> — smaller selection but more beers and great advice from the staff as well\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"other-delights\">Other delights\u003C/h2>\n\u003Ch3 id=\"ice-creams\">Ice creams\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450\">Forno gusto\u003C/a> — only in the summer\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540\">Moustache\u003C/a> — lots of flavours\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cheese-shop\">Cheese shop\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://xavier.fr/\">Xavier\u003C/a> — one of the \u003Cstrong>best of the country\u003C/strong>, two shops in Toulouse, including one at Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490\">Massembea\u003C/a> — a serious contender in Toulouse (weird hours)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"delicatessen\">Delicatessen\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"http://cafe-bacquie.com/\">Café Bacquié\u003C/a> — stock up on fine foods, coffees, teas and other great quality products\u003C/li>\n\u003C/ul>",{"headings":231,"imagePaths":268,"frontmatter":269},[232,235,238,241,244,247,250,253,256,259,262,265],{"depth":30,"slug":233,"text":234},"restaurants","Restaurants",{"depth":88,"slug":236,"text":237},"french-cuisine","French cuisine",{"depth":88,"slug":239,"text":240},"korean","Korean",{"depth":88,"slug":242,"text":243},"japanese","Japanese",{"depth":30,"slug":245,"text":246},"drinks-and-snacks","Drinks and snacks",{"depth":88,"slug":248,"text":249},"bars","Bars",{"depth":88,"slug":251,"text":252},"cafés--tea-rooms","Cafés & tea rooms",{"depth":88,"slug":254,"text":255},"wine-shops","Wine shops",{"depth":30,"slug":257,"text":258},"other-delights","Other delights",{"depth":88,"slug":260,"text":261},"ice-creams","Ice creams",{"depth":88,"slug":263,"text":264},"cheese-shop","Cheese shop",{"depth":88,"slug":266,"text":267},"delicatessen","Delicatessen",[],{"title":220,"subtitle":221,"lang":196,"slug":217,"excerpt":270,"tags":271,"type":199,"createdAt":272},"Gonna have to trust me on this ¯\\_(ツ)_/¯",[223],"2022-06-22T15:34:45.000Z","en-visited-links",{"id":273,"data":275,"body":203,"filePath":279,"digest":280,"rendered":281},{"title":276,"subtitle":195,"lang":196,"tags":277,"type":199,"slug":273,"createdAt":278,"draft":202},"Visited links and visuel aid",[132],["Date","2023-06-06T18:34:00.000Z"],"src/content/fragments/en/visited-links.md","cb7c11c12c25067e",{"html":282,"metadata":283},"\u003Cp>\u003Ca href=\"/en/snippets\">Go back to available snippets\u003C/a>\u003C/p>",{"headings":284,"imagePaths":285,"frontmatter":286},[],[],{"title":276,"subtitle":195,"lang":196,"draft":202,"slug":273,"excerpt":287,"tags":288,"type":199,"createdAt":289},"Petit hack CSS",[132],"2023-06-06T18:34:00.000Z","array-vs-array",{"id":290,"data":292,"body":298,"filePath":299,"digest":300,"rendered":301},{"title":293,"subtitle":294,"lang":15,"tags":295,"type":189,"slug":290,"createdAt":297,"draft":202},"Filtrer un array avec un autre array","En cours de traduction.",[296],"nuxt.js",["Date","2022-06-08T14:24:06.000Z"],"[Voir les fragments disponibles](/fragments)","src/content/fragments/fr/array-vs-array.md","7321d444177c3841",{"html":302,"metadata":303},"\u003Cp>\u003Ca href=\"/fragments\">Voir les fragments disponibles\u003C/a>\u003C/p>",{"headings":304,"imagePaths":305,"frontmatter":306},[],[],{"title":293,"subtitle":294,"lang":15,"draft":202,"slug":290,"createdAt":307,"excerpt":294,"tags":308,"type":189},"2022-06-08T14:24:06.000Z",[296],"buttons",{"id":309,"data":311,"body":316,"filePath":317,"digest":318,"deferredRender":202},{"title":312,"subtitle":313,"lang":15,"tags":314,"type":189,"slug":309,"createdAt":315,"code":202,"draft":202},"Effets de survol de boutons","Simples mais efficaces.",[198],["Date","2020-10-08T09:00:00.000Z"],"## Styles généraux\n\nTous les boutons présents utilisent ces styles comme base en guise de « reset » :\n\n> N'oubliez pas de préfixer si besoin !\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Ajout d'icône\n\n\u003Cbutton role='none' class='btn btn-icon'>\n\t\u003Cspan>Icône\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('./assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double volet\n\n\u003Cbutton role='none' class='btn btn-rideau'>\n\t\u003Cspan>Volet\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Dégradé animé\n\n\u003Cbutton role='none' class='btn btn-gradient'>\n\t\u003Cspan>Dégradé\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Échelle non desctructrice\n\n\u003Cbutton role='none' class='btn btn-scale'>\n\t\u003Cspan>Échelle\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/fr/buttons.mdx","f5d7b03520f96b04","image-full",{"id":319,"data":321,"body":327,"filePath":328,"digest":329,"deferredRender":202},{"title":322,"subtitle":323,"lang":15,"tags":324,"type":189,"slug":319,"createdAt":325,"updatedAt":326},"Image pleine largeur","Casser le conteneur.",[198],["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Image inline\n\nOn est parfois obligé d'utiliser des images dans des balises `img` plutôt que dans un `background` en css. Comment faire alors pour que l'image sorte de son conteneur pour en faire une bannière ? Exemple pratique à partir de ce même site.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_container_9e3939b3ae.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Contexte\n\nConsidérons le html suivant :\n\n```html\n\u003C!-- index.html -->\n\u003Csection class=\"container\">\n\t\u003Cdiv class=\"hero\">\n\t\t\u003Cimg class=\"hero__image\" src=\"hero.img\" />\n\t\u003C/div>\n\u003C/section>\n```\n\nEt le style suivant :\n\n```css\n/* style.css */\n.container {\n\tpadding: 0 14px;\n\tmargin-inline: auto;\n\tmax-inline-size: 1040px;\n}\nimg {\n\tmax-inline-size: 100%;\n\tblock-size: auto;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_original_d49f0d11bf.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Déborder du conteneur\n\nAfin de faire prendre à l'image toute la largeur, on agit sur son conteneur :\n\n```css\n/* style.css */\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_full_2a902f9539.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Faire une bannière\n\nOn peut alors réduire la hauteur du conteneur pour obtenir une bannière plutôt que l'image entière et faire correspondre la hauteur de l'image à la hauteur du conteneur :\n\n```css title='style.css' ins={5, 7-9}\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n\tblock-size: 200px;\n}\n.hero__image {\n\tblock-size: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_height_81b4ce969a.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nIl faut ensuite forcer l'image à prendre toute la largeur du conteneur :\n\n```css title='style.css' ins={3}\n.hero__image {\n\tblock-size: 100%;\n\tinline-size: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_deformed_479046d2cb.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nPas top…\n\n### J'ai cassé l'image…\n\n**ENFIN** le code magique pour redonner son ratio à l'image sans la déformer :\n\n```css title='style.css' ins={4,5}\n.hero__image {\n\tblock-size: 100%;\n\tinline-size: 100%;\n\tobject-fit: cover;\n\tobject-position: center; /* à positionner comme on veut */\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_6c164e82b3.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nCette technique s'apparente à l'utilisation d'une image de background.\n\n## TL;DR\n\nLe code complet :\n\n```css\n/* style.css */\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n\tblock-size: 200px;\n}\n.hero__image {\n\tinline-size: 100%;\n\tblock-size: 100%;\n\t-o-object-fit: cover;\n\tobject-fit: cover;\n\t-o-object-position: center;\n\tobject-position: center;\n}\n```","src/content/fragments/fr/image-full.mdx","585dcfae92fb08fb","super-cookies",{"id":330,"data":332,"body":338,"filePath":339,"digest":340,"deferredRender":202},{"title":333,"subtitle":334,"lang":15,"tags":335,"type":189,"slug":330,"createdAt":337},"Les meilleurs cookies","Des gâteaux sans consentement.",[336],"cuisine",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Version végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 3/4 de l'aquafaba de 400g de pois chiche (l'eau des pois chiche)\n- 125 grammes d'huile de noix de coco\n- 2 cuillères à café de sirop d'érable\n- 1 plaquette de chocolat (noir) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre si besoin l'huile de noix de coco à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (huile, aquafaba, sirop d'érable)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Version non végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 1 œuf\n- 125 grammes de beurre fondu\n- 2 cuillères à café de miel\n- 1 plaquette de chocolat (noir/blanc/les deux) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre le beurre à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (beurre fondu, œuf, miel)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Notes\n\nLe chocolat peut-être remplacé par n'importe quoi comme des noix, des raisins secs, des légos… (mangez pas des légos soyez sérieux).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Tous les ingrédients mélangés forment une pâte marron.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Les cookies cuits sont bombés et très moelleux.'\n/>","src/content/fragments/fr/super-cookies.mdx","f7a802e0b68cb04a","toulouse-fun",{"id":341,"data":343,"body":298,"filePath":346,"digest":347,"rendered":348},{"title":220,"subtitle":294,"lang":15,"tags":344,"type":189,"slug":341,"createdAt":345,"draft":202},[223],["Date","2022-06-22T15:34:45.000Z"],"src/content/fragments/fr/toulouse-fun.md","a0c25b438b34c05e",{"html":302,"metadata":349},{"headings":350,"imagePaths":351,"frontmatter":352},[],[],{"title":220,"subtitle":294,"lang":15,"draft":202,"slug":341,"createdAt":272,"excerpt":294,"tags":353,"type":189},[223],"visited-links",{"id":354,"data":356,"body":362,"filePath":363,"digest":364,"rendered":365},{"title":357,"subtitle":358,"lang":15,"tags":359,"type":199,"slug":354,"createdAt":360,"draft":361},"Liens visités et indication visuelle","Comment différencier les liens déjà cliqués",[132],["Date","2023-06-06T18:34:00.000Z"],false,"## La théorie\n\nIl est possible sur le web d'appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu'un lien visité est violet.\n\nGénéralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L'information qu'un lien a déjà été visité ne semble pas indispensable à la navigation. C'est sûrement vrai, mais personnellement, je suis assez content d'avoir un rappel des pages que j'ai déjà consultées lorsque je navigue.\n\nUne information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J'ai alors cherché un moyen d'ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n'est certainement pas idéale, elle se rapproche plus d'une expérience, à priori inoffensive pour l'internaute.\n\n## La spécification\n\nQuand je me suis intéressé à ce qu'il était possible de faire avec les liens déjà visités, j'ai découvert qu'extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu'il était possible de récupérer l'historique de navigation d'un utilisateur grâce aux styles des liens visités. Le sélecteur `:visited` a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. [Plus d'informations dans cet article.](https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector)\n\n## La pratique\n\nQue faire alors, en terme de style, quand on ne peut changer que des couleurs ?\n\nD'après MDN, les propriétés suivantes sont modifiables :\n\n- `color`\n- `background-color`\n- `border-color` (et les propriétés détaillées associées),\n- `column-rule-color`\n- `outline-color`\n- `text-decoration-color`\n- `text-emphasis-color`\n- Les composantes de couleur liées aux attributs SVG `fill` et `stroke`.\n\nChanger la couleur d'un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\n\nEn revanche, il est possible de \" masquer \" un élément en modifiant sa couleur pour qu'elle corresponde à la couleur du fond de la page ou de l'élément parent. On pourrait ainsi imaginer masquer une `border` ou un `outline`.\n\nJ'ai personnellement choisi de faire différemment. J'ai décidé d'utiliser un pseudo-élément `::before` sur l'état non visité du lien puis de le masquer quand celui-ci devient visité.\n\n### Le code\n\n```css {5,16} title=\"style.css\"\na {\n\tposition: relative;\n\ttext-decoration: none;\n}\na::before {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 0;\n\tinline-size: 2px;\n\tblock-size: 2px;\n\tborder-radius: 4px;\n\ttransform: translate(-6px, 0);\n\tbackground-color: grey;\n}\na:visited::before {\n\tbackground-color: white;\n}\n```\n\nCes règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\n\n### Accessibilité\n\nOn pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété `content` mais les lecteurs d'écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d'écrans annoncent déjà si un lien est visité avant de lire son intitulé.\n\n## Aller plus loin\n\nAfin de pousser l'expérience un peu plus loin, j'ai tenté d'utiliser des éléments plus explicites pour signifier l'état visité du lien. Bien qu'encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\n\nL'idée est d'avoir un `::before` et un `::after`, chacun contenant une icône en base 64 blanche en tant qu'image de fond. Quand le lien est non visité, le `::before` contient un fond coloré qui fait apparaître l'icône. Quand le lien passe en visité, le fond du `::before` devient blanc et celui du `::after` devient coloré, ce qui masque la première icône et affiche la deuxième.\n\nIl est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l'une sur l'autre.\n\n[Voir la démo sur codepen.](https://codepen.io/narduin/pen/VwVwmrO)","src/content/fragments/fr/visited-links.md","c062a565e4c30dfe",{"html":366,"metadata":367},"\u003Ch2 id=\"la-théorie\">La théorie\u003C/h2>\n\u003Cp>Il est possible sur le web d’appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu’un lien visité est violet.\u003C/p>\n\u003Cp>Généralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L’information qu’un lien a déjà été visité ne semble pas indispensable à la navigation. C’est sûrement vrai, mais personnellement, je suis assez content d’avoir un rappel des pages que j’ai déjà consultées lorsque je navigue.\u003C/p>\n\u003Cp>Une information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J’ai alors cherché un moyen d’ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n’est certainement pas idéale, elle se rapproche plus d’une expérience, à priori inoffensive pour l’internaute.\u003C/p>\n\u003Ch2 id=\"la-spécification\">La spécification\u003C/h2>\n\u003Cp>Quand je me suis intéressé à ce qu’il était possible de faire avec les liens déjà visités, j’ai découvert qu’extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu’il était possible de récupérer l’historique de navigation d’un utilisateur grâce aux styles des liens visités. Le sélecteur \u003Ccode>:visited\u003C/code> a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector\">Plus d’informations dans cet article.\u003C/a>\u003C/p>\n\u003Ch2 id=\"la-pratique\">La pratique\u003C/h2>\n\u003Cp>Que faire alors, en terme de style, quand on ne peut changer que des couleurs ?\u003C/p>\n\u003Cp>D’après MDN, les propriétés suivantes sont modifiables :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>background-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>border-color\u003C/code> (et les propriétés détaillées associées),\u003C/li>\n\u003Cli>\u003Ccode>column-rule-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>outline-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-decoration-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-emphasis-color\u003C/code>\u003C/li>\n\u003Cli>Les composantes de couleur liées aux attributs SVG \u003Ccode>fill\u003C/code> et \u003Ccode>stroke\u003C/code>.\u003C/li>\n\u003C/ul>\n\u003Cp>Changer la couleur d’un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\u003C/p>\n\u003Cp>En revanche, il est possible de ” masquer ” un élément en modifiant sa couleur pour qu’elle corresponde à la couleur du fond de la page ou de l’élément parent. On pourrait ainsi imaginer masquer une \u003Ccode>border\u003C/code> ou un \u003Ccode>outline\u003C/code>.\u003C/p>\n\u003Cp>J’ai personnellement choisi de faire différemment. J’ai décidé d’utiliser un pseudo-élément \u003Ccode>::before\u003C/code> sur l’état non visité du lien puis de le masquer quand celui-ci devient visité.\u003C/p>\n\u003Ch3 id=\"le-code\">Le code\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">style.css\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">relative\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-decoration: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line highlight mark\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#eca3a8\">a\u003C/span>\u003Cspan style=\"--0:#73c3cc\">::before\u003C/span>\u003Cspan style=\"--0:#b0b6c3\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">inline-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">block-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">4\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-6\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: grey;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line highlight mark\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#eca3a8\">a\u003C/span>\u003Cspan style=\"--0:#73c3cc\">:visited::before\u003C/span>\u003Cspan style=\"--0:#b0b6c3\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"a { position: relative; text-decoration: none;}a::before { content: ''; position: absolute; top: 50%; left: 0; inline-size: 2px; block-size: 2px; border-radius: 4px; transform: translate(-6px, 0); background-color: grey;}a:visited::before { background-color: white;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Ces règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\u003C/p>\n\u003Ch3 id=\"accessibilité\">Accessibilité\u003C/h3>\n\u003Cp>On pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété \u003Ccode>content\u003C/code> mais les lecteurs d’écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d’écrans annoncent déjà si un lien est visité avant de lire son intitulé.\u003C/p>\n\u003Ch2 id=\"aller-plus-loin\">Aller plus loin\u003C/h2>\n\u003Cp>Afin de pousser l’expérience un peu plus loin, j’ai tenté d’utiliser des éléments plus explicites pour signifier l’état visité du lien. Bien qu’encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\u003C/p>\n\u003Cp>L’idée est d’avoir un \u003Ccode>::before\u003C/code> et un \u003Ccode>::after\u003C/code>, chacun contenant une icône en base 64 blanche en tant qu’image de fond. Quand le lien est non visité, le \u003Ccode>::before\u003C/code> contient un fond coloré qui fait apparaître l’icône. Quand le lien passe en visité, le fond du \u003Ccode>::before\u003C/code> devient blanc et celui du \u003Ccode>::after\u003C/code> devient coloré, ce qui masque la première icône et affiche la deuxième.\u003C/p>\n\u003Cp>Il est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l’une sur l’autre.\u003C/p>\n\u003Cp>\u003Ca href=\"https://codepen.io/narduin/pen/VwVwmrO\">Voir la démo sur codepen.\u003C/a>\u003C/p>",{"headings":368,"imagePaths":386,"frontmatter":387},[369,372,375,378,381,383],{"depth":30,"slug":370,"text":371},"la-théorie","La théorie",{"depth":30,"slug":373,"text":374},"la-spécification","La spécification",{"depth":30,"slug":376,"text":377},"la-pratique","La pratique",{"depth":88,"slug":379,"text":380},"le-code","Le code",{"depth":88,"slug":146,"text":382},"Accessibilité",{"depth":30,"slug":384,"text":385},"aller-plus-loin","Aller plus loin",[],{"title":357,"subtitle":358,"lang":15,"draft":361,"slug":354,"excerpt":287,"tags":388,"type":199,"createdAt":289},[132],"en-array-vs-array",{"id":389,"data":391,"body":396,"filePath":397,"digest":398,"rendered":399},{"title":392,"subtitle":393,"lang":196,"tags":394,"type":199,"slug":389,"createdAt":395},"Filter an array against another array","Array vs Array.",[296],["Date","2022-06-08T14:24:06.000Z"],"## Context\n\nFor a project, I had to come up with a way to filter an array of objects based on another array of strings.\n\nIn other words, I needed to include every object which `user` property was found in the second array.\n\nHere is an example:\n\n```javascript\nconst skills = [\n\t{\n\t\tname: 'Be awesome',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Great jokes',\n\t\tuser: 'Jacques'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Beatriz'\n\t}\n]\n\nconst selectedUsers = ['Jean', 'Beatriz']\n```\n\nI thought it would be pretty easy but I guess I'm not familiar enough with javascript 😬\n\n## My solution\n\nAfter a bit of thinking, I came up with the following statement:\n\n> I need to filter the skills based on which users are selected. So I need to loop over the `selectedUsers` array and filter the skills according to their `user` value.\n\nAfter a bit more trials and errors, this is the code I ended up using in a `computed property`:\n\n```javascript\n// index.vue\nconst filteredSkills = selectedUsers.map((user) => {\n\treturn skills.filter((skill) => {\n\t\treturn skill.user === user\n\t})\n})\n```\n\nI used `map()` in order to loop on the second array and used its string value to only include the corresponding skills with `filter()`.\n\nI'm pretty sure there is a better way to do it though…","src/content/fragments/en/array-vs-array.md","c63ba57b1049cf4c",{"html":400,"metadata":401},"\u003Ch2 id=\"context\">Context\u003C/h2>\n\u003Cp>For a project, I had to come up with a way to filter an array of objects based on another array of strings.\u003C/p>\n\u003Cp>In other words, I needed to include every object which \u003Ccode>user\u003C/code> property was found in the second array.\u003C/p>\n\u003Cp>Here is an example:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Be awesome'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Great jokes'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jacques'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Beatriz'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">selectedUsers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> [\u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#98C379\">'Beatriz'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const skills = [ { name: 'Be awesome', user: 'Jean' }, { name: 'Great jokes', user: 'Jacques' }, { name: 'Heavy sleeper', user: 'Jean' }, { name: 'Heavy sleeper', user: 'Beatriz' }]const selectedUsers = ['Jean', 'Beatriz']\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>I thought it would be pretty easy but I guess I’m not familiar enough with javascript 😬\u003C/p>\n\u003Ch2 id=\"my-solution\">My solution\u003C/h2>\n\u003Cp>After a bit of thinking, I came up with the following statement:\u003C/p>\n\u003Cblockquote>\n\u003Cp>I need to filter the skills based on which users are selected. So I need to loop over the \u003Ccode>selectedUsers\u003C/code> array and filter the skills according to their \u003Ccode>user\u003C/code> value.\u003C/p>\n\u003C/blockquote>\n\u003Cp>After a bit more trials and errors, this is the code I ended up using in a \u003Ccode>computed property\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">filteredSkills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">selectedUsers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">map\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">((\u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) \u003C/span>\u003Cspan style=\"--0:#CD89E1\">=>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">filter\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">((\u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">skill\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) \u003C/span>\u003Cspan style=\"--0:#CD89E1\">=>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skill\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">===\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const filteredSkills = selectedUsers.map((user) => { return skills.filter((skill) => { return skill.user === user })})\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>I used \u003Ccode>map()\u003C/code> in order to loop on the second array and used its string value to only include the corresponding skills with \u003Ccode>filter()\u003C/code>.\u003C/p>\n\u003Cp>I’m pretty sure there is a better way to do it though…\u003C/p>",{"headings":402,"imagePaths":409,"frontmatter":410},[403,406],{"depth":30,"slug":404,"text":405},"context","Context",{"depth":30,"slug":407,"text":408},"my-solution","My solution",[],{"title":392,"subtitle":393,"lang":196,"slug":389,"createdAt":307,"excerpt":411,"tags":412,"type":199},"My peak javascript",[296],"en-nuxt-graphql-static",{"id":413,"data":415,"body":421,"filePath":422,"digest":423,"rendered":424},{"title":416,"subtitle":417,"lang":196,"tags":418,"type":199,"slug":413,"createdAt":419,"updatedAt":420},"Static website and GraphQL queries with Nuxt.js","Graphql client is king.",[296],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## The problem\n\nI encountered a nasty bug while using static generation with Nuxt and [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (new tab)') client.\nI found [the issue](https://github.com/nuxt-community/apollo-module/issues/339 'Github issue on nuxt/apollo repository (new tab)') already reported on github.\n\nIt seems the module doesn't handle static generation correctly with `nuxt generate`.\n\nI could find request to my local API url after the static generation. Moreover, it also seemed like `\u003Cnuxt-link>` navigation was broken.\n\n## The solution 🙌\n\nFortunately, there is another Nuxt module that handles GraphQL requests!\n\n[Nuxt graphql request to the rescue!](https://github.com/gomah/nuxt-graphql-request)\n\n### The conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### The request\n\nThe best approach so far is to use `asyncData` in pages and `fetch` in components. Using `fetch` in pages does not work well at all with `nuxt generate`.\n\nI also install the `graphql-tag` package (only in `devDependencies`) to be able to import directly `.gql` files.\n\nQuery example:\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Inside a page\n\n```vue\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n\tasync asyncData({ $graphql }) {\n\t\tconst data = await $graphql.default.request(homepageQuery)\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```\n\n#### Inside a component\n\nIt is safer to wait until `fetch` has received a response before displaying anything. You can use `$fetchState` to be sure ([documentation](https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation on the fetch hook (new tab)')).\n\n```vue\n// Header.vue\n\u003Ctemplate>\n\t\u003Cheader v-if=\"!$fetchState.pending\">…\u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tdata: {}\n\t\t}\n\t},\n\tasync fetch() {\n\t\ttry {\n\t\t\tconst data = await this.$graphql.default.request(headerQuery)\n\t\t\tthis.data = data\n\t\t} catch (error) {\n\t\t\tconsole.error(JSON.stringify(error, undefined, 2))\n\t\t}\n\t}\n}\n\u003C/script>\n```\n\n### Options\n\nTo pass options to the request, for example for a multilingual version with [nuxt/i18n](https://i18n.nuxtjs.org/) and/or a url parameter in a dynamic page:\n\n```vue\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n\tasync asyncData({ $graphql, app, params }) {\n\t\tconst locale = app.i18n.localeProperties.iso\n\t\tconst data = await $graphql.default.request(articleQuery, {\n\t\t\tcode: locale,\n\t\t\tslug: params.slug\n\t\t})\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```","src/content/fragments/en/nuxt-graphql-static.md","c5d4f0dd6ca0e1c2",{"html":425,"metadata":426},"\u003Ch2 id=\"the-problem\">The problem\u003C/h2>\n\u003Cp>I encountered a nasty bug while using static generation with Nuxt and \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (new tab)\">nuxt apollo\u003C/a> client.\nI found \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Github issue on nuxt/apollo repository (new tab)\">the issue\u003C/a> already reported on github.\u003C/p>\n\u003Cp>It seems the module doesn’t handle static generation correctly with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I could find request to my local API url after the static generation. Moreover, it also seemed like \u003Ccode><nuxt-link>\u003C/code> navigation was broken.\u003C/p>\n\u003Ch2 id=\"the-solution\">The solution 🙌\u003C/h2>\n\u003Cp>Fortunately, there is another Nuxt module that handles GraphQL requests!\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\">Nuxt graphql request to the rescue!\u003C/a>\u003C/p>\n\u003Ch3 id=\"the-conf\">The conf\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">nuxt.config.js\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">buildModules\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">clients\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">endpoint\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">options\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">authorization\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"buildModules: [ 'nuxt-graphql-request',],graphql: { clients: { default: { endpoint: 'http://API_URL/graphql', options: { headers: { authorization: 'Bearer API_TOKEN', }, }, }, },},\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"the-request\">The request\u003C/h3>\n\u003Cp>The best approach so far is to use \u003Ccode>asyncData\u003C/code> in pages and \u003Ccode>fetch\u003C/code> in components. Using \u003Ccode>fetch\u003C/code> in pages does not work well at all with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I also install the \u003Ccode>graphql-tag\u003C/code> package (only in \u003Ccode>devDependencies\u003C/code>) to be able to import directly \u003Ccode>.gql\u003C/code> files.\u003C/p>\n\u003Cp>Query example:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">homepage.gql\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"graphql\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">query\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepage\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">subtitle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">hero\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">id\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">alt\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"query { homepage { title subtitle hero { id alt } }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"inside-a-page\">Inside a page\u003C/h4>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/homepage'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import homepageQuery from '~/graphql/queries/singles/homepage'export default { async asyncData({ $graphql }) { const data = await $graphql.default.request(homepageQuery) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"inside-a-component\">Inside a component\u003C/h4>\n\u003Cp>It is safer to wait until \u003Ccode>fetch\u003C/code> has received a response before displaying anything. You can use \u003Ccode>$fetchState\u003C/code> to be sure (\u003Ca href=\"https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation on the fetch hook (new tab)\">documentation\u003C/a>).\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">Header.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">v-if\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#56B6C2\">!\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$fetchState\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">pending\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>…</\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/header'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">fetch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">try\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">} \u003C/span>\u003Cspan style=\"--0:#CD89E1\">catch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> (\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">console\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E5C07B\">JSON\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">stringify\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">undefined\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">))\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ctemplate> \u003Cheader v-if="!$fetchState.pending">…\u003C/header>\u003C/template>\u003Cscript>import headerQuery from '~/graphql/queries/singles/header'export default { data() { return { data: {} } }, async fetch() { try { const data = await this.$graphql.default.request(headerQuery) this.data = data } catch (error) { console.error(JSON.stringify(error, undefined, 2)) } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"options\">Options\u003C/h3>\n\u003Cp>To pass options to the request, for example for a multilingual version with \u003Ca href=\"https://i18n.nuxtjs.org/\">nuxt/i18n\u003C/a> and/or a url parameter in a dynamic page:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">_slug.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/articles'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">i18n\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">localeProperties\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">iso\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">code\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E6888F\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E5C07B\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import articleQuery from '~/graphql/queries/articles'export default { async asyncData({ $graphql, app, params }) { const locale = app.i18n.localeProperties.iso const data = await $graphql.default.request(articleQuery, { code: locale, slug: params.slug }) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":427,"imagePaths":450,"frontmatter":451},[428,431,434,437,440,444,447],{"depth":30,"slug":429,"text":430},"the-problem","The problem",{"depth":30,"slug":432,"text":433},"the-solution","The solution 🙌",{"depth":88,"slug":435,"text":436},"the-conf","The conf",{"depth":88,"slug":438,"text":439},"the-request","The request",{"depth":441,"slug":442,"text":443},4,"inside-a-page","Inside a page",{"depth":441,"slug":445,"text":446},"inside-a-component","Inside a component",{"depth":88,"slug":448,"text":449},"options","Options",[],{"title":416,"subtitle":417,"lang":196,"slug":413,"createdAt":307,"updatedAt":452,"excerpt":453,"tags":454,"type":199},"2022-09-08T13:43:33.000Z","When the most used gql module doesn't work…",[296],"nuxt-graphql-static",{"id":455,"data":457,"body":463,"filePath":464,"digest":465,"rendered":466},{"title":458,"subtitle":459,"lang":15,"tags":460,"type":189,"slug":455,"createdAt":461,"updatedAt":462},"Site statique et requêtes GraphQL avec Nuxt.js","Le client graphql est roi.",[296],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## Le problème\n\nJe me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (nouvel onglet)').\nAprès quelques recherches, voici [le bug constaté par quelqu'un d'autre](https://github.com/nuxt-community/apollo-module/issues/339 'Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)') sur github.\n\nIl semblerait que le module en l'état ne gère pas correctement la génération statique avec `nuxt generate`.\n\nJe trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les `\u003Cnuxt-link>` ne fonctionnait pas.\n\n## La solution 🙌\n\nHeureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\n\n[Nuxt graphql request à la rescousse !](https://github.com/gomah/nuxt-graphql-request 'Dépôt github du module (nouvel onglet)')\n\n### La conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### La requête\n\nLa meilleure méthode à ce jour est d'utiliser `asyncData` dans les pages et `fetch` dans les composants. Utiliser `fetch` dans les pages ne fonctionne pas bien du tout avec `nuxt generate`.\n\nJ'installe également le paquet `graphql-tag` (uniquement en `devDependencies`) afin de pouvoir importer directement des fichiers `.gql`\n\nExemple de fichier :\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Dans une page\n\n```vue\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n\tasync asyncData({ $graphql }) {\n\t\tconst data = await $graphql.default.request(homepageQuery)\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```\n\n#### Dans un composant\n\nIl est plus prudent d'attendre que `fetch` ait reçu une réponse avant d'afficher quoi que ce soit. On peut utiliser `$fetchState` afin d'être tranquille ([documentation](https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation sur la méthode fetch (nouvel onglet)')).\n\n```vue\n// Header.vue\n\u003Ctemplate>\n\t\u003Cheader v-if=\"!$fetchState.pending\">…\u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tdata: {}\n\t\t}\n\t},\n\tasync fetch() {\n\t\ttry {\n\t\t\tconst data = await this.$graphql.default.request(headerQuery)\n\t\t\tthis.data = data\n\t\t} catch (error) {\n\t\t\tconsole.error(JSON.stringify(error, undefined, 2))\n\t\t}\n\t}\n}\n\u003C/script>\n```\n\n### Les options\n\nPour passer des options à la requête, par exemple pour une version multilingue avec [nuxt/i18n](https://i18n.nuxtjs.org/ 'Documentation de nuxt i18n (nouvel onglet)') et/ou un paramètre d'url dans le cadre d'une page dynamique :\n\n```vue\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n\tasync asyncData({ $graphql, app, params }) {\n\t\tconst locale = app.i18n.localeProperties.iso\n\t\tconst data = await $graphql.default.request(articleQuery, {\n\t\t\tcode: locale,\n\t\t\tslug: params.slug\n\t\t})\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```","src/content/fragments/fr/nuxt-graphql-static.md","6304f174b83f0078",{"html":467,"metadata":468},"\u003Ch2 id=\"le-problème\">Le problème\u003C/h2>\n\u003Cp>Je me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (nouvel onglet)\">nuxt apollo\u003C/a>.\nAprès quelques recherches, voici \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)\">le bug constaté par quelqu’un d’autre\u003C/a> sur github.\u003C/p>\n\u003Cp>Il semblerait que le module en l’état ne gère pas correctement la génération statique avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>Je trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les \u003Ccode><nuxt-link>\u003C/code> ne fonctionnait pas.\u003C/p>\n\u003Ch2 id=\"la-solution\">La solution 🙌\u003C/h2>\n\u003Cp>Heureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\" title=\"Dépôt github du module (nouvel onglet)\">Nuxt graphql request à la rescousse !\u003C/a>\u003C/p>\n\u003Ch3 id=\"la-conf\">La conf\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">nuxt.config.js\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">buildModules\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">clients\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">endpoint\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">options\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">authorization\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"buildModules: [ 'nuxt-graphql-request',],graphql: { clients: { default: { endpoint: 'http://API_URL/graphql', options: { headers: { authorization: 'Bearer API_TOKEN', }, }, }, },},\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"la-requête\">La requête\u003C/h3>\n\u003Cp>La meilleure méthode à ce jour est d’utiliser \u003Ccode>asyncData\u003C/code> dans les pages et \u003Ccode>fetch\u003C/code> dans les composants. Utiliser \u003Ccode>fetch\u003C/code> dans les pages ne fonctionne pas bien du tout avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>J’installe également le paquet \u003Ccode>graphql-tag\u003C/code> (uniquement en \u003Ccode>devDependencies\u003C/code>) afin de pouvoir importer directement des fichiers \u003Ccode>.gql\u003C/code>\u003C/p>\n\u003Cp>Exemple de fichier :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">homepage.gql\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"graphql\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">query\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepage\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">subtitle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">hero\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">id\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">alt\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"query { homepage { title subtitle hero { id alt } }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"dans-une-page\">Dans une page\u003C/h4>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/homepage'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import homepageQuery from '~/graphql/queries/singles/homepage'export default { async asyncData({ $graphql }) { const data = await $graphql.default.request(homepageQuery) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"dans-un-composant\">Dans un composant\u003C/h4>\n\u003Cp>Il est plus prudent d’attendre que \u003Ccode>fetch\u003C/code> ait reçu une réponse avant d’afficher quoi que ce soit. On peut utiliser \u003Ccode>$fetchState\u003C/code> afin d’être tranquille (\u003Ca href=\"https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation sur la méthode fetch (nouvel onglet)\">documentation\u003C/a>).\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">Header.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">v-if\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#56B6C2\">!\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$fetchState\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">pending\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>…</\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/header'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">fetch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">try\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">} \u003C/span>\u003Cspan style=\"--0:#CD89E1\">catch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> (\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">console\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E5C07B\">JSON\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">stringify\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">undefined\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">))\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ctemplate> \u003Cheader v-if="!$fetchState.pending">…\u003C/header>\u003C/template>\u003Cscript>import headerQuery from '~/graphql/queries/singles/header'export default { data() { return { data: {} } }, async fetch() { try { const data = await this.$graphql.default.request(headerQuery) this.data = data } catch (error) { console.error(JSON.stringify(error, undefined, 2)) } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"les-options\">Les options\u003C/h3>\n\u003Cp>Pour passer des options à la requête, par exemple pour une version multilingue avec \u003Ca href=\"https://i18n.nuxtjs.org/\" title=\"Documentation de nuxt i18n (nouvel onglet)\">nuxt/i18n\u003C/a> et/ou un paramètre d’url dans le cadre d’une page dynamique :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">_slug.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/articles'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">i18n\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">localeProperties\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">iso\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">code\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E6888F\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E5C07B\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import articleQuery from '~/graphql/queries/articles'export default { async asyncData({ $graphql, app, params }) { const locale = app.i18n.localeProperties.iso const data = await $graphql.default.request(articleQuery, { code: locale, slug: params.slug }) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":469,"imagePaths":491,"frontmatter":492},[470,473,476,479,482,485,488],{"depth":30,"slug":471,"text":472},"le-problème","Le problème",{"depth":30,"slug":474,"text":475},"la-solution","La solution 🙌",{"depth":88,"slug":477,"text":478},"la-conf","La conf",{"depth":88,"slug":480,"text":481},"la-requête","La requête",{"depth":441,"slug":483,"text":484},"dans-une-page","Dans une page",{"depth":441,"slug":486,"text":487},"dans-un-composant","Dans un composant",{"depth":88,"slug":489,"text":490},"les-options","Les options",[],{"title":458,"subtitle":459,"lang":15,"slug":455,"createdAt":307,"updatedAt":452,"excerpt":493,"tags":494,"type":189},"Quand le module gql le plus utilisé ne fonctionne pas…",[296],"en-buttons",{"id":495,"data":497,"body":502,"filePath":503,"digest":504,"rendered":505},{"title":498,"subtitle":499,"lang":196,"tags":500,"type":199,"slug":495,"createdAt":501,"code":202,"draft":202},"Buttons hover","Simple, but nice.",[198],["Date","2020-10-08T09:00:00.000Z"],"## General rules\n\nAll the buttons use these styles as a “reset”:\n\n> Don't forget to prefix if necessary!\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Add an icon\n\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('~assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double shutter down\n\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Animated gradient\n\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Non destructive scale\n\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/en/buttons.md","ea9a5513a5a4cef4",{"html":506,"metadata":507},"\u003Ch2 id=\"general-rules\">General rules\u003C/h2>\n\u003Cp>All the buttons use these styles as a “reset”:\u003C/p>\n\u003Cblockquote>\n\u003Cp>Don’t forget to prefix if necessary!\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">margin: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">padding: \u003C/span>\u003Cspan style=\"--0:#D19A66\">12\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">26\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">relative\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">display: \u003C/span>\u003Cspan style=\"--0:#D19A66\">inline-block\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">overflow: \u003C/span>\u003Cspan style=\"--0:#D19A66\">hidden\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">font-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">rem\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">; \u003C/span>\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\">/* 20px */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">line-height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">1.6\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-align: \u003C/span>\u003Cspan style=\"--0:#D19A66\">center\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-decoration: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">font-weight: \u003C/span>\u003Cspan style=\"--0:#D19A66\">bold\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">cursor: \u003C/span>\u003Cspan style=\"--0:#D19A66\">pointer\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">-moz-appearance\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">-webkit-appearance\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: background-color \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn { margin: 20px 0; padding: 12px 26px; position: relative; display: inline-block; overflow: hidden; font-size: 20rem; /* 20px */ line-height: 1.6; text-align: center; text-decoration: none; font-weight: bold; cursor: pointer; border: none; border-radius: 2px; -moz-appearance: none; -webkit-appearance: none; color: white; background-color: hotpink; transition: background-color 0.3s ease;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"add-an-icon\">Add an icon\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">url\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#98C379\">'~assets/svg/arrow-right-white.svg'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">right: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">40\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">-50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: darkorchid;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-10\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">-50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">display: \u003C/span>\u003Cspan style=\"--0:#D19A66\">inline-block\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">27\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">28\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">29\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translateX\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-10\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">30\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-icon { background-color: hotpink;}.btn-icon::before { content: url('~assets/svg/arrow-right-white.svg'); position: absolute; width: 20px; top: 50%; right: 0; transform: translate(40px, -50%); transition: transform ease 0.3s;}.btn-icon:hover,.btn-icon:focus { background-color: darkorchid;}.btn-icon:hover::before,.btn-icon:focus::before { transform: translate(-10px, -50%);}.btn-icon > span { display: inline-block; width: 100%; height: 100%; transition: transform 0.3s ease;}.btn-icon:hover > span,.btn-icon:focus > span { transform: translateX(-10px);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"double-shutter-down\">Double shutter down\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">solid\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">transparent\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: \u003C/span>\u003Cspan style=\"--0:#D19A66\">color\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: darkorchid;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">bottom: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">z-index: \u003C/span>\u003Cspan style=\"--0:#D19A66\">-1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-timing-function: \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">27\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-timing-function: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">cubic-bezier\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">0.75\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.125\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">28\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">29\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">30\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">31\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">32\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">33\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translateY\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">34\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">35\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">36\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">37\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-delay: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.175\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">38\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-rideau { border: 2px solid #10113a; color: #10113a; background-color: transparent; transition: color 0.3s ease;}.btn-rideau:hover { color: white;}.btn-rideau::before { background: hotpink;}.btn-rideau::after { background: darkorchid;}.btn-rideau::before,.btn-rideau::after { content: ''; position: absolute; height: 100%; width: 100%; bottom: 100%; left: 0; z-index: -1; transition: transform 0.3s; transition-timing-function: ease; transition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);}.btn-rideau:hover::before,.btn-rideau:hover::after,.btn-rideau:focus::before,.btn-rideau:focus::after { transform: translateY(100%);}.btn-rideau:hover::after,.btn-rideau:focus::after { transition-delay: 0.175s;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"animated-gradient\">Animated gradient\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">linear-gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-45\u003C/span>\u003Cspan style=\"--0:#E6888F\">deg\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#ee7752\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#e73c7e\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#23a6d5\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#23d5ab\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">400\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">400\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">animation: GradientReverse \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.5\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">normal\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">forwards\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">animation: Gradient \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.5\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">normal\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">forwards\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">@keyframes\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">Gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">0% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">100% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">@keyframes\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">GradientReverse\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">0% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">100% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-gradient { background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); background-size: 400% 400%; background-position: 0% 50%; animation: GradientReverse 0.5s ease 1 normal forwards;}.btn-gradient:hover,.btn-gradient:focus { animation: Gradient 0.5s ease 1 normal forwards;}@keyframes Gradient { 0% { background-position: 0% 50%; } 100% { background-position: 100% 100%; }}@keyframes GradientReverse { 0% { background-position: 100% 100%; } 100% { background-position: 0% 50%; }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"non-destructive-scale\">Non destructive scale\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">overflow: \u003C/span>\u003Cspan style=\"--0:#D19A66\">visible\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">transparent\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">bottom: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">solid\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">scale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">1.1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-scale { overflow: visible; color: #10113a; background-color: transparent;}.btn-scale::after { content: ''; position: absolute; top: 0; left: 0; bottom: 0; width: 100%; border: 2px solid #10113a; border-radius: 2px; transition: transform 0.3s ease;}.btn-scale:hover::after,.btn-scale:focus::after { transform: scale(1.1);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":508,"imagePaths":524,"frontmatter":525},[509,512,515,518,521],{"depth":30,"slug":510,"text":511},"general-rules","General rules",{"depth":30,"slug":513,"text":514},"add-an-icon","Add an icon",{"depth":30,"slug":516,"text":517},"double-shutter-down","Double shutter down",{"depth":30,"slug":519,"text":520},"animated-gradient","Animated gradient",{"depth":30,"slug":522,"text":523},"non-destructive-scale","Non destructive scale",[],{"title":498,"subtitle":499,"lang":196,"slug":495,"draft":202,"excerpt":526,"tags":527,"code":202,"type":199,"createdAt":528},"Easy to grab and use hover effects.",[198],"2020-10-08T09:00:00.000Z","en-acme-sh-tls-cert",{"id":529,"data":531,"body":537,"filePath":538,"digest":539,"rendered":540},{"title":532,"subtitle":533,"lang":196,"tags":534,"type":199,"slug":529,"createdAt":536},"Strong TLS certificates with acme.sh","384-bit of https",[535],"security",["Date","2022-06-08T14:24:06.000Z"],"## Disclaimer\n\nI'm, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs. \nThis is why I've switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nYou can learn (far) more by reading [this topic](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) and its linked resources.\n\n## Requirements\n\n### Installing acme.sh\n\nFor automation and ease of use purposes, I'm using [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# for using standalone mode, you might have to install as sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changing default authority\n\nBy default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let's Encrypt because according to acme.sh, they're the only ones offering ECC capabilities.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Using your DNS api\n\nIf available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports [a lot](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) of DNS providers.\n\n### Define an api key\n\nFollow the [docs](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) for your DNS provider, usually:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Issue the cert\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Using standalone mode\n\nIf you don't have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\n\nPort `80` must be free.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Examples\n\n### Multi domains standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domain DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Next steps\n\nThe ECC certificate alone will not grant you a high/perfect score.\n\n### TLS version\n\nLimit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a [5% compatibility gap](https://caniuse.com/?search=tls%201.) with 1.2).\n\n### HSTS\n\nUse the [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/) header.\n\n```http\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Cipher suite\n\nUse recent and strong ciphers. This is where my knowledge hits its limit… I'm having a really hard time understanding what to use and why.\n\nI've based my initial choices of ciphers on [this list](https://tls.imirhil.fr/ciphers), cross referencing it with (older?) [browser compatibility](https://tls.imirhil.fr/suite).\n\nI then asked [Aeris](https://twitter.com/aeris22), the creator of [tls.imirhil.fr](https://tls.imirhil.fr), about it and he advised me to use the following:\n\n```cypher\nECDHE+AES:ECDHE+CHACHA20\n```\n\nIn order to achieve a perfect score, we can be a little more restrictive with:\n\n```cypher\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/en/acme-sh-tls-cert.md","4dc80f1d0e800d6f",{"html":541,"metadata":542},"\u003Ch2 id=\"disclaimer\">Disclaimer\u003C/h2>\n\u003Cp>I’m, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs.\u003Cbr>\nThis is why I’ve switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>You can learn (far) more by reading \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">this topic\u003C/a> and its linked resources.\u003C/p>\n\u003Ch2 id=\"requirements\">Requirements\u003C/h2>\n\u003Ch3 id=\"installing-acmesh\">Installing acme.sh\u003C/h3>\n\u003Cp>For automation and ease of use purposes, I’m using \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\"># for using standalone mode, you might have to install as sudo\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">curl\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">https://get.acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> | \u003C/span>\u003Cspan style=\"--0:#61AFEF\">sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">email=mail@domain.tld\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl https://get.acme.sh | sh -s email=mail@domain.tld\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"changing-default-authority\">Changing default authority\u003C/h3>\n\u003Cp>By default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let’s Encrypt because according to acme.sh, they’re the only ones offering ECC capabilities.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--set-default-ca\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--server\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">letsencrypt\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --set-default-ca --server letsencrypt\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"using-your-dns-api\">Using your DNS api\u003C/h2>\n\u003Cp>If available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">a lot\u003C/a> of DNS providers.\u003C/p>\n\u003Ch3 id=\"define-an-api-key\">Define an api key\u003C/h3>\n\u003Cp>Follow the \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">docs\u003C/a> for your DNS provider, usually:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">PROVIDER_Key\u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#98C379\">\"YOUR_API_KEY\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export PROVIDER_Key="YOUR_API_KEY"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"issue-the-cert\">Issue the cert\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"using-standalone-mode\">Using standalone mode\u003C/h2>\n\u003Cp>If you don’t have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\u003C/p>\n\u003Cp>Port \u003Ccode>80\u003C/code> must be free.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"examples\">Examples\u003C/h2>\n\u003Ch3 id=\"multi-domains-standalone\">Multi domains standalone\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">www.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">subdomain.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"wildcard-domain-dns\">Wildcard domain DNS\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'*.domain.tld'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"next-steps\">Next steps\u003C/h2>\n\u003Cp>The ECC certificate alone will not grant you a high/perfect score.\u003C/p>\n\u003Ch3 id=\"tls-version\">TLS version\u003C/h3>\n\u003Cp>Limit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a \u003Ca href=\"https://caniuse.com/?search=tls%201.\">5% compatibility gap\u003C/a> with 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Use the \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a> header.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">Strict-Transport-Security\u003C/span>\u003Cspan style=\"--0:#CD89E1\">:\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">max-age=31536000; includeSubDomains\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Strict-Transport-Security: max-age=31536000; includeSubDomains\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"cipher-suite\">Cipher suite\u003C/h3>\n\u003Cp>Use recent and strong ciphers. This is where my knowledge hits its limit… I’m having a really hard time understanding what to use and why.\u003C/p>\n\u003Cp>I’ve based my initial choices of ciphers on \u003Ca href=\"https://tls.imirhil.fr/ciphers\">this list\u003C/a>, cross referencing it with (older?) \u003Ca href=\"https://tls.imirhil.fr/suite\">browser compatibility\u003C/a>.\u003C/p>\n\u003Cp>I then asked \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, the creator of \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, about it and he advised me to use the following:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>In order to achieve a perfect score, we can be a little more restrictive with:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES256\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES256:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":543,"imagePaths":589,"frontmatter":590},[544,547,550,553,556,559,562,565,568,571,574,577,580,583,586],{"depth":30,"slug":545,"text":546},"disclaimer","Disclaimer",{"depth":30,"slug":548,"text":549},"requirements","Requirements",{"depth":88,"slug":551,"text":552},"installing-acmesh","Installing acme.sh",{"depth":88,"slug":554,"text":555},"changing-default-authority","Changing default authority",{"depth":30,"slug":557,"text":558},"using-your-dns-api","Using your DNS api",{"depth":88,"slug":560,"text":561},"define-an-api-key","Define an api key",{"depth":88,"slug":563,"text":564},"issue-the-cert","Issue the cert",{"depth":30,"slug":566,"text":567},"using-standalone-mode","Using standalone mode",{"depth":30,"slug":569,"text":570},"examples","Examples",{"depth":88,"slug":572,"text":573},"multi-domains-standalone","Multi domains standalone",{"depth":88,"slug":575,"text":576},"wildcard-domain-dns","Wildcard domain DNS",{"depth":30,"slug":578,"text":579},"next-steps","Next steps",{"depth":88,"slug":581,"text":582},"tls-version","TLS version",{"depth":88,"slug":584,"text":585},"hsts","HSTS",{"depth":88,"slug":587,"text":588},"cipher-suite","Cipher suite",[],{"title":532,"subtitle":533,"lang":196,"slug":529,"createdAt":307,"excerpt":591,"tags":592,"type":199},"Real cert have curves.",[535],"acme-sh-tls-cert",{"id":593,"data":595,"body":601,"filePath":602,"digest":603,"rendered":604},{"title":596,"subtitle":597,"lang":15,"tags":598,"type":189,"slug":593,"createdAt":600},"Certificates TLS robustes avec acme.sh","384-bit de https",[599],"sécurité",["Date","2022-06-08T14:24:06.000Z"],"## Attention\n\nJe ne suis pas du tout un expert en sécurité. J'aime juste les trucs nouveaux et stylés des internets. \nC'est pourquoi j'ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J'ai maintenant un joli 100/100 sur [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nVous pouvez en apprendre (beaucoup) plus [ici](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) et sur les liens cités (en anglais).\n\n## Prérequis\n\n### Installer acme.sh\n\nPour des raisons de simplicité et d'automatisation, j'utilise [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changer l'authorité par défaut\n\nPar défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let's Encrypt car, d'après acme.sh, ils sont les seuls à proposer des certificats ECC.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Utiliser l'api DNS\n\nSi vous en avez la possibilité, la façon la plus simple de générer un certificat est via l'api de votre fournisseur DNS. acme.sh supporte [énormément](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) de fournisseurs DNS.\n\n### Definir la clé api\n\nSuivez la [documentation](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) pour votre fournisseur DNS, généralement:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Émettre le certificat\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Utiliser le mode standalone\n\nSi vous n'avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s'occupe de toutes les vérifications.\n\nLe port `80` doit être disponible.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Exemples\n\n### Multi domaines standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domaine DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Étapes supplémentaires\n\nLe certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\n\n### Version TLS\n\nLimiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu [la différence de compatibilité de 5%](https://caniuse.com/?search=tls%201.) avec 1.2).\n\n### HSTS\n\nUtiliser le header [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/).\n\n```http\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Suite cryptographique\n\nUtiliser une suite cryptographique récente et robuste. C'est ici que mes connaissances deviennent limitées… J'ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\n\nJ'avais basé ma première suite sur [cette liste](https://tls.imirhil.fr/ciphers), en la comparant avec celle de la compatibilité (d'anciens ?) [navigateurs](https://tls.imirhil.fr/suite).\n\nJ'ai ensuite demandé à [Aeris](https://twitter.com/aeris22), le créateur de [tls.imirhil.fr](https://tls.imirhil.fr), ses conseils sur cette suite. Il m'a recommandé d'utiliser :\n\n```cypher\nECDHE+AES:ECDHE+CHACHA20\n```\n\nAfin d'atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\n\n```cypher\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/fr/acme-sh-tls-cert.md","018b0c09d1fdd6cc",{"html":605,"metadata":606},"\u003Ch2 id=\"attention\">Attention\u003C/h2>\n\u003Cp>Je ne suis pas du tout un expert en sécurité. J’aime juste les trucs nouveaux et stylés des internets.\u003Cbr>\nC’est pourquoi j’ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J’ai maintenant un joli 100/100 sur \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>Vous pouvez en apprendre (beaucoup) plus \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">ici\u003C/a> et sur les liens cités (en anglais).\u003C/p>\n\u003Ch2 id=\"prérequis\">Prérequis\u003C/h2>\n\u003Ch3 id=\"installer-acmesh\">Installer acme.sh\u003C/h3>\n\u003Cp>Pour des raisons de simplicité et d’automatisation, j’utilise \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\"># pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">curl\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">https://get.acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> | \u003C/span>\u003Cspan style=\"--0:#61AFEF\">sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">email=mail@domain.tld\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl https://get.acme.sh | sh -s email=mail@domain.tld\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"changer-lauthorité-par-défaut\">Changer l’authorité par défaut\u003C/h3>\n\u003Cp>Par défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let’s Encrypt car, d’après acme.sh, ils sont les seuls à proposer des certificats ECC.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--set-default-ca\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--server\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">letsencrypt\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --set-default-ca --server letsencrypt\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"utiliser-lapi-dns\">Utiliser l’api DNS\u003C/h2>\n\u003Cp>Si vous en avez la possibilité, la façon la plus simple de générer un certificat est via l’api de votre fournisseur DNS. acme.sh supporte \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">énormément\u003C/a> de fournisseurs DNS.\u003C/p>\n\u003Ch3 id=\"definir-la-clé-api\">Definir la clé api\u003C/h3>\n\u003Cp>Suivez la \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">documentation\u003C/a> pour votre fournisseur DNS, généralement:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">PROVIDER_Key\u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#98C379\">\"YOUR_API_KEY\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export PROVIDER_Key="YOUR_API_KEY"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"émettre-le-certificat\">Émettre le certificat\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"utiliser-le-mode-standalone\">Utiliser le mode standalone\u003C/h2>\n\u003Cp>Si vous n’avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s’occupe de toutes les vérifications.\u003C/p>\n\u003Cp>Le port \u003Ccode>80\u003C/code> doit être disponible.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"exemples\">Exemples\u003C/h2>\n\u003Ch3 id=\"multi-domaines-standalone\">Multi domaines standalone\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">www.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">subdomain.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"wildcard-domaine-dns\">Wildcard domaine DNS\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'*.domain.tld'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"étapes-supplémentaires\">Étapes supplémentaires\u003C/h2>\n\u003Cp>Le certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\u003C/p>\n\u003Ch3 id=\"version-tls\">Version TLS\u003C/h3>\n\u003Cp>Limiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu \u003Ca href=\"https://caniuse.com/?search=tls%201.\">la différence de compatibilité de 5%\u003C/a> avec 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Utiliser le header \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a>.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">Strict-Transport-Security\u003C/span>\u003Cspan style=\"--0:#CD89E1\">:\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">max-age=31536000; includeSubDomains\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Strict-Transport-Security: max-age=31536000; includeSubDomains\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"suite-cryptographique\">Suite cryptographique\u003C/h3>\n\u003Cp>Utiliser une suite cryptographique récente et robuste. C’est ici que mes connaissances deviennent limitées… J’ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\u003C/p>\n\u003Cp>J’avais basé ma première suite sur \u003Ca href=\"https://tls.imirhil.fr/ciphers\">cette liste\u003C/a>, en la comparant avec celle de la compatibilité (d’anciens ?) \u003Ca href=\"https://tls.imirhil.fr/suite\">navigateurs\u003C/a>.\u003C/p>\n\u003Cp>J’ai ensuite demandé à \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, le créateur de \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, ses conseils sur cette suite. Il m’a recommandé d’utiliser :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Afin d’atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES256\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES256:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":607,"imagePaths":651,"frontmatter":652},[608,611,614,617,620,623,626,629,632,635,638,641,644,647,648],{"depth":30,"slug":609,"text":610},"attention","Attention",{"depth":30,"slug":612,"text":613},"prérequis","Prérequis",{"depth":88,"slug":615,"text":616},"installer-acmesh","Installer acme.sh",{"depth":88,"slug":618,"text":619},"changer-lauthorité-par-défaut","Changer l’authorité par défaut",{"depth":30,"slug":621,"text":622},"utiliser-lapi-dns","Utiliser l’api DNS",{"depth":88,"slug":624,"text":625},"definir-la-clé-api","Definir la clé api",{"depth":88,"slug":627,"text":628},"émettre-le-certificat","Émettre le certificat",{"depth":30,"slug":630,"text":631},"utiliser-le-mode-standalone","Utiliser le mode standalone",{"depth":30,"slug":633,"text":634},"exemples","Exemples",{"depth":88,"slug":636,"text":637},"multi-domaines-standalone","Multi domaines standalone",{"depth":88,"slug":639,"text":640},"wildcard-domaine-dns","Wildcard domaine DNS",{"depth":30,"slug":642,"text":643},"étapes-supplémentaires","Étapes supplémentaires",{"depth":88,"slug":645,"text":646},"version-tls","Version TLS",{"depth":88,"slug":584,"text":585},{"depth":88,"slug":649,"text":650},"suite-cryptographique","Suite cryptographique",[],{"title":596,"subtitle":597,"lang":15,"slug":593,"createdAt":307,"excerpt":653,"tags":654,"type":189},"La sécurité avec des courbes.",[599],"articles",["Map",657,658,691,692,725,726,747,748,758,759,775,776,790,791,803,804,816,817,827,828,175,857,885,886,902,903,946,947,957,958,967,968,984,985],"en-2022",{"id":657,"data":659,"body":665,"filePath":666,"digest":667,"rendered":668},{"title":660,"subtitle":661,"lang":196,"tags":662,"type":655,"slug":657,"createdAt":664},"Nico v2.0","2022 update of many things.",[663],"Freelance",["Date","2022-06-08T14:24:06.000Z"],"After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\n\n## Services\n\n### No more print\n\nEven though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for \"classic\" graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\n\n### Internet all the way\n\nOn the other hand, I spend my time **doing web stuff.** A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer **more specific web offerings,** in which I have specialised.\n\nThus, **accessibility** and **eco-design** become integrated expertises in my practice. They are no longer options on a quote but **my core business.**\n\n## The website\n\nI have reworked my website, especially the homepage and its content, to better reflect these decisions.\n\nI have also made several behavioural changes:\n\n- external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven't found a good reason to continue using this behaviour;\n- I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu);\n- \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\n- I only trigger animations if the user has not asked the system to reduce the amount motion [(reference)](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).\n\nI am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello [astro](https://astro.build/) 👀).\n\n## Le Nico\n\nOn a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\n\nI have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.","src/content/articles/en/2022.md","7b98592763cb0929",{"html":669,"metadata":670},"\u003Cp>After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\u003C/p>\n\u003Ch2 id=\"services\">Services\u003C/h2>\n\u003Ch3 id=\"no-more-print\">No more print\u003C/h3>\n\u003Cp>Even though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for “classic” graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\u003C/p>\n\u003Ch3 id=\"internet-all-the-way\">Internet all the way\u003C/h3>\n\u003Cp>On the other hand, I spend my time \u003Cstrong>doing web stuff.\u003C/strong> A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer \u003Cstrong>more specific web offerings,\u003C/strong> in which I have specialised.\u003C/p>\n\u003Cp>Thus, \u003Cstrong>accessibility\u003C/strong> and \u003Cstrong>eco-design\u003C/strong> become integrated expertises in my practice. They are no longer options on a quote but \u003Cstrong>my core business.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Cp>I have reworked my website, especially the homepage and its content, to better reflect these decisions.\u003C/p>\n\u003Cp>I have also made several behavioural changes:\u003C/p>\n\u003Cul>\n\u003Cli>external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven’t found a good reason to continue using this behaviour;\u003C/li>\n\u003Cli>I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a>;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\u003C/li>\n\u003Cli>I only trigger animations if the user has not asked the system to reduce the amount motion \u003Ca href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion\">(reference)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>I am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello \u003Ca href=\"https://astro.build/\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>On a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\u003C/p>\n\u003Cp>I have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.\u003C/p>",{"headings":671,"imagePaths":687,"frontmatter":688},[672,675,678,681,684],{"depth":30,"slug":673,"text":674},"services","Services",{"depth":88,"slug":676,"text":677},"no-more-print","No more print",{"depth":88,"slug":679,"text":680},"internet-all-the-way","Internet all the way",{"depth":30,"slug":682,"text":683},"the-website","The website",{"depth":30,"slug":685,"text":686},"le-nico","Le Nico",[],{"title":660,"subtitle":661,"lang":196,"slug":657,"excerpt":689,"tags":690,"type":655,"createdAt":307},"Changes in my services, the website and myself.",[663],"en-2023",{"id":691,"data":693,"body":699,"filePath":700,"digest":701,"rendered":702},{"title":694,"subtitle":695,"lang":196,"tags":696,"type":655,"slug":691,"createdAt":697,"updatedAt":698},"Nico v2.5","Update 2023.",[663],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"This article will be updated when I have something new to share during the year 2023.\n\n## The website\n\n### Technologies\n\nOops... I (re)did it again.\n\nI have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself [in 2022 !](/en/articles/2022/#the-website)\n\nI will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\n\nMy \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I'm back to a solid **95/100** without any particular optimization. With some small efforts, I've reached the good old 100/100.\n\nI then did a work of modernization of the codebase. Hello CSS variables and goodbye `media queries`. In no particular order, here are some of the improvements I made:\n\n- `flexbox` and `grid` to adapt the layout to different screen sizes;\n- CSS variables for colors, font sizes and margins;\n- some `container queries`, just to try;\n- logical CSS properties (`inline` and `block` instead of `width` and `height` for example).\n\nI took this opportunity to publish [the source code](https://git.nardu.in/nardu.in/website-astro) on my git repository.\n\n**Update #1:** I've added [an RSS feed](/en/rss.xml) as I find myself using it more and more on other websites.\n\n### Analytics\n\nI removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\n\nIt's nice to see that your site is consulted, but if there is no other purpose behind it, it's an extra resource loaded for nothing by visitors. Maybe I'll reactivate the tracking when I have a use for it (other than flattering my ego).\n\nPrevious visit reports can be found at [this link.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Content\n\n- I've added a [work](/en/work/) page to list some of my projects.\n- I've also added [a page](/en/veille/) where I list some interesting things from around the web.\n\n## Additional projects\n\nI'm still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at [3-w.fr](https://3-w.fr/) (an address I am very proud of).\n\nI have to update it more regularly but I hope that the platform will help students progress!\n\n**More to come soon!**","src/content/articles/en/2023.md","489c650e66cced63",{"html":703,"metadata":704},"\u003Cp>This article will be updated when I have something new to share during the year 2023.\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oops… I (re)did it again.\u003C/p>\n\u003Cp>I have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself \u003Ca href=\"/en/articles/2022/#the-website\">in 2022 !\u003C/a>\u003C/p>\n\u003Cp>I will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\u003C/p>\n\u003Cp>My \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I’m back to a solid \u003Cstrong>95/100\u003C/strong> without any particular optimization. With some small efforts, I’ve reached the good old 100/100.\u003C/p>\n\u003Cp>I then did a work of modernization of the codebase. Hello CSS variables and goodbye \u003Ccode>media queries\u003C/code>. In no particular order, here are some of the improvements I made:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> and \u003Ccode>grid\u003C/code> to adapt the layout to different screen sizes;\u003C/li>\n\u003Cli>CSS variables for colors, font sizes and margins;\u003C/li>\n\u003Cli>some \u003Ccode>container queries\u003C/code>, just to try;\u003C/li>\n\u003Cli>logical CSS properties (\u003Ccode>inline\u003C/code> and \u003Ccode>block\u003C/code> instead of \u003Ccode>width\u003C/code> and \u003Ccode>height\u003C/code> for example).\u003C/li>\n\u003C/ul>\n\u003Cp>I took this opportunity to publish \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">the source code\u003C/a> on my git repository.\u003C/p>\n\u003Cp>\u003Cstrong>Update #1:\u003C/strong> I’ve added \u003Ca href=\"/en/rss.xml\">an RSS feed\u003C/a> as I find myself using it more and more on other websites.\u003C/p>\n\u003Ch3 id=\"analytics\">Analytics\u003C/h3>\n\u003Cp>I removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\u003C/p>\n\u003Cp>It’s nice to see that your site is consulted, but if there is no other purpose behind it, it’s an extra resource loaded for nothing by visitors. Maybe I’ll reactivate the tracking when I have a use for it (other than flattering my ego).\u003C/p>\n\u003Cp>Previous visit reports can be found at \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">this link.\u003C/a>\u003C/p>\n\u003Ch3 id=\"content\">Content\u003C/h3>\n\u003Cul>\n\u003Cli>I’ve added a \u003Ca href=\"/en/work/\">work\u003C/a> page to list some of my projects.\u003C/li>\n\u003Cli>I’ve also added \u003Ca href=\"/en/veille/\">a page\u003C/a> where I list some interesting things from around the web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"additional-projects\">Additional projects\u003C/h2>\n\u003Cp>I’m still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (an address I am very proud of).\u003C/p>\n\u003Cp>I have to update it more regularly but I hope that the platform will help students progress!\u003C/p>\n\u003Cp>\u003Cstrong>More to come soon!\u003C/strong>\u003C/p>",{"headings":705,"imagePaths":719,"frontmatter":720},[706,707,710,713,716],{"depth":30,"slug":682,"text":683},{"depth":88,"slug":708,"text":709},"technologies","Technologies",{"depth":88,"slug":711,"text":712},"analytics","Analytics",{"depth":88,"slug":714,"text":715},"content","Content",{"depth":30,"slug":717,"text":718},"additional-projects","Additional projects",[],{"title":694,"subtitle":695,"lang":196,"slug":691,"excerpt":721,"tags":722,"type":655,"createdAt":723,"updatedAt":724},"New changes.",[663],"2023-02-03T17:41:00.000Z","2023-05-17T17:41:00.000Z","en-2025",{"id":725,"data":727,"body":732,"filePath":733,"digest":734,"rendered":735},{"title":728,"subtitle":729,"lang":196,"tags":730,"type":655,"slug":725,"createdAt":731},"Nico v3.0","This website no longer has an english version..",[663],["Date","2025-01-02T17:41:00.000Z"],"## So long \u003Ccode style=\"font-size: var(--size-2)\">lang=\"en\"\u003C/code>\n\nI have maintained an english version of my website for some years but **no more…** The effort needed to make a fully multilingual website with Astro is just too much work for my small personal website.\n\n**All previous content will remain online** ([articles](/articles/#en-articles) and [snippets](/fragments/#en-fragments)) but the interface and internal pages will only be in french.\n\nI do not have any metrics on who visits my website but I don't think it will be missed. If you do miss it, don't hesitate to send me an email!","src/content/articles/en/2025.md","669bebc4518d51e1",{"html":736,"metadata":737},"\u003Ch2 id=\"so-long-langen\">So long \u003Ccode style=\"font-size: var(--size-2)\">lang=“en”\u003C/code>\u003C/h2>\n\u003Cp>I have maintained an english version of my website for some years but \u003Cstrong>no more…\u003C/strong> The effort needed to make a fully multilingual website with Astro is just too much work for my small personal website.\u003C/p>\n\u003Cp>\u003Cstrong>All previous content will remain online\u003C/strong> (\u003Ca href=\"/articles/#en-articles\">articles\u003C/a> and \u003Ca href=\"/fragments/#en-fragments\">snippets\u003C/a>) but the interface and internal pages will only be in french.\u003C/p>\n\u003Cp>I do not have any metrics on who visits my website but I don’t think it will be missed. If you do miss it, don’t hesitate to send me an email!\u003C/p>",{"headings":738,"imagePaths":742,"frontmatter":743},[739],{"depth":30,"slug":740,"text":741},"so-long-langen","So long lang=“en”",[],{"title":728,"subtitle":729,"lang":196,"slug":725,"excerpt":744,"tags":745,"type":655,"createdAt":746},"This website no longer has an english version.",[663],"2025-01-02T17:41:00.000Z","en-after-effects-expressions",{"id":747,"data":749,"body":755,"filePath":756,"digest":757,"deferredRender":202},{"title":750,"subtitle":751,"lang":196,"tags":752,"type":655,"slug":747,"createdAt":754,"code":202},"After Effects Expressions","Animation on steroïds.",[753],"Design",["Date","2019-04-24T09:00:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## An ever lasting battle\n\nThere is very little documentation and the existing one is hard to find or very old. Very often I just don't have the time to dive into expression learning while animating even though it could help the entire project on the long term.\nSo the last time I had to do a complex animation, **I took the damn time!**\n\n## The begining of the end (of keyframes).\n\nEveryone uses expressions whether they know it or not. Most of the time it's a rather transparent process for the animator. For example: when parenting a property to another one, After Effects creates an expression for us.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/basic_expression_d81b12f1ac.jpeg'\n\twidth='728'\n\theight='80'\n\talt='Parenting the position of the form to a null creates an expression.'\n/>\n\nOver the last updates, Adobe has made an effort to make expressions more accessible to everyone. For example, the expression box is now resembling a code editor thanks to code-coloring and auto-completion features. After Effects expression feel like JavaScript with custom functions.\n\nThose custom functions can be called through a menu once you enabled the expressions on a property. It offers organized shortcut and proper syntax to all of AE native functions and a bunch of JavaScript standard ones.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/shortcut_39cc19d383.jpeg'\n\twidth='728'\n\theight='322'\n\talt='Alt + Click the stopwatch to access the shortcuts.'\n/>\n\n## So I need to learn javascript to do motion design now?\n\n### Why bother?\n\nI know that most animators don't have any kind of development background. However, if Adobe thought it best to let us use expressions, I think we ought to, at least, try.\n\n> A lot of incredible professionals like [Mt Mograph](https://www.mtmograph.com/) and [Video Copilot](https://videocopilot.net/) use expressions.\n\nLike every optimization process, building an expressions knowledge takes time. However, like all optimization process, you will benefit from it afterwards.\n\n### Where to learn\n\nI've gathered a list of my favourite learning grounds. Plenty more exist, **go get'em!**\n\n- [Adobe official expression starter guide (FR)](https://helpx.adobe.com/fr/after-effects/using/expression-language-reference.html)\n- [Adobe official expression basic (EN)](https://helpx.adobe.com/after-effects/using/expression-basics.html)\n- [Adobe forums for expressions](https://community.adobe.com/t5/after-effects/bd-p/after-effects?page=1&sort=latest_replies&filter=all&topics=label-expressions)\n- [Creative Cow expressions forums](https://creativecow.net/forums/forum/adobe-after-effects-expressions/)\n- [Youtube channel about expressions](https://www.youtube.com/playlist?list=PLvr5U5ZSt6IzHyvSL9fo0M9NRPsTvra31)\n- [All expressions explained](http://aescript.jecool.net/reference/)\n- [All expressions explained again](http://expressions.aenhancers.com/index.html)\n- [Nice examples of basic expressions](https://www.schoolofmotion.com/tutorials/amazing-expressions-in-after-effects)\n\n## Real world example\n\n### Number counter\n\nLet's say you need to animate a rather simple counter from 0% to 100%.\n\n- Start by creating a text layer. Define your typographic choices, colours, etc.\n- On the effect menu add expression options > slider control\n- Alt + Click the Source text property\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/alt-counter.mp4' type='video/mp4' />\n\u003C/video>\n\n- Parent the source text to the slider control through the pickwhip.\n\n\u003Cvideo width='462' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/pickwhip.mp4' type='video/mp4' />\n\u003C/video>\n\nYou should get something like this in the expressions panel:\n\n```javascript\neffect(\"Slider Control\")(\"Slider\")​\n```\n\n- Set two keyframes on the slider from 0 to 100. The text should update accordingly.\n- By default, After Effects does not round numbers. In the expression panel, wrap your expression with the `Math.round()` function.\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/round.mp4' type='video/mp4' />\n\u003C/video>\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\"))​\n```\n\nGreat! We have a working counter. But we wanted a percentage counter. We could add a % glyph in another text layer but let's not.\n\nStill in the expression panel, we're going to add a string containing the % glyph, using basic JavaScript concatenation: `+ '%'`\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\")) + '%'​\n```\n\n\u003Cvideo width='538' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/percent.mp4' type='video/mp4' />\n\u003C/video>\n\n**And there we go!** A fully functioning and customizable counter using a slider controller and expressions.","src/content/articles/en/after-effects-expressions.mdx","3b6f88fbf35af1a4","en-faq",{"id":758,"data":760,"body":764,"filePath":765,"digest":766,"rendered":767},{"title":761,"subtitle":195,"lang":196,"tags":762,"type":655,"slug":758,"createdAt":763,"draft":202},"Accessibility and sobriety",[663],["Date","2022-06-22T15:34:45.000Z"],"[Go back to available articles](/en/articles)","src/content/articles/en/faq.md","82d516449896f6ca",{"html":768,"metadata":769},"\u003Cp>\u003Ca href=\"/en/articles\">Go back to available articles\u003C/a>\u003C/p>",{"headings":770,"imagePaths":771,"frontmatter":772},[],[],{"title":761,"subtitle":195,"lang":196,"slug":758,"draft":202,"excerpt":773,"tags":774,"type":655,"createdAt":272},"Why, how et and especially what.",[663],"en-gratuiste",{"id":775,"data":777,"body":764,"filePath":781,"digest":782,"rendered":783},{"title":778,"subtitle":195,"lang":196,"tags":779,"type":655,"slug":775,"createdAt":780,"draft":202},"Gratuiste",[753,663],["Date","2017-05-27T07:47:36.000Z"],"src/content/articles/en/gratuiste.md","ebec75d19f0ff741",{"html":768,"metadata":784},{"headings":785,"imagePaths":786,"frontmatter":787},[],[],{"title":778,"subtitle":195,"lang":196,"slug":775,"draft":202,"excerpt":195,"tags":788,"type":655,"createdAt":789},[753,663],"2017-05-27T07:47:36.000Z","en-sci-hub-unblock",{"id":790,"data":792,"body":800,"filePath":801,"digest":802,"deferredRender":202},{"title":793,"subtitle":794,"lang":196,"tags":795,"type":655,"slug":790,"createdAt":798,"updatedAt":799},"Access blocked Sci-hub","The science of sharing.",[796,797],"Internet","Science",["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nThe current sci-hub address is: \u003Ca href=\"https://www.sci-hub.st/\" rel=\"noreferer noopener\">sci-hub.st\u003C/a>\n\n## What is this about?\n\nNot being a researcher myself, here’s an [extremely well done explanatory video](https://youtu.be/rcgxY__YXEc) on the subject of scientific publication (french audio with auto subtitle).\n\n> “This is outrageous!”​\n\nI noticed that my ISP was indeed blocking access. I have not yet been able to check for the other suppliers, but I imagine that they have all complied with the court decision.\nThe restriction in place is quite basic. This is a “DNS” block. A DNS is a server that is used to link a domain name: **www.sci-hub.tw** to an IP address: **186.2.163.90**\nIt is, in a way, the Internet phone book. Without the address, it is impossible to contact the domain. What ISPs have certainly done: block requests to the [sci-hub.se.](http://sci-hub.se/) domain name. As a result, no IP address is returned and the site is not accessible.\n\n## How to bypass this?\n\n- Either by using a VPN\n- Either by modifying the DNS servers of your computers/Internet box\n\nI would recommend the second solution because it allows you to protect yourself against future blockages/filtering/censorship from your ISP and does not require any financial compensation.\nI will focus on change from a computer because it will be effective wherever you are and not only from your home.\n\n### MacOs\n\nGo to:\n\n1. System Preferences\n1. Network\n1. (wi-fi and/or ethernet)\n1. Advanced\n1. DNS\n\nFrom there, you can add DNS servers by clicking the + icon. Click ok and apply the new settings. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS network and DNS settings'\n/>\n\n### Windows (10)\n\nGo to:\n\n1. System Settings\n1. Network & Internet\n1. Change adapter options\n1. Right click your adapter then “properties”\n1. Select “internet protocol version 4” (and/or 6)\n1. Properties\n1. Use the following DNS server addresses\n\nFrom there, you can add DNS servers. Click save. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Windows system settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows network settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows network connections settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows network adapter settings'\n/>\n\n## Which DNS?\n\nThere are many DNS servers available. The best known are Google, Cloudflare and OpenDNS. If you really want to use Google’s, I’ll let you look up their address. Here are my recommendations in order of preference.\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMy favorite since it is a [french association](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net)\n\nQuand9 is a non-profit foundation offering free public DNS servers. Their classic servers offer filtering of identified malicious domains. They do not collect data and are \u003Cabbr title=\"General Data Protection Regulation\">GDPR\u003C/abbr>-compliant.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## That's it.\n\nBy changing these settings, you are free from your ISPs and their content filtering rules.\n\nFor the moment, these restrictions are almost symbolic because if Sci-hub were to change its url, the block would no longer work. But the publishers’ victory in court shows that they have not had their last word. We are therefore not immune to a wider and stronger block in the future.\n\nIf you want to learn more about the struggle of the people who fight to ensure that research is not a paid commodity, I recommend [this documentary](https://youtu.be/y_CQATGOX2w) on Aaron Shwartz. Or [this article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) about the founder of Sci-hub.\n\nIn the meantime, good readings to all of you. We stand with you!","src/content/articles/en/sci-hub-blocage.mdx","af48e8c0c3b463bf","en-the-day-I-jamd",{"id":803,"data":805,"body":813,"filePath":814,"digest":815,"deferredRender":202},{"title":806,"subtitle":807,"lang":196,"tags":808,"type":655,"slug":803,"createdAt":811,"updatedAt":812},"The day I Jam’d","A story of unusual tools and fun gambles.",[809,810],"Dev","Jamstack",["Date","2020-10-08T09:00:00.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## The not so easy choice\n\nWhen I was still using Wordpress for my personal website, I thought it would be nice to try [OpenLiteSpeed](https://openlitespeed.org) webserver. Being a designer, I always like to have a graphical interface and I heard OLS had very nice caching and overall performances.\n\n## FIGHT!\n\nA few years later, I learned about Jamstack and its incredible potential. Not being impulsive at all, I chose to entirely remake my website with tools like [11ty](https://www.11ty.dev/) and [Strapi](https://strapi.io/).\n\nI remember Strapi still being in alpha/beta and colleagues telling me it was a risky gamble, especially since I was pretty new to the node.js world.\n\n> Open source and french? Sign me up!\n\nSo I started recreating my website identically with 11ty and Strapi. Same hosting on a Digital Ocean droplet, same webserver, same content. I had done a fair amout of performance optimizations on my wordpress install so I was eager to compare the results with the new static version.\n\nBoy did they exceed my expectations! With almost no optimization on the static side, I got the following results.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 53/100 on Wordpress.'\n/>\n\nDespite a lot of efforts I could not do better. I’m no expert in caching, do not use CDN and relied on plugins to achieve a lot of stuff (php not being my strongest skill 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 97/100 on jamstack.'\n/>\n\nAlmost **zero** special configuration (I was too anxious to test) and I reached an awesome score. I know lighthouse scores are not everything but hey, **53 vs 97**… I’ll take it!\n\n## Now kiss 🥰\n\nBoth of these approaches have their benefits and drawbacks. As a freelance, my clients often prefer or ask for Wordpress because of its reputation. I always present a Jamstack alternative when possible but it’s still scary to most compared to Wordpress. I feel however that it’s going to be easier to use Jamstack with time.\n\n## I did it again…\n\nHere we are now, a quarantine and a few months later and this website is running with… [Nuxt.js](https://nuxtjs.org/). I know, I’m sorry, I couldn’t resist the latest [nuxt content](https://content.nuxtjs.org/) functionnality.\n\nSo I re-did everything again… and let me just say: **wow**, what an experience!\nI **love** developing with Nuxt. Using nuxt content allowed me to focus on design and, well, content.\nNo more Apollo client and graphQL query, only markdown and a few promises.\n\nDon’t get me wrong, I really like working with Strapi and its graphQL capabilities but for the purpose of this website, nuxt content does it (extremely well).\n\nI’m still using Strapi as a way to upload, store and manage images, videos, gifs, etc. It might be too much for this use case but I like to know that I can still go back to it if I want to! Also, I spent quite a bit of time setting it up with OpenLiteSpeed and I’m still too attached to this accomplishment to let it go.\n\n## In the end\n\nWordpress, Jamstack, vanilla everything… Does it really matter? For me, the dev experience was far more enjoyable working with 11ty, nuxt.js and strapi than with Wordpress.\n\nOn the performance and accessibility side, it also seems to be the better/smarter choice. It might not be everytime! ¯\\\\\\_(ツ)\\_/¯\n\nCan’t wait to learn [astro](https://astro.build/) and start from scratch again!","src/content/articles/en/the-day-I-jamd.mdx","60b77e216e02f618","en-video-compression",{"id":816,"data":818,"body":824,"filePath":825,"digest":826,"deferredRender":202},{"title":819,"subtitle":820,"lang":196,"tags":821,"type":655,"slug":816,"createdAt":822,"updatedAt":823},"Video compression","Encode like you mean it.",[753],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Let's play.\n\nVideos are everywhere. **EVERYWHERE!** But videos can and will be huge when 4k becomes an internet standard. Currently, 1920x1080 is king and we usually have no problem hosting or playing this resolution.\n\n## Because we can doesn't mean we should.\n\nRight now, the (good) trend of web performance is on the rise. Everyone wants a blazing fast loading website, which might not be possible if we send requests to 100mb (or even more) videos.\n\nWith a good connection, users will not see the difference. But if we go down that path, nor will they with a 300mb one. So the goal is to make every asset as small as possible. It's already the case with images. But it's simpler and faster than video encoding.\n\n## Small size, best quality.\n\nLet's say we exported​ a 1920x1080 video from Premiere Pro with these basic settings:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-premiere-1.jpeg'\n\twidth='673'\n\theight='800'\n/>\n\nIt's gorgeous, it's Full HD, it's 1:30 minute of excellent editing but it's 50mb… What a shame.\n\n> We can already bring down the size from Premiere or Media Encoder by selecting CBR instead of VBR and using a low bitrate (like 2 or 3).\n\nLet's now use [Handbrake!](https://handbrake.fr/) It's free, open source and multi platform. You can also read this great article from [Ueno](https://loremipsum.ueno.co/dear-ueno-how-do-you-compress-videos-6657ebd9dd28?gi=930afecec398) on video encoding.\n\n**Please please PLEASE. Never export videos from within After Effects.**\n\n## Handbrake\n\n### Summary screen\n\nWhile it's not as nice as Premiere Pro, it has way more exporting capabilities. Follow these steps to use good standard settings:\n\n1. Open your source video\n1. Select a preset corresponding to your future usage like Fast 1080p30\n1. Check Web Optimized\n1. Keep MPEG-4 as the format\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-1.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Video screen\n\n1. Keep H.264 (x264) or use H.264 nvidia nvenc if you can (crazy fast encoding by nvidia)\n1. Choose Constant Quality and try a value between 20 and 30​ (higher = smaller size but lower quality)\n1. Choose Peak Framerate. If you don't know the framerate, keep the default setting\n1. Choose the type of video you are encoding (film, animation…)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-2.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Audio screen\n\nIf you don't have audio, be sure to set the audio channel to none.\nIf you have an audio channel, these settings are great and will not influence the size much​:\n\n1. Codec AAC\n1. Samplerate 44.1\n1. Bitrate 192 to 256 (your choice)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-3.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Export!\n\nI used a RF of 25 for this example and no audio.\n\n1. My Premiere Pro video was 50,6mb\n1. My Handbrake video is 5,5mb​\n\n> What a save!\n\n​I ended up dividing the original size by 10. Which is cool.\nI tried with a RF of 30. The video was still pretty good and only 3,3mb.\n\n## Exporting for the web\n\nNow that we know how to properly compress videos, let's go further. Say we have a website with a lot of videos on the same page. We still want to load the content as fast as possible. So our videos need to be as small as possible. We won't do better than previously seen using mp4/H.264. However, we can use **webm/VP9.**\nWebm is an html video format and VP9 is its latest codec.\n\nUsing Handbrake and webm/VP9, we can achieve really great compression without losing too much quality (or none at all depending on the settings). I was able to divide by 4 the size of a video using these presets:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-4.jpg'\n\twidth='728'\n\theight='313'\n\talt=''\n/>\n\nThe only down side is that it takes some time to encode. It will depend on the video length and your computing power.\n\nI tried various settings but I read [here](https://trac.ffmpeg.org/wiki/Encode/VP9) that VP9 is supposed to be used with two-pass encoding. You then have to find the right bitrate (here 1000) for your situation.","src/content/articles/en/video-compression.mdx","5bb9f69df6c651d1","2022",{"id":827,"data":829,"body":833,"filePath":834,"digest":835,"rendered":836},{"title":660,"subtitle":830,"lang":15,"tags":831,"type":655,"slug":827,"createdAt":832},"Mise à jour 2022 de plein de trucs.",[663],["Date","2022-06-08T14:24:06.000Z"],"\u003Ca href='/articles/en-2022/' lang='en'>This content exists in english.\u003C/a>\n\nAprès deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\n\n## Les services\n\n### J’arrête le print\n\nMême si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\n\n### J’internet à fond\n\nÀ l’inverse, je passe mon temps à **faire du web.** Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer **des offres web plus précises,** dans lesquelles je me suis spécialisé.\n\nAinsi, **l’accessibilité numérique** et **l’éco-conception** deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien **mon cœur de métier.**\n\n## Le site\n\nJ’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\n\nJ’ai également fait plusieurs changements de comportements :\n\n- les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\n- j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec [cette analyse](https://twitter.com/HTeuMeuLeu/status/1370310316496728065) de [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu) ;\n- [idem pour la favicon](https://twitter.com/HTeuMeuLeu/status/1370310312214339586) ;\n- je ne déclenche les animations que si l'utilisateur n'a pas demandé au système de minimiser la quantité d'animation ou de mouvement [(référence de l'option)](https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion).\n\nJe suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> 👀).\n\n## Le Nico\n\nD’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif [Good-it!](https://www.good-it.org/) et en participant activement à son développement.\n\nJ’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.","src/content/articles/fr/2022.md","58986e0446a97cfc",{"html":837,"metadata":838},"\u003Cp>\u003Ca href=\"/articles/en-2022/\" lang=\"en\">This content exists in english.\u003C/a>\u003C/p>\n\u003Cp>Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\u003C/p>\n\u003Ch2 id=\"les-services\">Les services\u003C/h2>\n\u003Ch3 id=\"jarrête-le-print\">J’arrête le print\u003C/h3>\n\u003Cp>Même si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\u003C/p>\n\u003Ch3 id=\"jinternet-à-fond\">J’internet à fond\u003C/h3>\n\u003Cp>À l’inverse, je passe mon temps à \u003Cstrong>faire du web.\u003C/strong> Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer \u003Cstrong>des offres web plus précises,\u003C/strong> dans lesquelles je me suis spécialisé.\u003C/p>\n\u003Cp>Ainsi, \u003Cstrong>l’accessibilité numérique\u003C/strong> et \u003Cstrong>l’éco-conception\u003C/strong> deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien \u003Cstrong>mon cœur de métier.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Cp>J’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\u003C/p>\n\u003Cp>J’ai également fait plusieurs changements de comportements :\u003C/p>\n\u003Cul>\n\u003Cli>les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\u003C/li>\n\u003Cli>j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\">cette analyse\u003C/a> de \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a> ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\">idem pour la favicon\u003C/a> ;\u003C/li>\n\u003Cli>je ne déclenche les animations que si l’utilisateur n’a pas demandé au système de minimiser la quantité d’animation ou de mouvement \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion\">(référence de l’option)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>Je suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>D’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif \u003Ca href=\"https://www.good-it.org/\">Good-it!\u003C/a> et en participant activement à son développement.\u003C/p>\n\u003Cp>J’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.\u003C/p>",{"headings":839,"imagePaths":853,"frontmatter":854},[840,843,846,849,852],{"depth":30,"slug":841,"text":842},"les-services","Les services",{"depth":88,"slug":844,"text":845},"jarrête-le-print","J’arrête le print",{"depth":88,"slug":847,"text":848},"jinternet-à-fond","J’internet à fond",{"depth":30,"slug":850,"text":851},"le-site","Le site",{"depth":30,"slug":685,"text":686},[],{"title":660,"subtitle":830,"lang":15,"slug":827,"excerpt":855,"tags":856,"type":655,"createdAt":307},"Évolution des services, du site et de moi-même.",[663],{"id":175,"data":858,"body":863,"filePath":864,"digest":865,"rendered":866},{"title":694,"subtitle":859,"lang":15,"tags":860,"type":655,"slug":175,"createdAt":861,"updatedAt":862},"Mise à jour 2023.",[663],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"\u003Ca href='/articles/en-2023/' lang='en'>This content exists in english.\u003C/a>\n\nCet article sera mis à jour lorsque j'aurai des nouveautés à partager au cours de l'année 2023.\n\n## Le site\n\n### Technologies\n\nOups… je l'ai encore (re)fait.\n\nJ'ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même [en 2022 !](/articles/2022/#le-site)\n\nJe ferai certainement un ou deux articles/fragments sur Astro et les extensions que j'ai utilisées. En tout cas c'était super comme expérience. Nuxt v2 n'étant plus vraiment à jour, les performances n'étaient plus au rendez-vous. Astro a complètement corrigé ça.\n\nMon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide **95/100** sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\n\nJ'ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les `media queries`. En vrac, voici certaines améliorations que j'ai mises en place :\n\n- `flexbox` et `grid` pour adapter la mise en page aux différentes tailles d'écran ;\n- variables CSS pour les couleurs, les tailles de polices et les marges ;\n- quelques \u003Cspan lang=\"en\">`container queries`\u003C/span> pour essayer ;\n- propriétés logiques CSS (\u003Cspan lang=\"en\">`inline`\u003C/span> et \u003Cspan lang=\"en\">`block`\u003C/span> à la place de \u003Cspan lang=\"en\">`width`\u003C/span> et \u003Cspan lang=\"en\">`height`\u003C/span> par exemple).\n\nJ'en ai profité pour publier [le code source](https://git.nardu.in/nardu.in/website-astro) sur mon dépôt git.\n\n**Mise à jour #1 :** J'ai ajouté [un flux RSS](/rss.xml) car j'utilise de plus en plus le RSS sur d'autres sites web.\n\n### Suivi des visites\n\nJ’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n'était collectée et je consultais rarement les rapports.\n\nC'est sympa de voir que son site est visité, mais s'il n'y a aucun autre but derrière, c'est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j'en aurai l'utilité (autre que flatter mon égo).\n\nLes rapports de visites précédents sont consultables sur [ce lien.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Contenu\n\n- J'ai ajouté une page [références](/references/) pour lister certains de mes projets.\n- J'ai également ajouté [une page](/veille/) où je répertorie des choses intéressantes trouvées sur le web.\n\n## Projets annexes\n\nJe continue d'enseigner le développement web cette année. Afin d'étoffer mes supports de cours, j'ai mis en place un mini site de documentation disponible à l'adresse [3-w.fr](https://3-w.fr/) (adresse dont je suis très fier).\n\nIl faut que j'arrive à être plus régulier dans sa mise à jour mais j'ai bon espoir que la plateforme aide les élèves à progresser !\n\n**Plus de trucs bientôt!**","src/content/articles/fr/2023.md","ea1e7bd05f4e2599",{"html":867,"metadata":868},"\u003Cp>\u003Ca href=\"/articles/en-2023/\" lang=\"en\">This content exists in english.\u003C/a>\u003C/p>\n\u003Cp>Cet article sera mis à jour lorsque j’aurai des nouveautés à partager au cours de l’année 2023.\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oups… je l’ai encore (re)fait.\u003C/p>\n\u003Cp>J’ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même \u003Ca href=\"/articles/2022/#le-site\">en 2022 !\u003C/a>\u003C/p>\n\u003Cp>Je ferai certainement un ou deux articles/fragments sur Astro et les extensions que j’ai utilisées. En tout cas c’était super comme expérience. Nuxt v2 n’étant plus vraiment à jour, les performances n’étaient plus au rendez-vous. Astro a complètement corrigé ça.\u003C/p>\n\u003Cp>Mon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide \u003Cstrong>95/100\u003C/strong> sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\u003C/p>\n\u003Cp>J’ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les \u003Ccode>media queries\u003C/code>. En vrac, voici certaines améliorations que j’ai mises en place :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> et \u003Ccode>grid\u003C/code> pour adapter la mise en page aux différentes tailles d’écran ;\u003C/li>\n\u003Cli>variables CSS pour les couleurs, les tailles de polices et les marges ;\u003C/li>\n\u003Cli>quelques \u003Cspan lang=\"en\">\u003Ccode>container queries\u003C/code>\u003C/span> pour essayer ;\u003C/li>\n\u003Cli>propriétés logiques CSS (\u003Cspan lang=\"en\">\u003Ccode>inline\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>block\u003C/code>\u003C/span> à la place de \u003Cspan lang=\"en\">\u003Ccode>width\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>height\u003C/code>\u003C/span> par exemple).\u003C/li>\n\u003C/ul>\n\u003Cp>J’en ai profité pour publier \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">le code source\u003C/a> sur mon dépôt git.\u003C/p>\n\u003Cp>\u003Cstrong>Mise à jour #1 :\u003C/strong> J’ai ajouté \u003Ca href=\"/rss.xml\">un flux RSS\u003C/a> car j’utilise de plus en plus le RSS sur d’autres sites web.\u003C/p>\n\u003Ch3 id=\"suivi-des-visites\">Suivi des visites\u003C/h3>\n\u003Cp>J’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n’était collectée et je consultais rarement les rapports.\u003C/p>\n\u003Cp>C’est sympa de voir que son site est visité, mais s’il n’y a aucun autre but derrière, c’est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j’en aurai l’utilité (autre que flatter mon égo).\u003C/p>\n\u003Cp>Les rapports de visites précédents sont consultables sur \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">ce lien.\u003C/a>\u003C/p>\n\u003Ch3 id=\"contenu\">Contenu\u003C/h3>\n\u003Cul>\n\u003Cli>J’ai ajouté une page \u003Ca href=\"/references/\">références\u003C/a> pour lister certains de mes projets.\u003C/li>\n\u003Cli>J’ai également ajouté \u003Ca href=\"/veille/\">une page\u003C/a> où je répertorie des choses intéressantes trouvées sur le web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"projets-annexes\">Projets annexes\u003C/h2>\n\u003Cp>Je continue d’enseigner le développement web cette année. Afin d’étoffer mes supports de cours, j’ai mis en place un mini site de documentation disponible à l’adresse \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (adresse dont je suis très fier).\u003C/p>\n\u003Cp>Il faut que j’arrive à être plus régulier dans sa mise à jour mais j’ai bon espoir que la plateforme aide les élèves à progresser !\u003C/p>\n\u003Cp>\u003Cstrong>Plus de trucs bientôt!\u003C/strong>\u003C/p>",{"headings":869,"imagePaths":881,"frontmatter":882},[870,871,872,875,878],{"depth":30,"slug":850,"text":851},{"depth":88,"slug":708,"text":709},{"depth":88,"slug":873,"text":874},"suivi-des-visites","Suivi des visites",{"depth":88,"slug":876,"text":877},"contenu","Contenu",{"depth":30,"slug":879,"text":880},"projets-annexes","Projets annexes",[],{"title":694,"subtitle":859,"lang":15,"slug":175,"excerpt":883,"tags":884,"type":655,"createdAt":723,"updatedAt":724},"Suite des évolutions.",[663],"after-effects-expressions",{"id":885,"data":887,"body":891,"filePath":892,"digest":893,"rendered":894},{"title":750,"subtitle":888,"lang":15,"tags":889,"type":655,"slug":885,"createdAt":890,"draft":202},"En cours de traduction, revenez bientôt ;)",[753],["Date","2019-04-24T09:00:00.000Z"],"[Retour aux articles](/articles)","src/content/articles/fr/after-effects-expressions.md","884d725859a7bab5",{"html":895,"metadata":896},"\u003Cp>\u003Ca href=\"/articles\">Retour aux articles\u003C/a>\u003C/p>",{"headings":897,"imagePaths":898,"frontmatter":899},[],[],{"title":750,"subtitle":888,"lang":15,"draft":202,"slug":885,"excerpt":888,"tags":900,"type":655,"createdAt":901},[753],"2019-04-24T09:00:00.000Z","gratuiste",{"id":902,"data":904,"body":910,"filePath":911,"digest":912,"rendered":913},{"title":778,"subtitle":905,"lang":15,"tags":906,"type":655,"slug":902,"createdAt":908,"updatedAt":909},"Ou le travail gratuit.",[907,663],"Graphisme",["Date","2017-05-27T07:47:36.000Z"],["Date","2022-12-27T15:36:06.000Z"],"## Gratuiste, qu’est-ce que c’est ?\n\nDans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc. \nDe plus en plus, la communauté s’élève contre ces pratiques et les [dénonce.](https://twitter.com/PayeTonAffiche)\n\n> “ On n’est pas des gratuistes ! ”\n\nComprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez [cette vidéo](https://youtu.be/essNmNOrQto) qui transpose ces pratiques à des métiers “ standards ” et [celle-ci](https://youtu.be/DsstOs-K7gk) qui explique en détails le processus actuel.\n\n## T’es débile du coup ?\n\nJ’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\n\nÉtant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre. \nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\n\n## Le concept\n\nJe compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux. \nCe type de prestation porte le nom de “ **pro bono publico** ” – “ **pour le bien public** ”.\n\nCette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\n\n> Graphiste pro bono, pourquoi pas ?\n\n## Quels genres de services ?\n\nEn toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\n\n### En résumé :\n\n- maquette de site web\n- intégration front-end (en dur ou via wordpress) du site\n- gestion de la mise en ligne du site\n- newsletter (design et/ou intégration)\n- flyers\n- autres petites demandes\n\nVous pouvez avoir un aperçu de mon travail [sur ce même site.](/) J’ai déjà eu l’occasion de travailler pour :\n\n- [Cygnal](/projets/cygnal)\n- [OpenMole](https://openmole.org/)\n- [Good-it](https://good-it.org)\n\n## Dans quelles conditions ?\n\n- l’association doit être active\n- elle doit porter des valeurs que je partage\n- elle doit pouvoir me montrer ses actions\n- elle ne doit pas avoir les moyens de se payer un graphiste\n\n## C’est un peu trop beau pour être vrai ton truc…\n\nIl faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\n\nSi vous êtes intéressés, [envoyez-moi un mail !](mailto:contac@nardu.in)\n\n## Qu’est-ce que t’y gagnes toi ?\n\nSimplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.","src/content/articles/fr/gratuiste.md","80c20493583a842c",{"html":914,"metadata":915},"\u003Ch2 id=\"gratuiste-quest-ce-que-cest\">Gratuiste, qu’est-ce que c’est ?\u003C/h2>\n\u003Cp>Dans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc.\u003Cbr>\nDe plus en plus, la communauté s’élève contre ces pratiques et les \u003Ca href=\"https://twitter.com/PayeTonAffiche\">dénonce.\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“ On n’est pas des gratuistes ! ”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Comprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez \u003Ca href=\"https://youtu.be/essNmNOrQto\">cette vidéo\u003C/a> qui transpose ces pratiques à des métiers “ standards ” et \u003Ca href=\"https://youtu.be/DsstOs-K7gk\">celle-ci\u003C/a> qui explique en détails le processus actuel.\u003C/p>\n\u003Ch2 id=\"tes-débile-du-coup\">T’es débile du coup ?\u003C/h2>\n\u003Cp>J’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\u003C/p>\n\u003Cp>Étant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre.\u003Cbr>\nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\u003C/p>\n\u003Ch2 id=\"le-concept\">Le concept\u003C/h2>\n\u003Cp>Je compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux.\u003Cbr>\nCe type de prestation porte le nom de “ \u003Cstrong>pro bono publico\u003C/strong> ” – “ \u003Cstrong>pour le bien public\u003C/strong> ”.\u003C/p>\n\u003Cp>Cette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Graphiste pro bono, pourquoi pas ?\u003C/p>\n\u003C/blockquote>\n\u003Ch2 id=\"quels-genres-de-services\">Quels genres de services ?\u003C/h2>\n\u003Cp>En toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\u003C/p>\n\u003Ch3 id=\"en-résumé\">En résumé :\u003C/h3>\n\u003Cul>\n\u003Cli>maquette de site web\u003C/li>\n\u003Cli>intégration front-end (en dur ou via wordpress) du site\u003C/li>\n\u003Cli>gestion de la mise en ligne du site\u003C/li>\n\u003Cli>newsletter (design et/ou intégration)\u003C/li>\n\u003Cli>flyers\u003C/li>\n\u003Cli>autres petites demandes\u003C/li>\n\u003C/ul>\n\u003Cp>Vous pouvez avoir un aperçu de mon travail \u003Ca href=\"/\">sur ce même site.\u003C/a> J’ai déjà eu l’occasion de travailler pour :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"/projets/cygnal\">Cygnal\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://openmole.org/\">OpenMole\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://good-it.org\">Good-it\u003C/a>\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"dans-quelles-conditions\">Dans quelles conditions ?\u003C/h2>\n\u003Cul>\n\u003Cli>l’association doit être active\u003C/li>\n\u003Cli>elle doit porter des valeurs que je partage\u003C/li>\n\u003Cli>elle doit pouvoir me montrer ses actions\u003C/li>\n\u003Cli>elle ne doit pas avoir les moyens de se payer un graphiste\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"cest-un-peu-trop-beau-pour-être-vrai-ton-truc\">C’est un peu trop beau pour être vrai ton truc…\u003C/h2>\n\u003Cp>Il faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\u003C/p>\n\u003Cp>Si vous êtes intéressés, \u003Ca href=\"mailto:contac@nardu.in\">envoyez-moi un mail !\u003C/a>\u003C/p>\n\u003Ch2 id=\"quest-ce-que-ty-gagnes-toi\">Qu’est-ce que t’y gagnes toi ?\u003C/h2>\n\u003Cp>Simplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.\u003C/p>",{"headings":916,"imagePaths":941,"frontmatter":942},[917,920,923,926,929,932,935,938],{"depth":30,"slug":918,"text":919},"gratuiste-quest-ce-que-cest","Gratuiste, qu’est-ce que c’est ?",{"depth":30,"slug":921,"text":922},"tes-débile-du-coup","T’es débile du coup ?",{"depth":30,"slug":924,"text":925},"le-concept","Le concept",{"depth":30,"slug":927,"text":928},"quels-genres-de-services","Quels genres de services ?",{"depth":88,"slug":930,"text":931},"en-résumé","En résumé :",{"depth":30,"slug":933,"text":934},"dans-quelles-conditions","Dans quelles conditions ?",{"depth":30,"slug":936,"text":937},"cest-un-peu-trop-beau-pour-être-vrai-ton-truc","C’est un peu trop beau pour être vrai ton truc…",{"depth":30,"slug":939,"text":940},"quest-ce-que-ty-gagnes-toi","Qu’est-ce que t’y gagnes toi ?",[],{"title":778,"subtitle":905,"lang":15,"slug":902,"excerpt":943,"tags":944,"type":655,"createdAt":789,"updatedAt":945},"J’ai cherché un moyen de mettre mes compétences au service d’autrui et je pense avoir trouvé: je vais travailler gratuitement pour des associations.",[907,663],"2022-12-27T15:36:06.000Z","sci-hub-blocage",{"id":946,"data":948,"body":954,"filePath":955,"digest":956,"deferredRender":202},{"title":949,"subtitle":950,"lang":15,"tags":951,"type":655,"slug":946,"createdAt":952,"updatedAt":953},"Sci-hub bloqué, comment contourner","La science du partage.",[796,797],["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n\u003Ca href='/articles/en-sci-hub-unblock/' lang='en'>This content exists in english.\u003C/a>\n\nL'adresse actuelle de sci-hub est : \u003Ca href=\"https://www.sci-hub.st/\" rel=\"noreferer noopener\">sci-hub.st\u003C/a>\n\n## Résumé de la situation\n\nN’étant pas moi-même directement chercheur, je vous laisse regarder [cette vidéo](https://youtu.be/rcgxY__YXEc) explicative extrêmement bien faite sur le sujet de la publication scientifique.\n\n> “ Mais c’est scandaleux ! ”​\n\nJ’ai constaté que le blocage était actif chez SFR. Je n’ai pas encore pu vérifier pour les autres fournisseurs mais j’imagine qu’ils se sont tous conformés à la décision de justice.\nLe blocage mis en place est assez basique. Il s’agit d’un blocage “ DNS ”.\n\nUn DNS est un serveur qui sert à faire le lien entre un nom de domaine : **sci-hub.tw** et une adresse IP : **186.2.163.90**.\n\nC’est en quelque sorte l’annuaire d’internet. Sans l’adresse, impossible de contacter le domaine. Ce que les FAI ont certainement fait : bloquer les requêtes au nom de domaine [sci-hub.se.](http://sci-hub.se/) Ainsi, aucune adresse IP n’est renvoyée et le site n’est pas accessible.\n\n## Comment contourner ce blocage ?\n\n- Soit en utilisant un VPN\n- Soit en modifiant les serveurs DNS de vos ordinateurs/box internet\n\nJe recommande la deuxième solution car elle permet de se prémunir contre de futurs blocages/filtrages/censures de la part de votre FAI et ne nécessite pas de contrepartie financière.\nJe vais me focaliser sur le changement depuis un ordinateur car il sera effectif où que vous soyez.\n\n### Sur MacOs\n\nOuvrez :\n\n1. Préférences système\n1. Réseau\n1. Ethernet et/ou Wi-fi\n1. Avancé\n1. DNS\n1. Serveurs DNS\n\nDe là, vous pouvez ajouter des serveurs DNS en cliquant sur l'icône +. Cliquez sur ok et appliquez les nouveaux paramètres. Vous devrez peut-être redémarrer votre ordinateur pour que les changements fonctionnent.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS réglages réseau et DNS'\n/>\n\n### Sur Windows (ici 10)\n\nOuvrez :\n\n1. Réglages\n1. Réseau et internet\n1. Modifier les options de l'adaptateur\n1. Clic droit sur les propriétés de votre interface réseau\n1. Selectionnez « protocole Internet version 4 » (et/ou 6)\n1. Propriétés\n1. Utiliser l’adresse de serveur DNS suivante\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Réglages windows'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows réglages réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows régalges connections réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows options adaptateur réseau'\n/>\n\n## Quels serveurs DNS utiliser ?\n\nIl y a de nombreux serveurs DNS accessibles. Les plus connus étant ceux de Google, Cloudflare et OpenDNS. Si vous tenez vraiment à utiliser ceux de Google, je vous laisse chercher leur adresse. Voici mes recommandations par ordre de préférence.\n\nPlusieurs fournisseurs :\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMes favoris puisqu’il s’agit d’une [association française.](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net/fr)\n\nQuand9 est une fondation à but non lucratif proposant des serveurs DNS publics et gratuits. Leurs serveur classiques offrent un filtrage de domaines malveillants identifiés. Ils ne collectent pas de données et sont conforment au \u003Cabbr title=\"Règlement général sur la protection des données\">RGPD\u003C/abbr>.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## C'est tout.\n\nEn modifiant ces réglages, vous vous affranchissez de vos fournisseurs d’accès et de leurs règles de filtrage du contenu.\n\nPour l’instant, ces blocages sont presque symboliques car si Sci-hub venait à changer d’url, le blocage ne fonctionnerait plus. Mais la victoire des éditeurs au tribunal montre qu’ils n’ont pas dit leur dernier mot. Nous ne sommes donc pas à l’abri d’un futur blocage plus large et plus dur à contrer.\n\nSi vous voulez en apprendre plus sur le combat de ces gens qui se battent pour que la recherche ne soit pas une marchandise, je vous conseille [ce documentaire](https://youtu.be/y_CQATGOX2w) sur Aaron Shwartz. Ou plus simplement [cet article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) sur la fondatrice de Sci-hub.\n\nEn attendant, bonnes lectures à tou·te·s. On est avec vous !","src/content/articles/fr/sci-hub-blocage.mdx","f7b5a20f2a594ef2","the-day-I-jamd",{"id":957,"data":959,"body":964,"filePath":965,"digest":966,"deferredRender":202},{"title":806,"subtitle":960,"lang":15,"tags":961,"type":655,"slug":957,"createdAt":962,"updatedAt":963},"Des paris, des outils et du fun.",[809,810],["Date","2020-10-08T07:47:36.000Z"],["Date","2022-12-27T15:40:06.000Z"],"\u003Ca href='/articles/en-the-day-I-jamd/' lang='en'>This content exists in english.\u003C/a>\n\nimport AstroImage from '../../../components/AstroImage.astro'\n\n## La solution de non facilité\n\nLorsque j’utilisais encore Wordpress pour mon site web personnel, j’ai voulu essayer le serveur web \u003Ca href=\"https://openlitespeed.org\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">OpenLiteSpeed (en anglais)\u003C/a>. En tant que designer, j’ai toujours aimé avoir une interface graphique et j’avais entendu dire qu’OLS jouissait de bonnes performances en général et de cache en particulier.\n\n## Battez-vous!\n\nQuelques années plus tard, je découvrais l’univers Jamstack et son incroyable potentiel. N’étant pas du tout impulsif, j’ai choisi de refaire entièrement mon site web avec des outils comme \u003Ca href=\"https://www.11ty.dev/\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">11ty (en anglais)\u003C/a> et \u003Ca href=\"https://strapi.io/\" hreflang=\"en\">Strapi (en anglais)\u003C/a>.\n\nJe me souviens que Strapi était encore en alpha/beta et que certains collègues me disaient que c’était un pari risqué, surtout que je découvrais à peine le monde de node.js.\n\n> Open source et français ? Je dis banco !\n\nJ’ai donc commencé à recréer mon site web à l’identique avec 11ty et Strapi. Même hébergement chez Digital Ocean, même serveur web, même contenu. J’avais fait pas mal d’optimisations de performances sur mon installation wordpress, j’étais donc impatient de comparer les résultats avec la nouvelle version statique.\n\nJ’en suis resté pantois ! Quasiment sans optimisation du côté statique, j’ai obtenu les résultats ci-dessous.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 53/100 sur Wordpress.'\n/>\n\nMalgré beaucoup d’efforts, je n’ai pas pu faire mieux. Je ne suis pas un expert en cache, je n’utilise pas de CDN et je me suis appuyé sur des plugins pour réaliser beaucoup de choses (php n’étant pas ma spécialité 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 97/100 en Jamstack.'\n/>\n\nPresque **zéro** configuration spéciale (j’étais trop impatient de tester) et j’ai atteint un score impressionnant. Je sais que les scores lighthouse ne font pas tout mais **53 contre 97**… Ça me va !\n\n## Embrassez-vous 🥰\n\nCes deux approches ont leurs avantages et leurs inconvénients. En tant que freelance, mes clients préfèrent ou demandent souvent Wordpress en raison de sa réputation. Je présente toujours une alternative Jamstack lorsque c’est possible, mais cela reste effrayant la plupart du temps par rapport à Wordpress. Je pense cependant qu’il sera plus facile d’utiliser la Jamstack avec le temps.\n\n## Encore et encore…\n\nNous voici maintenant une quarantaine et quelques mois plus tard et ce site fonctionne avec… [Nuxt.js](https://fr.nuxtjs.org/). Je sais, je suis désolé, je n’ai pas pu résister à la dernière fonctionnalité [\u003Cspan lang=\"en\">nuxt content\u003C/span>](https://content.nuxtjs.org/fr) de Nuxt.\n\nDu coup j’ai tout refait… et laissez-moi vous dire : **wow**, quelle expérience !\nJ’adore développer avec Nuxt. L’utilisation de \u003Cspan lang=\"en\">nuxt content\u003C/span> m’a permis de me concentrer sur le design et, évidemment, sur le contenu.\nPlus de client Apollo ni de requête graphQL, seulement du \u003Cspan lang=\"en\">markdown\u003C/span> et quelques promesses.\n\nAttention, j’aime beaucoup travailler avec Strapi et son interface graphQL mais pour les besoins de ce site, \u003Cspan lang=\"en\">nuxt content\u003C/span> fait le \u003Cspan lang=\"en\">job\u003C/span> (extrêmement bien).\n\nJ’utilise toujours Strapi pour téléverser, stocker et gérer les images, vidéos, gifs, etc. C’est peut-être trop pour ce que j’en fait mais j’aime savoir que je peux toujours y revenir si j’ai envie ! De plus, j’ai passé pas mal de temps à le mettre en place avec \u003Cspan lang=\"en\">OpenLiteSpeed\u003C/span> et je suis encore trop attaché à cette réussite pour la laisser tomber.\n\n## Et en fait à la fin\n\nWordpress, Jamstack, fait main… Est-ce vraiment important ? Pour moi, l’expérience de développement a été bien plus agréable en travaillant avec 11ty, nuxt.js et strapi qu’avec Wordpress.\n\nDu point de vue de la performance et de l’accessibilité, il semble également que ce soit le choix le plus judicieux. Ce n’est peut-être pas le cas à chaque fois ! ¯\\\\\\_(ツ)\\_/¯\n\nJ’ai hâte d’apprendre \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> et de tout recommencer à zéro !","src/content/articles/fr/the-day-I-jamd.mdx","b474c8ff88ed0b47","video-compression",{"id":967,"data":969,"body":891,"filePath":974,"digest":975,"rendered":976},{"title":970,"subtitle":888,"lang":15,"tags":971,"type":655,"slug":967,"createdAt":972,"updatedAt":973,"draft":202},"Compression vidéo",[753],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"src/content/articles/fr/video-compression.md","2296c41874b23b3d",{"html":895,"metadata":977},{"headings":978,"imagePaths":979,"frontmatter":980},[],[],{"title":970,"subtitle":888,"lang":15,"draft":202,"slug":967,"excerpt":981,"tags":982,"type":655,"createdAt":983,"updatedAt":307},"Pas encore traduit",[753],"2021-05-05T09:00:00.000Z","faq",{"id":984,"data":986,"body":991,"filePath":992,"digest":993,"rendered":994},{"title":987,"subtitle":988,"lang":15,"tags":989,"type":655,"slug":984,"createdAt":990},"Accessibilité, sobriété et F.A.Q.","Explications sur ma vision et mon fonctionnement.",[663],["Date","2022-06-22T15:34:45.000Z"],"## l'Accessibilité\n\n### Quèsaco ?\n\nD'après [access42 :](https://access42.net)\n\n> L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\n\nAinsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que **n'importe quel visiteur** puisse l'utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais **ce n'est pas le cas !**\n\nLorsqu'un site est pensé et conçu avec l'accessibilité en tête, il ne prend **pas plus de temps** qu'un projet qui ne le fait pas. En revanche, **corriger** un site existant qui n'a pas bénéficié de cette réflexion en amont **demande beaucoup plus d'efforts.**\n\n### Pourquoi c'est important ?\n\nAprès avoir été sensibilisé à l'accessibilité et aux [situations frustrantes voire bloquantes](https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles) que rencontrent les personnes handicapées sur le web, j'ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m'a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\n\n## l'Éco-conception\n\n### Quèsaco ?\n\nD'après le collectif [\u003Cspan lang=\"en\">green it\u003C/span> :](https://www.greenit.fr)\n\n> L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\n\nIl s'agit ici pour moi de créer des produits les plus sobres possibles. C'est-à-dire de développer ou d'utiliser une fonctionnalité uniquement si elle est indispensable.\n\nPar exemple, mettre en place **un formulaire de contact** sur un site web implique plusieurs choses :\n\n- développer un formulaire\n- envoyer les données au serveur\n- vérifier les données envoyées\n- envoyer les données par mail\n- confirmer l'envoi du mail (en fournissant une copie)\n- gérer les erreurs à chaque étape\n\nUn site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d'effectuer ces opérations (ou un prestataire qui s'en charge). C'est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu'un formulaire. Dans le cas d'un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\n\n### Pourquoi c'est important ?\n\nL'éco-conception fait beaucoup de bien à la qualité globale d'un site et à l'expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\n\n## F.A.Q.\n\n### Cette démarche est-elle opportuniste ?\n\n**Non.** Il est vrai que l'accessibilité et, surtout, l'éco-conception, commencent à être « tendance ». On pourrait donc croire que j'en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c'est ma responsabilité de créer des sites web accessibles et éco-conçus **par défaut.**\n\n### Un site accessible est-il plus cher ?\n\n**Oui et non.** Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l'accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j'augmente mes tarifs suite à l'obtention de certifications relatives à mon activité.\n\n### Mon site sera-t-il 100 % accessible ?\n\n**Non,** je ne suis pas en mesure de garantir ou de certifier la conformité totale d'un site au [référentiel général d'amélioration de l'accessibilité.](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d'un site. Cependant, je peux vous accompagner avant et après l'audit afin d'anticiper puis de corriger les critères d'accessibilité requis. [Access42](https://access42.net/) et [Tanaguru](https://www.tanaguru.com/) font parties de ces entreprises spécialisées.\n\n### Pourquoi ne pas utiliser un outil automatique ?\n\nCar ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom [sous peine de procès](https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/)), ne sont pas des solutions micracles. Lisez [cet article](https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/) d'une experte en accessibilité et/ou [ce test](https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/) de différents outils pour en savoir plus.\n\n### Un site éco-conçu et accessible peut-il être beau ?\n\n**Oui, évidemment.** Je vous laisse juger par vous-même avec [cette liste](https://lowww.directory/) de sites éco-conçus. En ce qui concerne l'accessibilité, elle n'impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d'un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l'utilisation d'un produit.","src/content/articles/fr/faq.md","65e9e60bcd00806c",{"html":995,"metadata":996},"\u003Ch2 id=\"laccessibilité\">l’Accessibilité\u003C/h2>\n\u003Ch3 id=\"quèsaco\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après \u003Ca href=\"https://access42.net\">access42 :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Ainsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que \u003Cstrong>n’importe quel visiteur\u003C/strong> puisse l’utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais \u003Cstrong>ce n’est pas le cas !\u003C/strong>\u003C/p>\n\u003Cp>Lorsqu’un site est pensé et conçu avec l’accessibilité en tête, il ne prend \u003Cstrong>pas plus de temps\u003C/strong> qu’un projet qui ne le fait pas. En revanche, \u003Cstrong>corriger\u003C/strong> un site existant qui n’a pas bénéficié de cette réflexion en amont \u003Cstrong>demande beaucoup plus d’efforts.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>Après avoir été sensibilisé à l’accessibilité et aux \u003Ca href=\"https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles\">situations frustrantes voire bloquantes\u003C/a> que rencontrent les personnes handicapées sur le web, j’ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m’a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\u003C/p>\n\u003Ch2 id=\"léco-conception\">l’Éco-conception\u003C/h2>\n\u003Ch3 id=\"quèsaco-1\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après le collectif \u003Ca href=\"https://www.greenit.fr\">\u003Cspan lang=\"en\">green it\u003C/span> :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Il s’agit ici pour moi de créer des produits les plus sobres possibles. C’est-à-dire de développer ou d’utiliser une fonctionnalité uniquement si elle est indispensable.\u003C/p>\n\u003Cp>Par exemple, mettre en place \u003Cstrong>un formulaire de contact\u003C/strong> sur un site web implique plusieurs choses :\u003C/p>\n\u003Cul>\n\u003Cli>développer un formulaire\u003C/li>\n\u003Cli>envoyer les données au serveur\u003C/li>\n\u003Cli>vérifier les données envoyées\u003C/li>\n\u003Cli>envoyer les données par mail\u003C/li>\n\u003Cli>confirmer l’envoi du mail (en fournissant une copie)\u003C/li>\n\u003Cli>gérer les erreurs à chaque étape\u003C/li>\n\u003C/ul>\n\u003Cp>Un site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d’effectuer ces opérations (ou un prestataire qui s’en charge). C’est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu’un formulaire. Dans le cas d’un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important-1\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>L’éco-conception fait beaucoup de bien à la qualité globale d’un site et à l’expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\u003C/p>\n\u003Ch2 id=\"faq\">F.A.Q.\u003C/h2>\n\u003Ch3 id=\"cette-démarche-est-elle-opportuniste\">Cette démarche est-elle opportuniste ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non.\u003C/strong> Il est vrai que l’accessibilité et, surtout, l’éco-conception, commencent à être « tendance ». On pourrait donc croire que j’en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c’est ma responsabilité de créer des sites web accessibles et éco-conçus \u003Cstrong>par défaut.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"un-site-accessible-est-il-plus-cher\">Un site accessible est-il plus cher ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui et non.\u003C/strong> Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l’accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j’augmente mes tarifs suite à l’obtention de certifications relatives à mon activité.\u003C/p>\n\u003Ch3 id=\"mon-site-sera-t-il-100-accessible\">Mon site sera-t-il 100 % accessible ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non,\u003C/strong> je ne suis pas en mesure de garantir ou de certifier la conformité totale d’un site au \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité.\u003C/a> Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d’un site. Cependant, je peux vous accompagner avant et après l’audit afin d’anticiper puis de corriger les critères d’accessibilité requis. \u003Ca href=\"https://access42.net/\">Access42\u003C/a> et \u003Ca href=\"https://www.tanaguru.com/\">Tanaguru\u003C/a> font parties de ces entreprises spécialisées.\u003C/p>\n\u003Ch3 id=\"pourquoi-ne-pas-utiliser-un-outil-automatique\">Pourquoi ne pas utiliser un outil automatique ?\u003C/h3>\n\u003Cp>Car ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom \u003Ca href=\"https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/\">sous peine de procès\u003C/a>), ne sont pas des solutions micracles. Lisez \u003Ca href=\"https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/\">cet article\u003C/a> d’une experte en accessibilité et/ou \u003Ca href=\"https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/\">ce test\u003C/a> de différents outils pour en savoir plus.\u003C/p>\n\u003Ch3 id=\"un-site-éco-conçu-et-accessible-peut-il-être-beau\">Un site éco-conçu et accessible peut-il être beau ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui, évidemment.\u003C/strong> Je vous laisse juger par vous-même avec \u003Ca href=\"https://lowww.directory/\">cette liste\u003C/a> de sites éco-conçus. En ce qui concerne l’accessibilité, elle n’impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d’un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l’utilisation d’un produit.\u003C/p>",{"headings":997,"imagePaths":1031,"frontmatter":1032},[998,1001,1004,1007,1010,1012,1014,1016,1019,1022,1025,1028],{"depth":30,"slug":999,"text":1000},"laccessibilité","l’Accessibilité",{"depth":88,"slug":1002,"text":1003},"quèsaco","Quèsaco ?",{"depth":88,"slug":1005,"text":1006},"pourquoi-cest-important","Pourquoi c’est important ?",{"depth":30,"slug":1008,"text":1009},"léco-conception","l’Éco-conception",{"depth":88,"slug":1011,"text":1003},"quèsaco-1",{"depth":88,"slug":1013,"text":1006},"pourquoi-cest-important-1",{"depth":30,"slug":984,"text":1015},"F.A.Q.",{"depth":88,"slug":1017,"text":1018},"cette-démarche-est-elle-opportuniste","Cette démarche est-elle opportuniste ?",{"depth":88,"slug":1020,"text":1021},"un-site-accessible-est-il-plus-cher","Un site accessible est-il plus cher ?",{"depth":88,"slug":1023,"text":1024},"mon-site-sera-t-il-100-accessible","Mon site sera-t-il 100 % accessible ?",{"depth":88,"slug":1026,"text":1027},"pourquoi-ne-pas-utiliser-un-outil-automatique","Pourquoi ne pas utiliser un outil automatique ?",{"depth":88,"slug":1029,"text":1030},"un-site-éco-conçu-et-accessible-peut-il-être-beau","Un site éco-conçu et accessible peut-il être beau ?",[],{"title":987,"subtitle":988,"lang":15,"slug":984,"excerpt":1033,"tags":1034,"type":655,"createdAt":272},"Pourquoi, comment et surtout quèsaco.",[663]] \ No newline at end of file diff --git a/astro.config.mjs b/astro.config.mjs index c7cb327..091d271 100755 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -11,28 +11,6 @@ export default defineConfig({ build: { format: 'directory' }, - redirects: { - '/en/': { - status: 308, - destination: '/articles/en-2025' - }, - '/articles/en/': { - status: 308, - destination: '/articles/#en-articles' - }, - '/articles/en/[...id]': { - status: 308, - destination: '/articles/en-[...id]' - }, - '/snippets/en/': { - status: 308, - destination: '/fragments/#en-fragments' - }, - '/snippets/en/[...id]': { - status: 308, - destination: '/fragments/en-[...id]' - } - }, image: { domains: ['assets.nardu.in'], remotePatterns: [{ protocol: 'https' }] diff --git a/src/components/CardEditorial.astro b/src/components/CardEditorial.astro index bd0da71..626e1b0 100755 --- a/src/components/CardEditorial.astro +++ b/src/components/CardEditorial.astro @@ -7,7 +7,7 @@ const { item, routeName } = Astro.props const isReference = routeName === 'references' --- -<div class:list={['card', { 'card--link': !isReference }]}> +<div class='card'> <h3> { !isReference ? ( @@ -44,58 +44,73 @@ const isReference = routeName === 'references' box-shadow: var(--shadow-elevation-medium); background-color: white; } - /* - * to be replaced with .card:has(a) - * when firefox supports it - */ - .card--link:hover { - box-shadow: var(--shadow-elevation-high); - } - .card--link:focus-within { - box-shadow: var(--shadow-elevation-high); - } - .card--link::after { - content: ''; - position: absolute; - inline-size: 30px; - block-size: 30px; - top: var(--space-m); - right: var(--space-s); - opacity: 0; - background-image: url('/assets/svg/arrow-right.svg'); - background-repeat: no-repeat; - background-position: center; - background-size: contain; - transform: translateX(1rem); - } - .card--link:hover::after, - .card--link:focus-within::after { - transform: translateX(0); - opacity: 1; - } - .card--link:hover h3 a { - text-decoration: underline; - } - .card--link:hover h3 a, - .card--link:focus-within h3 a { - color: var(--color-brique); - } - .card--link::before { - content: ''; - position: absolute; - top: 0; - left: 0; - bottom: 0; - block-size: 100%; - inline-size: 2px; - transform: scaleY(0); - transform-origin: bottom; - background-color: var(--color-brique); - } - .card--link:hover::before, - .card--link:focus-within::before { - transform: scaleY(1); - transform-origin: top; + + /* selects card that do not have an external link */ + .card:not(:has([rel='noopener noreferer'])) { + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + bottom: 0; + block-size: 100%; + inline-size: 2px; + transform: scaleY(0); + transform-origin: bottom; + background-color: var(--color-brique); + } + + &::after { + content: ''; + position: absolute; + inline-size: 30px; + block-size: 30px; + top: var(--space-m); + right: var(--space-s); + opacity: 0; + background-image: url('/assets/svg/arrow-right.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + transform: translateX(1rem); + } + + &:hover, + &:focus-within { + box-shadow: var(--shadow-elevation-high); + + &::before { + transform: scaleY(1); + transform-origin: top; + } + + &::after { + transform: translateX(0); + opacity: 1; + } + + h3 a { + text-decoration: underline; + color: var(--color-brique); + } + } + + @media (prefers-reduced-motion: no-preference) { + & { + transition: box-shadow 0.2s ease; + } + &::before { + transition: transform 0.2s ease-in-out; + } + &::after { + transition: + opacity ease 0.2s, + transform ease 0.2s; + } + h3 a { + transition: color ease 0.2s; + } + } } h3 { @@ -112,25 +127,6 @@ const isReference = routeName === 'references' position: absolute; inset: 0; } - @media (prefers-reduced-motion: no-preference) { - .card { - transition: box-shadow 0.2s ease; - } - .card::before { - transition: transform 0.2s ease-in-out; - } - .card::after { - transition: - opacity ease 0.2s, - transform ease 0.2s; - } - .card--link { - view-transition-name: var(--slug); - } - h3 a { - transition: color ease 0.2s; - } - } .card h4 { margin-block-start: var(--space-2xs); diff --git a/src/components/Footer.astro b/src/components/Footer.astro index 5c943e0..ffffdae 100755 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -1,26 +1,19 @@ -<footer class='footer' role='contentinfo'> - <section class='flow'> - <p>Nicolas Arduin</p> - <p>Développeur web spécialisé en accessibilité.</p> +--- +import SocialRel from '../components/SocialRel.astro' +--- + +<footer class='footer wrapper' role='contentinfo'> + <section class='info'> + <div> + <p class='h4'>Nicolas Arduin</p> + <p>Développeur web spécialisé en accessibilité.</p> + </div> <ul class='flow' role='list'> - <li> - <a - href='mailto:contact@nardu.in' - title='Envoyez-moi un mail (ouverture du logiciel automatique).' - >contact@nardu.in</a - > - </li> - <li> - <a - href='tel:+33749464239' - title='Contactez-moi par téléphone (ouverture du logiciel automatique)' - >+337 49 46 42 39</a - > - </li> <li><a href='/veille'>Veille</a></li> <li><a href='/plan-du-site'>Plan du site</a></li> - <li><a href='/"rss.xml'>RSS</a></li> + <li><a href='/rss.xml'>RSS</a></li> </ul> + <SocialRel /> </section> </footer> @@ -39,4 +32,12 @@ font-weight: 500; color: var(--color-blue); } + + .info { + display: flex; + flex-flow: row wrap; + justify-content: space-between; + gap: var(--space-s); + text-align: left; + } </style> diff --git a/src/components/Head.astro b/src/components/Head.astro index 20ac5ed..d01f809 100755 --- a/src/components/Head.astro +++ b/src/components/Head.astro @@ -5,9 +5,15 @@ const { pageTitle } = Astro.props <head> <meta charset='utf-8' /> <link rel='icon' type='image/svg+xml' href='/favicon.svg' /> + <link + rel='alternate' + type='application/rss+xml' + title='Nicolas Arduin' + href={new URL('rss.xml', Astro.site)} + /> <meta http-equiv='X-UA-Compatible' content='IE=edge' /> <meta name='viewport' content='width=device-width, initial-scale=1.0' /> - <title>{pageTitle} - Nicolas Arduin + {pageTitle} | Nicolas Arduin - + diff --git a/src/components/SocialRel.astro b/src/components/SocialRel.astro new file mode 100644 index 0000000..376449e --- /dev/null +++ b/src/components/SocialRel.astro @@ -0,0 +1,12 @@ + diff --git a/src/content/articles/en/2025.md b/src/content/articles/en/2025.md index fd350bf..d66c957 100644 --- a/src/content/articles/en/2025.md +++ b/src/content/articles/en/2025.md @@ -1,13 +1,18 @@ --- title: Nico v3.0 -subtitle: Update 2025. +subtitle: This website no longer has an english version.. lang: en -slug: en-2023 -excerpt: So long i18n +slug: en-2025 +excerpt: This website no longer has an english version. tags: ['Freelance'] type: articles +createdAt: '2025-01-02T17:41:00.000Z' --- -## This website no longer has an english version. +## So long lang="en" -I have maintained an english version of my website for some years. But the +I have maintained an english version of my website for some years but **no more…** The effort needed to make a fully multilingual website with Astro is just too much work for my small personal website. + +**All previous content will remain online** ([articles](/articles/#en-articles) and [snippets](/fragments/#en-fragments)) but the interface and internal pages will only be in french. + +I do not have any metrics on who visits my website but I don't think it will be missed. If you do miss it, don't hesitate to send me an email! diff --git a/src/content/articles/fr/2022.md b/src/content/articles/fr/2022.md index ceee23d..611aec3 100755 --- a/src/content/articles/fr/2022.md +++ b/src/content/articles/fr/2022.md @@ -9,6 +9,8 @@ type: articles createdAt: '2022-06-08T14:24:06.000Z' --- +This content exists in english. + Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais. ## Les services diff --git a/src/content/articles/fr/2023.md b/src/content/articles/fr/2023.md index 38dc1a3..206ab8f 100755 --- a/src/content/articles/fr/2023.md +++ b/src/content/articles/fr/2023.md @@ -10,6 +10,8 @@ createdAt: '2023-02-03T17:41:00.000Z' updatedAt: '2023-05-17T17:41:00.000Z' --- +This content exists in english. + Cet article sera mis à jour lorsque j'aurai des nouveautés à partager au cours de l'année 2023. ## Le site diff --git a/src/content/articles/fr/sci-hub-blocage.mdx b/src/content/articles/fr/sci-hub-blocage.mdx index 72d3715..864580e 100755 --- a/src/content/articles/fr/sci-hub-blocage.mdx +++ b/src/content/articles/fr/sci-hub-blocage.mdx @@ -12,6 +12,8 @@ updatedAt: '2022-12-27T12:08:00.000Z' import AstroImage from '../../../components/AstroImage.astro' +This content exists in english. + L'adresse actuelle de sci-hub est : sci-hub.st ## Résumé de la situation diff --git a/src/content/articles/fr/the-day-I-jamd.mdx b/src/content/articles/fr/the-day-I-jamd.mdx index 932cf42..860207e 100755 --- a/src/content/articles/fr/the-day-I-jamd.mdx +++ b/src/content/articles/fr/the-day-I-jamd.mdx @@ -10,6 +10,8 @@ createdAt: '2020-10-08T07:47:36.000Z' updatedAt: '2022-12-27T15:40:06.000Z' --- +This content exists in english. + import AstroImage from '../../../components/AstroImage.astro' ## La solution de non facilité diff --git a/src/pages/rss.xml.js b/src/pages/rss.xml.js index f91a0b2..a401bd6 100755 --- a/src/pages/rss.xml.js +++ b/src/pages/rss.xml.js @@ -1,7 +1,7 @@ import rss from '@astrojs/rss' import { getCollection } from 'astro:content' -export async function get(context) { +export async function GET(context) { const articles = await getCollection('articles', ({ data }) => { return data.lang === 'fr' && !data.draft }) diff --git a/src/styles/global/global-styles.css b/src/styles/global/global-styles.css index f7f554a..7bf28e4 100755 --- a/src/styles/global/global-styles.css +++ b/src/styles/global/global-styles.css @@ -46,7 +46,7 @@ h3, h4, .h4 { - font-size: var(--size-2); + font-size: var(--size-1); color: var(--color-dark); } -- 2.45.2 From 7d39c8446140564433264ea2d72698b232c854e0 Mon Sep 17 00:00:00 2001 From: nico Date: Thu, 2 Jan 2025 16:28:55 +0100 Subject: [PATCH 08/16] meta stuff --- .astro/content-modules.mjs | 4 ++-- src/components/Head.astro | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.astro/content-modules.mjs b/.astro/content-modules.mjs index 815dd4a..20a87a9 100644 --- a/.astro/content-modules.mjs +++ b/.astro/content-modules.mjs @@ -1,11 +1,11 @@ export default new Map([ ["src/content/articles/en/after-effects-expressions.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fafter-effects-expressions.mdx&astroContentModuleFlag=true")], -["src/content/articles/en/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], ["src/content/articles/en/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], ["src/content/articles/en/video-compression.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fvideo-compression.mdx&astroContentModuleFlag=true")], -["src/content/fragments/en/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fimage-full.mdx&astroContentModuleFlag=true")], ["src/content/fragments/en/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], +["src/content/fragments/en/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fimage-full.mdx&astroContentModuleFlag=true")], ["src/content/articles/fr/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], ["src/content/articles/fr/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], ["src/content/fragments/fr/buttons.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fbuttons.mdx&astroContentModuleFlag=true")], diff --git a/src/components/Head.astro b/src/components/Head.astro index d01f809..25a7b50 100755 --- a/src/components/Head.astro +++ b/src/components/Head.astro @@ -16,10 +16,16 @@ const { pageTitle } = Astro.props {pageTitle} | Nicolas Arduin + + + -- 2.45.2 From 53915b7e490167724ff60d346ab2408fe450760e Mon Sep 17 00:00:00 2001 From: nico Date: Tue, 7 Jan 2025 13:39:37 +0100 Subject: [PATCH 09/16] added missing lang attribute --- .astro/content-modules.mjs | 12 ++++++------ src/layouts/BaseLayout.astro | 2 +- src/pages/articles/[id].astro | 2 +- src/pages/fragments/[id].astro | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.astro/content-modules.mjs b/.astro/content-modules.mjs index 20a87a9..5accc34 100644 --- a/.astro/content-modules.mjs +++ b/.astro/content-modules.mjs @@ -1,14 +1,14 @@ export default new Map([ +["src/content/fragments/fr/buttons.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fbuttons.mdx&astroContentModuleFlag=true")], +["src/content/fragments/fr/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fimage-full.mdx&astroContentModuleFlag=true")], +["src/content/fragments/fr/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], ["src/content/articles/en/after-effects-expressions.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fafter-effects-expressions.mdx&astroContentModuleFlag=true")], -["src/content/articles/en/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], -["src/content/articles/en/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], ["src/content/articles/en/video-compression.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fvideo-compression.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], ["src/content/fragments/en/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], ["src/content/fragments/en/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fimage-full.mdx&astroContentModuleFlag=true")], ["src/content/articles/fr/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], -["src/content/articles/fr/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], -["src/content/fragments/fr/buttons.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fbuttons.mdx&astroContentModuleFlag=true")], -["src/content/fragments/fr/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fimage-full.mdx&astroContentModuleFlag=true")], -["src/content/fragments/fr/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fsuper-cookies.mdx&astroContentModuleFlag=true")]]); +["src/content/articles/fr/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")]]); \ No newline at end of file diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 1acf380..f22029c 100755 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -8,7 +8,7 @@ import Footer from '../components/Footer.astro' const { pageTitle, locale } = Astro.props --- - +
      diff --git a/src/pages/articles/[id].astro b/src/pages/articles/[id].astro index 954b845..c4aed32 100755 --- a/src/pages/articles/[id].astro +++ b/src/pages/articles/[id].astro @@ -17,6 +17,6 @@ export async function getStaticPaths() { const { article } = Astro.props --- - + diff --git a/src/pages/fragments/[id].astro b/src/pages/fragments/[id].astro index 24aa62f..9294c5b 100755 --- a/src/pages/fragments/[id].astro +++ b/src/pages/fragments/[id].astro @@ -17,6 +17,6 @@ export async function getStaticPaths() { const { fragment } = Astro.props --- - + -- 2.45.2 From d7392a0bd66bc97ec2d9d20cc7d4334b313278b8 Mon Sep 17 00:00:00 2001 From: nico Date: Wed, 8 Jan 2025 15:58:52 +0100 Subject: [PATCH 10/16] feat(security): add security.txt file --- .astro/content-modules.mjs | 16 ++++++++-------- public/security.txt | 3 +++ 2 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 public/security.txt diff --git a/.astro/content-modules.mjs b/.astro/content-modules.mjs index 5accc34..06ebea4 100644 --- a/.astro/content-modules.mjs +++ b/.astro/content-modules.mjs @@ -1,14 +1,14 @@ export default new Map([ -["src/content/fragments/fr/buttons.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fbuttons.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/after-effects-expressions.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fafter-effects-expressions.mdx&astroContentModuleFlag=true")], +["src/content/fragments/en/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fimage-full.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/video-compression.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fvideo-compression.mdx&astroContentModuleFlag=true")], +["src/content/fragments/en/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], +["src/content/articles/fr/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], ["src/content/fragments/fr/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fimage-full.mdx&astroContentModuleFlag=true")], ["src/content/fragments/fr/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], -["src/content/articles/en/after-effects-expressions.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fafter-effects-expressions.mdx&astroContentModuleFlag=true")], -["src/content/articles/en/video-compression.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fvideo-compression.mdx&astroContentModuleFlag=true")], -["src/content/articles/en/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], -["src/content/articles/en/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], -["src/content/fragments/en/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], -["src/content/fragments/en/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fimage-full.mdx&astroContentModuleFlag=true")], -["src/content/articles/fr/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], +["src/content/fragments/fr/buttons.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fbuttons.mdx&astroContentModuleFlag=true")], ["src/content/articles/fr/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")]]); \ No newline at end of file diff --git a/public/security.txt b/public/security.txt new file mode 100644 index 0000000..c36aed8 --- /dev/null +++ b/public/security.txt @@ -0,0 +1,3 @@ +Contact: mailto:security@nardu.in +Expires: 2027-01-01T11:00:00.000Z +Preferred-Languages: en, fr -- 2.45.2 From 836d4652e03ebb0c7dc757cdbd1ed141870b1d45 Mon Sep 17 00:00:00 2001 From: nico Date: Wed, 22 Jan 2025 14:38:21 +0100 Subject: [PATCH 11/16] feat(website): new contents and styles --- .astro/content-modules.mjs | 10 +++---- .astro/data-store.json | 2 +- .astro/settings.json | 2 +- bun.lockb | Bin 231283 -> 198857 bytes package.json | 13 ++++----- src/components/CardEditorial.astro | 10 ++++--- src/components/Footer.astro | 16 +++++++++-- src/components/QuickAccessCard.astro | 4 +-- src/images/fight-fascism.webp | Bin 0 -> 2026 bytes src/pages/index.astro | 2 +- src/styles/global/global-styles.css | 41 ++++++++++++++++++--------- src/styles/global/reset.css | 2 +- src/styles/global/variables.css | 41 +++++++++++++++++++++++++++ 13 files changed, 106 insertions(+), 37 deletions(-) create mode 100644 src/images/fight-fascism.webp diff --git a/.astro/content-modules.mjs b/.astro/content-modules.mjs index 06ebea4..0c5c721 100644 --- a/.astro/content-modules.mjs +++ b/.astro/content-modules.mjs @@ -1,14 +1,14 @@ export default new Map([ -["src/content/articles/en/after-effects-expressions.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fafter-effects-expressions.mdx&astroContentModuleFlag=true")], ["src/content/fragments/en/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fimage-full.mdx&astroContentModuleFlag=true")], -["src/content/articles/en/video-compression.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fvideo-compression.mdx&astroContentModuleFlag=true")], ["src/content/fragments/en/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Fen%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], -["src/content/articles/en/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/after-effects-expressions.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fafter-effects-expressions.mdx&astroContentModuleFlag=true")], ["src/content/articles/en/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], -["src/content/articles/fr/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")], +["src/content/articles/en/video-compression.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Fen%2Fvideo-compression.mdx&astroContentModuleFlag=true")], +["src/content/fragments/fr/buttons.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fbuttons.mdx&astroContentModuleFlag=true")], ["src/content/fragments/fr/image-full.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fimage-full.mdx&astroContentModuleFlag=true")], ["src/content/fragments/fr/super-cookies.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fsuper-cookies.mdx&astroContentModuleFlag=true")], -["src/content/fragments/fr/buttons.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Ffragments%2Ffr%2Fbuttons.mdx&astroContentModuleFlag=true")], +["src/content/articles/fr/sci-hub-blocage.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fsci-hub-blocage.mdx&astroContentModuleFlag=true")], ["src/content/articles/fr/the-day-I-jamd.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Farticles%2Ffr%2Fthe-day-I-jamd.mdx&astroContentModuleFlag=true")]]); \ No newline at end of file diff --git a/.astro/data-store.json b/.astro/data-store.json index 2c57848..eb84885 100644 --- a/.astro/data-store.json +++ b/.astro/data-store.json @@ -1 +1 @@ -[["Map",1,2,9,10,124,125,173,174,189,190,655,656],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.1.1","content-config-digest","8021b3469f132349","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"site\":\"https://www.nardu.in\",\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[\"assets.nardu.in\"],\"remotePatterns\":[{\"protocol\":\"https\"}]},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":false,\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[[null,{\"theme\":\"one-dark-pro\",\"plugins\":[{\"name\":\"Line numbers\",\"styleSettings\":{\"defaultValues\":{\"lineNumbers\":{\"foreground\":\"inherit\",\"highlightForeground\":\"inherit\"}},\"cssVarExclusions\":[],\"cssVarReplacements\":[]},\"hooks\":{}},{\"name\":\"astro-expressive-code\",\"hooks\":{}}],\"defaultProps\":{\"showLineNumbers\":false,\"overridesByLang\":{\"css,html,js,ts,vue\":{\"showLineNumbers\":true}}}}]],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"responsiveImages\":false},\"legacy\":{\"collections\":false}}","HPsections",["Map",11,12,35,36,53,54,70,71,96,97],"011-offre",{"id":11,"data":13,"body":22,"filePath":23,"digest":24,"rendered":25},{"type":14,"lang":15,"uid":16,"image":17,"order":18,"quickTitle":19,"quickImage":20,"reference":21},"section","fr","offre","/assets/images/home/offre-1.1.svg",1.1,"Mes offres en freelance","/assets/images/home/icon-desktop.svg","parole-expression","## L'offre site web classique\n\nCette offre est destinée à un public souhaitant **se doter d'un site web**, sans forcément intégrer l'accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du [référentiel général d'amélioration de l'accessibilité](https://accessibilite.numerique.gouv.fr/) (\u003Cabbr>RGAA\u003C/abbr>).\n\nL'objectif principal de cette offre étant d'**établir une présence en ligne** pour le client. Que cette dernière ait un but informatif et/ou éditorial.\n\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->","src/data/HP/011-offre.md","290ecd1ed94a1087",{"html":26,"metadata":27},"\u003Ch2 id=\"loffre-site-web-classique\">L’offre site web classique\u003C/h2>\n\u003Cp>Cette offre est destinée à un public souhaitant \u003Cstrong>se doter d’un site web\u003C/strong>, sans forcément intégrer l’accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du \u003Ca href=\"https://accessibilite.numerique.gouv.fr/\">référentiel général d’amélioration de l’accessibilité\u003C/a> (\u003Cabbr>RGAA\u003C/abbr>).\u003C/p>\n\u003Cp>L’objectif principal de cette offre étant d’\u003Cstrong>établir une présence en ligne\u003C/strong> pour le client. Que cette dernière ait un but informatif et/ou éditorial.\u003C/p>\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->",{"headings":28,"imagePaths":33,"frontmatter":34},[29],{"depth":30,"slug":31,"text":32},2,"loffre-site-web-classique","L’offre site web classique",[],{"type":14,"uid":16,"lang":15,"image":17,"order":18,"quickTitle":19,"quickImage":20,"reference":21},"012-offre",{"id":35,"data":37,"body":41,"filePath":42,"digest":43,"rendered":44},{"type":14,"lang":15,"image":38,"order":39,"reference":40},"/assets/images/home/offre-1.2.svg",1.2,"rose-primaire","## L'offre accessibilité avancée\n\nCette offre s'adresse plus spécifiquement aux entités pour lesquelles **l'accessibilité du site est un critère majeur.** Qu'il s'agisse d'une création ou d'une mise en conformité après un audit d'accessibilité.\n\nLorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\n\n- [Rose Primaire](https://roseprimaire.com/) pour le conseil et l'accompagnement du projet ;\n- [Sylvain Plantier](https://jedessinebien.com/) et/ou [Benoît Etchevery](http://ben-etche.com/) pour l'illustration et la direction artistique.\n\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->","src/data/HP/012-offre.md","2a3bf3411b3c171b",{"html":45,"metadata":46},"\u003Ch2 id=\"loffre-accessibilité-avancée\">L’offre accessibilité avancée\u003C/h2>\n\u003Cp>Cette offre s’adresse plus spécifiquement aux entités pour lesquelles \u003Cstrong>l’accessibilité du site est un critère majeur.\u003C/strong> Qu’il s’agisse d’une création ou d’une mise en conformité après un audit d’accessibilité.\u003C/p>\n\u003Cp>Lorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://roseprimaire.com/\">Rose Primaire\u003C/a> pour le conseil et l’accompagnement du projet ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://jedessinebien.com/\">Sylvain Plantier\u003C/a> et/ou \u003Ca href=\"http://ben-etche.com/\">Benoît Etchevery\u003C/a> pour l’illustration et la direction artistique.\u003C/li>\n\u003C/ul>\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->",{"headings":47,"imagePaths":51,"frontmatter":52},[48],{"depth":30,"slug":49,"text":50},"loffre-accessibilité-avancée","L’offre accessibilité avancée",[],{"type":14,"lang":15,"order":39,"image":38,"reference":40},"013-offre",{"id":53,"data":55,"body":58,"filePath":59,"digest":60,"rendered":61},{"type":14,"lang":15,"image":56,"order":57},"/assets/images/home/offre-1.3.svg",1.3,"## Et l'éco-conception alors ?\n\nJe ne conçois pas l'éco-conception comme une offre. C'est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l'éco-conception sans accessibilité, j'applique donc ces méthodologies quelque soit le projet !","src/data/HP/013-offre.md","03e37f364ac27cb4",{"html":62,"metadata":63},"\u003Ch2 id=\"et-léco-conception-alors\">Et l’éco-conception alors ?\u003C/h2>\n\u003Cp>Je ne conçois pas l’éco-conception comme une offre. C’est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l’éco-conception sans accessibilité, j’applique donc ces méthodologies quelque soit le projet !\u003C/p>",{"headings":64,"imagePaths":68,"frontmatter":69},[65],{"depth":30,"slug":66,"text":67},"et-léco-conception-alors","Et l’éco-conception alors ?",[],{"type":14,"lang":15,"order":57,"image":56},"020-methodo",{"id":70,"data":72,"body":77,"filePath":78,"digest":79,"rendered":80},{"type":14,"lang":15,"uid":73,"image":74,"order":30,"quickTitle":75,"quickImage":76},"methodology","/assets/images/home/methodo.svg","Ma méthodologie","/assets/images/home/icon-methodo.svg","## Méthodologie\n\n### Accessibilité par défaut\n\nEngagé pour un web plus accessible, je crée des **sites web** en m'appuyant sur le [référentiel général d'amélioration de l'accessibilité (RGAA)](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) ainsi que sur les bonnes pratiques [Opquast.](https://www.opquast.com/rendre-le-web-meilleur/)\n\n### Sobriété par choix\n\nJe privilégie le développement de **sites statiques** en adoptant une approche [d'éco-conception numérique.](https://eco-conception.designersethiques.org/guide/fr/) \nC'est-à-dire que le site est pensé pour n'embarquer que les fonctionnalités nécessaires à son utilisation.\n\nCette approche présente de **nombreux avantages :**\n\n- chargement rapide des pages ;\n- sécurité renforcée ;\n- coûts serveur réduits ;\n- maintenance facilitée.\n\nLorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l'interface. Cela permet de garantir que **le site reste en ligne** même si le CMS venait à ne plus fonctionner.","src/data/HP/020-methodo.md","75a09b4e0b1e926b",{"html":81,"metadata":82},"\u003Ch2 id=\"méthodologie\">Méthodologie\u003C/h2>\n\u003Ch3 id=\"accessibilité-par-défaut\">Accessibilité par défaut\u003C/h3>\n\u003Cp>Engagé pour un web plus accessible, je crée des \u003Cstrong>sites web\u003C/strong> en m’appuyant sur le \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité (RGAA)\u003C/a> ainsi que sur les bonnes pratiques \u003Ca href=\"https://www.opquast.com/rendre-le-web-meilleur/\">Opquast.\u003C/a>\u003C/p>\n\u003Ch3 id=\"sobriété-par-choix\">Sobriété par choix\u003C/h3>\n\u003Cp>Je privilégie le développement de \u003Cstrong>sites statiques\u003C/strong> en adoptant une approche \u003Ca href=\"https://eco-conception.designersethiques.org/guide/fr/\">d’éco-conception numérique.\u003C/a>\u003Cbr>\nC’est-à-dire que le site est pensé pour n’embarquer que les fonctionnalités nécessaires à son utilisation.\u003C/p>\n\u003Cp>Cette approche présente de \u003Cstrong>nombreux avantages :\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>chargement rapide des pages ;\u003C/li>\n\u003Cli>sécurité renforcée ;\u003C/li>\n\u003Cli>coûts serveur réduits ;\u003C/li>\n\u003Cli>maintenance facilitée.\u003C/li>\n\u003C/ul>\n\u003Cp>Lorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l’interface. Cela permet de garantir que \u003Cstrong>le site reste en ligne\u003C/strong> même si le CMS venait à ne plus fonctionner.\u003C/p>",{"headings":83,"imagePaths":94,"frontmatter":95},[84,87,91],{"depth":30,"slug":85,"text":86},"méthodologie","Méthodologie",{"depth":88,"slug":89,"text":90},3,"accessibilité-par-défaut","Accessibilité par défaut",{"depth":88,"slug":92,"text":93},"sobriété-par-choix","Sobriété par choix",[],{"type":14,"uid":73,"lang":15,"image":74,"order":30,"quickTitle":75,"quickImage":76},"030-about",{"id":96,"data":98,"body":103,"filePath":104,"digest":105,"rendered":106},{"type":14,"lang":15,"uid":99,"image":100,"order":88,"quickTitle":101,"quickImage":102},"about","/assets/images/home/about.svg","Moi","/assets/images/home/icon-heart.svg","## À propos\n\n### Formations personnelles\n\nAfin de solidifier mes compétences, j'ai suivi les formations et passé les certifications suivantes :\n\n- [Opquast](https://directory.opquast.com/fr/certificat/CTQSKP/) - Maîtrise de la qualité en projet web ;\n- Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\n\n### Formations des autres\n\nDepuis plusieurs années, j'interviens dans différents campus afin de dispenser des cours de développement web.\n\n### Temps libre\n\nJ’essaie de contribuer à des [projets open source](https://git.nardu.in/explore/repos) qui me tiennent à cœur et je m'engage localement avec le collectif [good-it!](https://www.good-it.org/)\n\nAh et j’écris [des articles](/articles) aussi ! Des articles sur le design, le développement web et l’informatique.","src/data/HP/030-about.md","a7abff6d744406ce",{"html":107,"metadata":108},"\u003Ch2 id=\"à-propos\">À propos\u003C/h2>\n\u003Ch3 id=\"formations-personnelles\">Formations personnelles\u003C/h3>\n\u003Cp>Afin de solidifier mes compétences, j’ai suivi les formations et passé les certifications suivantes :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://directory.opquast.com/fr/certificat/CTQSKP/\">Opquast\u003C/a> - Maîtrise de la qualité en projet web ;\u003C/li>\n\u003Cli>Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"formations-des-autres\">Formations des autres\u003C/h3>\n\u003Cp>Depuis plusieurs années, j’interviens dans différents campus afin de dispenser des cours de développement web.\u003C/p>\n\u003Ch3 id=\"temps-libre\">Temps libre\u003C/h3>\n\u003Cp>J’essaie de contribuer à des \u003Ca href=\"https://git.nardu.in/explore/repos\">projets open source\u003C/a> qui me tiennent à cœur et je m’engage localement avec le collectif \u003Ca href=\"https://www.good-it.org/\">good-it!\u003C/a>\u003C/p>\n\u003Cp>Ah et j’écris \u003Ca href=\"/articles\">des articles\u003C/a> aussi ! Des articles sur le design, le développement web et l’informatique.\u003C/p>",{"headings":109,"imagePaths":122,"frontmatter":123},[110,113,116,119],{"depth":30,"slug":111,"text":112},"à-propos","À propos",{"depth":88,"slug":114,"text":115},"formations-personnelles","Formations personnelles",{"depth":88,"slug":117,"text":118},"formations-des-autres","Formations des autres",{"depth":88,"slug":120,"text":121},"temps-libre","Temps libre",[],{"type":14,"uid":99,"lang":15,"image":100,"order":88,"quickTitle":101,"quickImage":102},"references",["Map",126,127,139,140,21,153,40,163],"3w",{"id":126,"data":128,"filePath":135,"digest":136,"rendered":137},{"title":126,"subtitle":129,"url":130,"lang":15,"slug":126,"tags":131,"createdAt":134},"J'ai fait de la doc!","https://3-w.fr",[132,133],"Front-end","documentation",["Date","2022-10-19T18:02:00.000Z"],"src/content/references/3w.md","0d3d94c8af754e1b",{"html":138},"","natureo",{"id":139,"data":141,"filePath":150,"digest":151,"rendered":152},{"title":142,"subtitle":143,"url":144,"lang":15,"slug":139,"tags":145,"createdAt":149},"Nature en Occitanie","La sobriété au naturel.","https://www.natureo.org/",[132,146,147,148],"accessibilité","éco-conception","CMS",["Date","2023-04-19T18:02:00.000Z"],"src/content/references/natureo.md","6a7169b855b57024",{"html":138},{"id":21,"data":154,"filePath":160,"digest":161,"rendered":162},{"title":155,"subtitle":156,"url":157,"lang":15,"slug":21,"tags":158,"createdAt":159},"Parole Expression","Un nouveau site pour l'association.","https://www.paroleexpression.fr/",[132,147,148],["Date","2022-04-19T17:11:00.000Z"],"src/content/references/parole-expression.md","ec95a408f8c3e99c",{"html":138},{"id":40,"data":164,"filePath":170,"digest":171,"rendered":172},{"title":165,"subtitle":166,"url":167,"lang":15,"slug":40,"tags":168,"createdAt":169},"Rose Primaire","Une agence comme on l'aime.","https://roseprimaire.com/",[132,146,147,148],["Date","2023-04-19T17:11:00.000Z"],"src/content/references/rose-primaire.md","a0133200cf1bee58",{"html":138},"veille",["Map",175,176],"2023",{"id":175,"data":177,"body":179,"filePath":180,"digest":181,"rendered":182},{"lang":15,"title":175,"updatedAt":178},["Date","2023-04-20T17:12:06.000Z"],"- [mmm.page](https://build.mmm.page/) - Éditeur de sites web très simples, en glisser-déposer, pour n'importe quoi.\n- [Color.io](https://www.color.io/) - Éditeur photo en ligne.\n- [Addy's toolkit](https://toolkit.addy.codes/) - Outils et ressources pour les designers et développeurs sites web.\n- [L’accessibilité n’est pas une variable d’ajustement](https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/) — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n > L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\n- [3D en CSS (english)](https://garden.bradwoods.io/notes/css/3d) – Explications et exemples des propriétés 3D en CSS.\n- [Climat : Comment ne pas déprimer ?](https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html) – Podcast.\n- [Fable (english)](https://fable.app) – Application de motion design.\n- [Rive (english)](https://rive.app) – Application de motion design.\n- [Cake Desk](https://cakedesk.app/) – Application de facturation.\n- [Ombre fluide en CSS](https://shadows.brumm.af/) – Générateur.\n- [Smol CSS](https://smolcss.dev/) – Collection de fragments CSS.\n- [Ajustement optique](https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/) (english) – Aligner visuellement plutôt que techniquement.\n- [Datawrapper](https://blog.datawrapper.de/category/datavis-dos-and-donts/) (english) – Conseils pour montrer de la donnée.\n- [Assistivlabs](https://assistivlabs.com/) (english) – Service de test des technologies d'assistance (browserstack mais pour l'accessibilité).\n- [Les caractères fantaisistes et l'accessibilité](https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/) – Explications et exemples de l'enfer que sont les caractères Unicode pour les technologies d'assistance.\n- [Créer un champ `time` sur le web](https://adamsilver.io/blog/designing-a-time-input-backed-by-research/) (english) – Article.\n- [La cascade](https://la-cascade.io) – Collection d'articles sur le CSS.\n- [Tabby](https://tabby.sh) (english) – An alternative terminal app.\n- [Newglyph](https://newglyph.com/) – Fonderie indépendante.\n- [\u003Cspan lang=\"en\">Headless UI\u003C/span>](https://headlessui.com/vue/dialog) (english) – Librairie de composants vue et react.\n- [Vie privée sexy](https://privacy.sexy) (english) – Outils de confidentialité pour windows et macos.\n- [33 concepts JavaScript](https://github.com/leonardomso/33-js-concepts) (english) – Articles.\n- [Formbricks](https://formbricks.com/) (english) – Alternative open source à google form/typeform.\n- [Animations de chargement SVG](https://github.com/n3r4zzurr0/svg-spinners) – Collection.\n- [a11yphant](https://a11yphant.com/) (english) – Challenges de code pour apprendre l'accessibilité.\n- [CSS moderne](https://moderncss.dev/) (english) – Fragments CSS.\n- [Conteneur moderne en CSS](https://twitter.com/KevinJPowell/status/1501555193799925761) (english) – Tweet de Kevin Powell ❤️","src/data/veille/2023.md","1135beec386f207f",{"html":183,"metadata":184},"\u003Cul>\n\u003Cli>\u003Ca href=\"https://build.mmm.page/\">mmm.page\u003C/a> - Éditeur de sites web très simples, en glisser-déposer, pour n’importe quoi.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.color.io/\">Color.io\u003C/a> - Éditeur photo en ligne.\u003C/li>\n\u003Cli>\u003Ca href=\"https://toolkit.addy.codes/\">Addy’s toolkit\u003C/a> - Outils et ressources pour les designers et développeurs sites web.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/\">L’accessibilité n’est pas une variable d’ajustement\u003C/a> — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n\u003Cblockquote>\n\u003Cp>L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\u003C/p>\n\u003C/blockquote>\n\u003C/li>\n\u003Cli>\u003Ca href=\"https://garden.bradwoods.io/notes/css/3d\">3D en CSS (english)\u003C/a> – Explications et exemples des propriétés 3D en CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html\">Climat : Comment ne pas déprimer ?\u003C/a> – Podcast.\u003C/li>\n\u003Cli>\u003Ca href=\"https://fable.app\">Fable (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://rive.app\">Rive (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://cakedesk.app/\">Cake Desk\u003C/a> – Application de facturation.\u003C/li>\n\u003Cli>\u003Ca href=\"https://shadows.brumm.af/\">Ombre fluide en CSS\u003C/a> – Générateur.\u003C/li>\n\u003Cli>\u003Ca href=\"https://smolcss.dev/\">Smol CSS\u003C/a> – Collection de fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/\">Ajustement optique\u003C/a> (english) – Aligner visuellement plutôt que techniquement.\u003C/li>\n\u003Cli>\u003Ca href=\"https://blog.datawrapper.de/category/datavis-dos-and-donts/\">Datawrapper\u003C/a> (english) – Conseils pour montrer de la donnée.\u003C/li>\n\u003Cli>\u003Ca href=\"https://assistivlabs.com/\">Assistivlabs\u003C/a> (english) – Service de test des technologies d’assistance (browserstack mais pour l’accessibilité).\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/\">Les caractères fantaisistes et l’accessibilité\u003C/a> – Explications et exemples de l’enfer que sont les caractères Unicode pour les technologies d’assistance.\u003C/li>\n\u003Cli>\u003Ca href=\"https://adamsilver.io/blog/designing-a-time-input-backed-by-research/\">Créer un champ \u003Ccode>time\u003C/code> sur le web\u003C/a> (english) – Article.\u003C/li>\n\u003Cli>\u003Ca href=\"https://la-cascade.io\">La cascade\u003C/a> – Collection d’articles sur le CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://tabby.sh\">Tabby\u003C/a> (english) – An alternative terminal app.\u003C/li>\n\u003Cli>\u003Ca href=\"https://newglyph.com/\">Newglyph\u003C/a> – Fonderie indépendante.\u003C/li>\n\u003Cli>\u003Ca href=\"https://headlessui.com/vue/dialog\">\u003Cspan lang=\"en\">Headless UI\u003C/span>\u003C/a> (english) – Librairie de composants vue et react.\u003C/li>\n\u003Cli>\u003Ca href=\"https://privacy.sexy\">Vie privée sexy\u003C/a> (english) – Outils de confidentialité pour windows et macos.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/leonardomso/33-js-concepts\">33 concepts JavaScript\u003C/a> (english) – Articles.\u003C/li>\n\u003Cli>\u003Ca href=\"https://formbricks.com/\">Formbricks\u003C/a> (english) – Alternative open source à google form/typeform.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/n3r4zzurr0/svg-spinners\">Animations de chargement SVG\u003C/a> – Collection.\u003C/li>\n\u003Cli>\u003Ca href=\"https://a11yphant.com/\">a11yphant\u003C/a> (english) – Challenges de code pour apprendre l’accessibilité.\u003C/li>\n\u003Cli>\u003Ca href=\"https://moderncss.dev/\">CSS moderne\u003C/a> (english) – Fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/KevinJPowell/status/1501555193799925761\">Conteneur moderne en CSS\u003C/a> (english) – Tweet de Kevin Powell ❤️\u003C/li>\n\u003C/ul>",{"headings":185,"imagePaths":186,"frontmatter":187},[],[],{"lang":15,"title":175,"updatedAt":188},"2023-04-20T17:12:06.000Z","fragments",["Map",191,192,206,207,217,218,273,274,290,291,309,310,319,320,330,331,341,342,354,355,389,390,413,414,455,456,495,496,529,530,593,594],"en-image-full",{"id":191,"data":193,"body":203,"filePath":204,"digest":205,"deferredRender":202},{"title":194,"subtitle":195,"lang":196,"tags":197,"type":199,"slug":191,"createdAt":200,"updatedAt":201,"draft":202},"Full width image","Translation in progress, stay tuned ;)","en",[198],"CSS","snippets",["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],true,"[Go back to available snippets](/en/snippets)","src/content/fragments/en/image-full.mdx","2e3dddf593f6d72f","en-super-cookies",{"id":206,"data":208,"body":214,"filePath":215,"digest":216,"deferredRender":202},{"title":209,"subtitle":210,"lang":196,"tags":211,"type":199,"slug":206,"createdAt":213},"The best cookies","Consentless biscuits.",[212],"food",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 tablespoon of baking powder\n- 3/4 of aquafaba from 400g of chickpea (chickpea water)\n- 125 grams of coconut oil\n- 2 teaspoons of maple syrup\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- if necessary, melt the coconut oil over low heat\n- meanwhile, mix all the dry ingredients\n- add all liquid ingredients (oil, aquafaba, maple syrup)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Non vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 table spoon of baking powder\n- 1 egg\n- 125 grams of melted butter\n- 2 teaspoons of honey\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- melt butter over low heat\n- meanwhile, mix all dry ingredients\n- add all liquid ingredients (melted butter, egg, honey)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Notes\n\nChocolate can be replaced by anything like nuts, raisins, legos... (don't eat legos be reasonable).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='All ingredients mixed together to form a brown paste.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='The cookies are round and soft after baking.'\n/>","src/content/fragments/en/super-cookies.mdx","b0c67adad40c177c","en-toulouse-fun",{"id":217,"data":219,"body":225,"filePath":226,"digest":227,"rendered":228},{"title":220,"subtitle":221,"lang":196,"tags":222,"type":199,"slug":217,"createdAt":224},"Toulouse yourself","Only the bestest",[223],"lifestyle",["Date","2022-06-22T15:34:45.000Z"],"Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite. \n**It's always a good idea to make a reservation!**\n\n## Restaurants\n\n### French cuisine\n\n- [Solides](https://www.solides.fr/) — semi-gastronomic\n- [Les impulsifs](https://les-impulsifs-toulouse.eatbu.com/?lang=en) — semi-gastronomic\n- [Sixta](https://sixta-toulouse.fr/) — vege/vegan/gluten friendly\n- [Attila](https://attila.site-solocal.com/) — great **fish restaurant,** just above the Victor Hugo market\n- [Chez Emile](https://www.restaurant-emile.com/) - best [cassoulet](https://en.wikipedia.org/wiki/Cassoulet) in town (or so I'm told)\n\n### Korean\n\n- [Le ptit Louis](https://leptitlouis.fr/) — best of its kind, **only for lunch**\n- [Kongbap](https://kong-bap.com/) — street-food like\n\n### Japanese\n\n- [Iori](https://www.iori.fr/) — best ramen\n- [Japoyaki](https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402) — best sushi/sashimis\n\n## Drinks and snacks\n\n### Bars\n\n- [Le Bièrographe](https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327) — all time favourite, **check out the typical toulouse basement**\n- [A Taula](https://www.facebook.com/ataulatolosa/) — all time favourite in summer, **amazing terrace,** also: great tapas\n- [The Hopscotch Pub](https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385) — good beers, good whiskies, good cocktials, good food\n\n### Cafés & tea rooms\n\n- [Bapz](https://www.bapz.fr/contact) — Excellent pastries / hot beverages\n- [Ô thé divin](https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/) — nice lunch options\n- [Les Rêveries d’Hercule](https://www.lesreveriesdhercule.com/) — Pottery Café, relaxing activity (ceramics need to be baked, there'll be a delay to get them back)\n- Bonus: the best bakeries in [Carmes](https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872) and [Saint-Aubin](https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694) — croissants, baguettes **traditions**, chocolatines and more\n\n### Wine shops\n\n- [l'envie du sud](https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930) — amazing selection of wines and other spirits, excellent advice from the staff\n- [enoteca](https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952) — smaller selection but more beers and great advice from the staff as well\n\n## Other delights\n\n### Ice creams\n\n- [Forno gusto](https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450) — only in the summer\n- [Moustache](https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540) — lots of flavours\n\n### Cheese shop\n\n- [Xavier](https://xavier.fr/) — one of the **best of the country**, two shops in Toulouse, including one at Victor Hugo market\n- [Massembea](https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490) — a serious contender in Toulouse (weird hours)\n\n### Delicatessen\n\n- [Café Bacquié](http://cafe-bacquie.com/) — stock up on fine foods, coffees, teas and other great quality products","src/content/fragments/en/toulouse-fun.md","370491cc68079e8c",{"html":229,"metadata":230},"\u003Cp>Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite.\u003Cbr>\n\u003Cstrong>It’s always a good idea to make a reservation!\u003C/strong>\u003C/p>\n\u003Ch2 id=\"restaurants\">Restaurants\u003C/h2>\n\u003Ch3 id=\"french-cuisine\">French cuisine\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.solides.fr/\">Solides\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://les-impulsifs-toulouse.eatbu.com/?lang=en\">Les impulsifs\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://sixta-toulouse.fr/\">Sixta\u003C/a> — vege/vegan/gluten friendly\u003C/li>\n\u003Cli>\u003Ca href=\"https://attila.site-solocal.com/\">Attila\u003C/a> — great \u003Cstrong>fish restaurant,\u003C/strong> just above the Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.restaurant-emile.com/\">Chez Emile\u003C/a> - best \u003Ca href=\"https://en.wikipedia.org/wiki/Cassoulet\">cassoulet\u003C/a> in town (or so I’m told)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"korean\">Korean\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://leptitlouis.fr/\">Le ptit Louis\u003C/a> — best of its kind, \u003Cstrong>only for lunch\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://kong-bap.com/\">Kongbap\u003C/a> — street-food like\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"japanese\">Japanese\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.iori.fr/\">Iori\u003C/a> — best ramen\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402\">Japoyaki\u003C/a> — best sushi/sashimis\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"drinks-and-snacks\">Drinks and snacks\u003C/h2>\n\u003Ch3 id=\"bars\">Bars\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327\">Le Bièrographe\u003C/a> — all time favourite, \u003Cstrong>check out the typical toulouse basement\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.facebook.com/ataulatolosa/\">A Taula\u003C/a> — all time favourite in summer, \u003Cstrong>amazing terrace,\u003C/strong> also: great tapas\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385\">The Hopscotch Pub\u003C/a> — good beers, good whiskies, good cocktials, good food\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cafés--tea-rooms\">Cafés & tea rooms\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.bapz.fr/contact\">Bapz\u003C/a> — Excellent pastries / hot beverages\u003C/li>\n\u003Cli>\u003Ca href=\"https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/\">Ô thé divin\u003C/a> — nice lunch options\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lesreveriesdhercule.com/\">Les Rêveries d’Hercule\u003C/a> — Pottery Café, relaxing activity (ceramics need to be baked, there’ll be a delay to get them back)\u003C/li>\n\u003Cli>Bonus: the best bakeries in \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872\">Carmes\u003C/a> and \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694\">Saint-Aubin\u003C/a> — croissants, baguettes \u003Cstrong>traditions\u003C/strong>, chocolatines and more\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"wine-shops\">Wine shops\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930\">l’envie du sud\u003C/a> — amazing selection of wines and other spirits, excellent advice from the staff\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952\">enoteca\u003C/a> — smaller selection but more beers and great advice from the staff as well\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"other-delights\">Other delights\u003C/h2>\n\u003Ch3 id=\"ice-creams\">Ice creams\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450\">Forno gusto\u003C/a> — only in the summer\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540\">Moustache\u003C/a> — lots of flavours\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cheese-shop\">Cheese shop\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://xavier.fr/\">Xavier\u003C/a> — one of the \u003Cstrong>best of the country\u003C/strong>, two shops in Toulouse, including one at Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490\">Massembea\u003C/a> — a serious contender in Toulouse (weird hours)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"delicatessen\">Delicatessen\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"http://cafe-bacquie.com/\">Café Bacquié\u003C/a> — stock up on fine foods, coffees, teas and other great quality products\u003C/li>\n\u003C/ul>",{"headings":231,"imagePaths":268,"frontmatter":269},[232,235,238,241,244,247,250,253,256,259,262,265],{"depth":30,"slug":233,"text":234},"restaurants","Restaurants",{"depth":88,"slug":236,"text":237},"french-cuisine","French cuisine",{"depth":88,"slug":239,"text":240},"korean","Korean",{"depth":88,"slug":242,"text":243},"japanese","Japanese",{"depth":30,"slug":245,"text":246},"drinks-and-snacks","Drinks and snacks",{"depth":88,"slug":248,"text":249},"bars","Bars",{"depth":88,"slug":251,"text":252},"cafés--tea-rooms","Cafés & tea rooms",{"depth":88,"slug":254,"text":255},"wine-shops","Wine shops",{"depth":30,"slug":257,"text":258},"other-delights","Other delights",{"depth":88,"slug":260,"text":261},"ice-creams","Ice creams",{"depth":88,"slug":263,"text":264},"cheese-shop","Cheese shop",{"depth":88,"slug":266,"text":267},"delicatessen","Delicatessen",[],{"title":220,"subtitle":221,"lang":196,"slug":217,"excerpt":270,"tags":271,"type":199,"createdAt":272},"Gonna have to trust me on this ¯\\_(ツ)_/¯",[223],"2022-06-22T15:34:45.000Z","en-visited-links",{"id":273,"data":275,"body":203,"filePath":279,"digest":280,"rendered":281},{"title":276,"subtitle":195,"lang":196,"tags":277,"type":199,"slug":273,"createdAt":278,"draft":202},"Visited links and visuel aid",[132],["Date","2023-06-06T18:34:00.000Z"],"src/content/fragments/en/visited-links.md","cb7c11c12c25067e",{"html":282,"metadata":283},"\u003Cp>\u003Ca href=\"/en/snippets\">Go back to available snippets\u003C/a>\u003C/p>",{"headings":284,"imagePaths":285,"frontmatter":286},[],[],{"title":276,"subtitle":195,"lang":196,"draft":202,"slug":273,"excerpt":287,"tags":288,"type":199,"createdAt":289},"Petit hack CSS",[132],"2023-06-06T18:34:00.000Z","array-vs-array",{"id":290,"data":292,"body":298,"filePath":299,"digest":300,"rendered":301},{"title":293,"subtitle":294,"lang":15,"tags":295,"type":189,"slug":290,"createdAt":297,"draft":202},"Filtrer un array avec un autre array","En cours de traduction.",[296],"nuxt.js",["Date","2022-06-08T14:24:06.000Z"],"[Voir les fragments disponibles](/fragments)","src/content/fragments/fr/array-vs-array.md","7321d444177c3841",{"html":302,"metadata":303},"\u003Cp>\u003Ca href=\"/fragments\">Voir les fragments disponibles\u003C/a>\u003C/p>",{"headings":304,"imagePaths":305,"frontmatter":306},[],[],{"title":293,"subtitle":294,"lang":15,"draft":202,"slug":290,"createdAt":307,"excerpt":294,"tags":308,"type":189},"2022-06-08T14:24:06.000Z",[296],"buttons",{"id":309,"data":311,"body":316,"filePath":317,"digest":318,"deferredRender":202},{"title":312,"subtitle":313,"lang":15,"tags":314,"type":189,"slug":309,"createdAt":315,"code":202,"draft":202},"Effets de survol de boutons","Simples mais efficaces.",[198],["Date","2020-10-08T09:00:00.000Z"],"## Styles généraux\n\nTous les boutons présents utilisent ces styles comme base en guise de « reset » :\n\n> N'oubliez pas de préfixer si besoin !\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Ajout d'icône\n\n\u003Cbutton role='none' class='btn btn-icon'>\n\t\u003Cspan>Icône\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('./assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double volet\n\n\u003Cbutton role='none' class='btn btn-rideau'>\n\t\u003Cspan>Volet\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Dégradé animé\n\n\u003Cbutton role='none' class='btn btn-gradient'>\n\t\u003Cspan>Dégradé\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Échelle non desctructrice\n\n\u003Cbutton role='none' class='btn btn-scale'>\n\t\u003Cspan>Échelle\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/fr/buttons.mdx","f5d7b03520f96b04","image-full",{"id":319,"data":321,"body":327,"filePath":328,"digest":329,"deferredRender":202},{"title":322,"subtitle":323,"lang":15,"tags":324,"type":189,"slug":319,"createdAt":325,"updatedAt":326},"Image pleine largeur","Casser le conteneur.",[198],["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Image inline\n\nOn est parfois obligé d'utiliser des images dans des balises `img` plutôt que dans un `background` en css. Comment faire alors pour que l'image sorte de son conteneur pour en faire une bannière ? Exemple pratique à partir de ce même site.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_container_9e3939b3ae.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Contexte\n\nConsidérons le html suivant :\n\n```html\n\u003C!-- index.html -->\n\u003Csection class=\"container\">\n\t\u003Cdiv class=\"hero\">\n\t\t\u003Cimg class=\"hero__image\" src=\"hero.img\" />\n\t\u003C/div>\n\u003C/section>\n```\n\nEt le style suivant :\n\n```css\n/* style.css */\n.container {\n\tpadding: 0 14px;\n\tmargin-inline: auto;\n\tmax-inline-size: 1040px;\n}\nimg {\n\tmax-inline-size: 100%;\n\tblock-size: auto;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_original_d49f0d11bf.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Déborder du conteneur\n\nAfin de faire prendre à l'image toute la largeur, on agit sur son conteneur :\n\n```css\n/* style.css */\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_full_2a902f9539.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Faire une bannière\n\nOn peut alors réduire la hauteur du conteneur pour obtenir une bannière plutôt que l'image entière et faire correspondre la hauteur de l'image à la hauteur du conteneur :\n\n```css title='style.css' ins={5, 7-9}\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n\tblock-size: 200px;\n}\n.hero__image {\n\tblock-size: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_height_81b4ce969a.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nIl faut ensuite forcer l'image à prendre toute la largeur du conteneur :\n\n```css title='style.css' ins={3}\n.hero__image {\n\tblock-size: 100%;\n\tinline-size: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_deformed_479046d2cb.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nPas top…\n\n### J'ai cassé l'image…\n\n**ENFIN** le code magique pour redonner son ratio à l'image sans la déformer :\n\n```css title='style.css' ins={4,5}\n.hero__image {\n\tblock-size: 100%;\n\tinline-size: 100%;\n\tobject-fit: cover;\n\tobject-position: center; /* à positionner comme on veut */\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_6c164e82b3.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nCette technique s'apparente à l'utilisation d'une image de background.\n\n## TL;DR\n\nLe code complet :\n\n```css\n/* style.css */\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n\tblock-size: 200px;\n}\n.hero__image {\n\tinline-size: 100%;\n\tblock-size: 100%;\n\t-o-object-fit: cover;\n\tobject-fit: cover;\n\t-o-object-position: center;\n\tobject-position: center;\n}\n```","src/content/fragments/fr/image-full.mdx","585dcfae92fb08fb","super-cookies",{"id":330,"data":332,"body":338,"filePath":339,"digest":340,"deferredRender":202},{"title":333,"subtitle":334,"lang":15,"tags":335,"type":189,"slug":330,"createdAt":337},"Les meilleurs cookies","Des gâteaux sans consentement.",[336],"cuisine",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Version végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 3/4 de l'aquafaba de 400g de pois chiche (l'eau des pois chiche)\n- 125 grammes d'huile de noix de coco\n- 2 cuillères à café de sirop d'érable\n- 1 plaquette de chocolat (noir) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre si besoin l'huile de noix de coco à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (huile, aquafaba, sirop d'érable)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Version non végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 1 œuf\n- 125 grammes de beurre fondu\n- 2 cuillères à café de miel\n- 1 plaquette de chocolat (noir/blanc/les deux) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre le beurre à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (beurre fondu, œuf, miel)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Notes\n\nLe chocolat peut-être remplacé par n'importe quoi comme des noix, des raisins secs, des légos… (mangez pas des légos soyez sérieux).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Tous les ingrédients mélangés forment une pâte marron.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Les cookies cuits sont bombés et très moelleux.'\n/>","src/content/fragments/fr/super-cookies.mdx","f7a802e0b68cb04a","toulouse-fun",{"id":341,"data":343,"body":298,"filePath":346,"digest":347,"rendered":348},{"title":220,"subtitle":294,"lang":15,"tags":344,"type":189,"slug":341,"createdAt":345,"draft":202},[223],["Date","2022-06-22T15:34:45.000Z"],"src/content/fragments/fr/toulouse-fun.md","a0c25b438b34c05e",{"html":302,"metadata":349},{"headings":350,"imagePaths":351,"frontmatter":352},[],[],{"title":220,"subtitle":294,"lang":15,"draft":202,"slug":341,"createdAt":272,"excerpt":294,"tags":353,"type":189},[223],"visited-links",{"id":354,"data":356,"body":362,"filePath":363,"digest":364,"rendered":365},{"title":357,"subtitle":358,"lang":15,"tags":359,"type":199,"slug":354,"createdAt":360,"draft":361},"Liens visités et indication visuelle","Comment différencier les liens déjà cliqués",[132],["Date","2023-06-06T18:34:00.000Z"],false,"## La théorie\n\nIl est possible sur le web d'appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu'un lien visité est violet.\n\nGénéralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L'information qu'un lien a déjà été visité ne semble pas indispensable à la navigation. C'est sûrement vrai, mais personnellement, je suis assez content d'avoir un rappel des pages que j'ai déjà consultées lorsque je navigue.\n\nUne information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J'ai alors cherché un moyen d'ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n'est certainement pas idéale, elle se rapproche plus d'une expérience, à priori inoffensive pour l'internaute.\n\n## La spécification\n\nQuand je me suis intéressé à ce qu'il était possible de faire avec les liens déjà visités, j'ai découvert qu'extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu'il était possible de récupérer l'historique de navigation d'un utilisateur grâce aux styles des liens visités. Le sélecteur `:visited` a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. [Plus d'informations dans cet article.](https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector)\n\n## La pratique\n\nQue faire alors, en terme de style, quand on ne peut changer que des couleurs ?\n\nD'après MDN, les propriétés suivantes sont modifiables :\n\n- `color`\n- `background-color`\n- `border-color` (et les propriétés détaillées associées),\n- `column-rule-color`\n- `outline-color`\n- `text-decoration-color`\n- `text-emphasis-color`\n- Les composantes de couleur liées aux attributs SVG `fill` et `stroke`.\n\nChanger la couleur d'un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\n\nEn revanche, il est possible de \" masquer \" un élément en modifiant sa couleur pour qu'elle corresponde à la couleur du fond de la page ou de l'élément parent. On pourrait ainsi imaginer masquer une `border` ou un `outline`.\n\nJ'ai personnellement choisi de faire différemment. J'ai décidé d'utiliser un pseudo-élément `::before` sur l'état non visité du lien puis de le masquer quand celui-ci devient visité.\n\n### Le code\n\n```css {5,16} title=\"style.css\"\na {\n\tposition: relative;\n\ttext-decoration: none;\n}\na::before {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 0;\n\tinline-size: 2px;\n\tblock-size: 2px;\n\tborder-radius: 4px;\n\ttransform: translate(-6px, 0);\n\tbackground-color: grey;\n}\na:visited::before {\n\tbackground-color: white;\n}\n```\n\nCes règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\n\n### Accessibilité\n\nOn pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété `content` mais les lecteurs d'écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d'écrans annoncent déjà si un lien est visité avant de lire son intitulé.\n\n## Aller plus loin\n\nAfin de pousser l'expérience un peu plus loin, j'ai tenté d'utiliser des éléments plus explicites pour signifier l'état visité du lien. Bien qu'encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\n\nL'idée est d'avoir un `::before` et un `::after`, chacun contenant une icône en base 64 blanche en tant qu'image de fond. Quand le lien est non visité, le `::before` contient un fond coloré qui fait apparaître l'icône. Quand le lien passe en visité, le fond du `::before` devient blanc et celui du `::after` devient coloré, ce qui masque la première icône et affiche la deuxième.\n\nIl est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l'une sur l'autre.\n\n[Voir la démo sur codepen.](https://codepen.io/narduin/pen/VwVwmrO)","src/content/fragments/fr/visited-links.md","c062a565e4c30dfe",{"html":366,"metadata":367},"\u003Ch2 id=\"la-théorie\">La théorie\u003C/h2>\n\u003Cp>Il est possible sur le web d’appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu’un lien visité est violet.\u003C/p>\n\u003Cp>Généralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L’information qu’un lien a déjà été visité ne semble pas indispensable à la navigation. C’est sûrement vrai, mais personnellement, je suis assez content d’avoir un rappel des pages que j’ai déjà consultées lorsque je navigue.\u003C/p>\n\u003Cp>Une information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J’ai alors cherché un moyen d’ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n’est certainement pas idéale, elle se rapproche plus d’une expérience, à priori inoffensive pour l’internaute.\u003C/p>\n\u003Ch2 id=\"la-spécification\">La spécification\u003C/h2>\n\u003Cp>Quand je me suis intéressé à ce qu’il était possible de faire avec les liens déjà visités, j’ai découvert qu’extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu’il était possible de récupérer l’historique de navigation d’un utilisateur grâce aux styles des liens visités. Le sélecteur \u003Ccode>:visited\u003C/code> a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector\">Plus d’informations dans cet article.\u003C/a>\u003C/p>\n\u003Ch2 id=\"la-pratique\">La pratique\u003C/h2>\n\u003Cp>Que faire alors, en terme de style, quand on ne peut changer que des couleurs ?\u003C/p>\n\u003Cp>D’après MDN, les propriétés suivantes sont modifiables :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>background-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>border-color\u003C/code> (et les propriétés détaillées associées),\u003C/li>\n\u003Cli>\u003Ccode>column-rule-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>outline-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-decoration-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-emphasis-color\u003C/code>\u003C/li>\n\u003Cli>Les composantes de couleur liées aux attributs SVG \u003Ccode>fill\u003C/code> et \u003Ccode>stroke\u003C/code>.\u003C/li>\n\u003C/ul>\n\u003Cp>Changer la couleur d’un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\u003C/p>\n\u003Cp>En revanche, il est possible de ” masquer ” un élément en modifiant sa couleur pour qu’elle corresponde à la couleur du fond de la page ou de l’élément parent. On pourrait ainsi imaginer masquer une \u003Ccode>border\u003C/code> ou un \u003Ccode>outline\u003C/code>.\u003C/p>\n\u003Cp>J’ai personnellement choisi de faire différemment. J’ai décidé d’utiliser un pseudo-élément \u003Ccode>::before\u003C/code> sur l’état non visité du lien puis de le masquer quand celui-ci devient visité.\u003C/p>\n\u003Ch3 id=\"le-code\">Le code\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">style.css\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">relative\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-decoration: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line highlight mark\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#eca3a8\">a\u003C/span>\u003Cspan style=\"--0:#73c3cc\">::before\u003C/span>\u003Cspan style=\"--0:#b0b6c3\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">inline-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">block-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">4\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-6\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: grey;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line highlight mark\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#eca3a8\">a\u003C/span>\u003Cspan style=\"--0:#73c3cc\">:visited::before\u003C/span>\u003Cspan style=\"--0:#b0b6c3\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"a { position: relative; text-decoration: none;}a::before { content: ''; position: absolute; top: 50%; left: 0; inline-size: 2px; block-size: 2px; border-radius: 4px; transform: translate(-6px, 0); background-color: grey;}a:visited::before { background-color: white;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Ces règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\u003C/p>\n\u003Ch3 id=\"accessibilité\">Accessibilité\u003C/h3>\n\u003Cp>On pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété \u003Ccode>content\u003C/code> mais les lecteurs d’écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d’écrans annoncent déjà si un lien est visité avant de lire son intitulé.\u003C/p>\n\u003Ch2 id=\"aller-plus-loin\">Aller plus loin\u003C/h2>\n\u003Cp>Afin de pousser l’expérience un peu plus loin, j’ai tenté d’utiliser des éléments plus explicites pour signifier l’état visité du lien. Bien qu’encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\u003C/p>\n\u003Cp>L’idée est d’avoir un \u003Ccode>::before\u003C/code> et un \u003Ccode>::after\u003C/code>, chacun contenant une icône en base 64 blanche en tant qu’image de fond. Quand le lien est non visité, le \u003Ccode>::before\u003C/code> contient un fond coloré qui fait apparaître l’icône. Quand le lien passe en visité, le fond du \u003Ccode>::before\u003C/code> devient blanc et celui du \u003Ccode>::after\u003C/code> devient coloré, ce qui masque la première icône et affiche la deuxième.\u003C/p>\n\u003Cp>Il est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l’une sur l’autre.\u003C/p>\n\u003Cp>\u003Ca href=\"https://codepen.io/narduin/pen/VwVwmrO\">Voir la démo sur codepen.\u003C/a>\u003C/p>",{"headings":368,"imagePaths":386,"frontmatter":387},[369,372,375,378,381,383],{"depth":30,"slug":370,"text":371},"la-théorie","La théorie",{"depth":30,"slug":373,"text":374},"la-spécification","La spécification",{"depth":30,"slug":376,"text":377},"la-pratique","La pratique",{"depth":88,"slug":379,"text":380},"le-code","Le code",{"depth":88,"slug":146,"text":382},"Accessibilité",{"depth":30,"slug":384,"text":385},"aller-plus-loin","Aller plus loin",[],{"title":357,"subtitle":358,"lang":15,"draft":361,"slug":354,"excerpt":287,"tags":388,"type":199,"createdAt":289},[132],"en-array-vs-array",{"id":389,"data":391,"body":396,"filePath":397,"digest":398,"rendered":399},{"title":392,"subtitle":393,"lang":196,"tags":394,"type":199,"slug":389,"createdAt":395},"Filter an array against another array","Array vs Array.",[296],["Date","2022-06-08T14:24:06.000Z"],"## Context\n\nFor a project, I had to come up with a way to filter an array of objects based on another array of strings.\n\nIn other words, I needed to include every object which `user` property was found in the second array.\n\nHere is an example:\n\n```javascript\nconst skills = [\n\t{\n\t\tname: 'Be awesome',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Great jokes',\n\t\tuser: 'Jacques'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Beatriz'\n\t}\n]\n\nconst selectedUsers = ['Jean', 'Beatriz']\n```\n\nI thought it would be pretty easy but I guess I'm not familiar enough with javascript 😬\n\n## My solution\n\nAfter a bit of thinking, I came up with the following statement:\n\n> I need to filter the skills based on which users are selected. So I need to loop over the `selectedUsers` array and filter the skills according to their `user` value.\n\nAfter a bit more trials and errors, this is the code I ended up using in a `computed property`:\n\n```javascript\n// index.vue\nconst filteredSkills = selectedUsers.map((user) => {\n\treturn skills.filter((skill) => {\n\t\treturn skill.user === user\n\t})\n})\n```\n\nI used `map()` in order to loop on the second array and used its string value to only include the corresponding skills with `filter()`.\n\nI'm pretty sure there is a better way to do it though…","src/content/fragments/en/array-vs-array.md","c63ba57b1049cf4c",{"html":400,"metadata":401},"\u003Ch2 id=\"context\">Context\u003C/h2>\n\u003Cp>For a project, I had to come up with a way to filter an array of objects based on another array of strings.\u003C/p>\n\u003Cp>In other words, I needed to include every object which \u003Ccode>user\u003C/code> property was found in the second array.\u003C/p>\n\u003Cp>Here is an example:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Be awesome'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Great jokes'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jacques'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Beatriz'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">selectedUsers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> [\u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#98C379\">'Beatriz'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const skills = [ { name: 'Be awesome', user: 'Jean' }, { name: 'Great jokes', user: 'Jacques' }, { name: 'Heavy sleeper', user: 'Jean' }, { name: 'Heavy sleeper', user: 'Beatriz' }]const selectedUsers = ['Jean', 'Beatriz']\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>I thought it would be pretty easy but I guess I’m not familiar enough with javascript 😬\u003C/p>\n\u003Ch2 id=\"my-solution\">My solution\u003C/h2>\n\u003Cp>After a bit of thinking, I came up with the following statement:\u003C/p>\n\u003Cblockquote>\n\u003Cp>I need to filter the skills based on which users are selected. So I need to loop over the \u003Ccode>selectedUsers\u003C/code> array and filter the skills according to their \u003Ccode>user\u003C/code> value.\u003C/p>\n\u003C/blockquote>\n\u003Cp>After a bit more trials and errors, this is the code I ended up using in a \u003Ccode>computed property\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">filteredSkills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">selectedUsers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">map\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">((\u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) \u003C/span>\u003Cspan style=\"--0:#CD89E1\">=>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">filter\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">((\u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">skill\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) \u003C/span>\u003Cspan style=\"--0:#CD89E1\">=>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skill\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">===\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const filteredSkills = selectedUsers.map((user) => { return skills.filter((skill) => { return skill.user === user })})\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>I used \u003Ccode>map()\u003C/code> in order to loop on the second array and used its string value to only include the corresponding skills with \u003Ccode>filter()\u003C/code>.\u003C/p>\n\u003Cp>I’m pretty sure there is a better way to do it though…\u003C/p>",{"headings":402,"imagePaths":409,"frontmatter":410},[403,406],{"depth":30,"slug":404,"text":405},"context","Context",{"depth":30,"slug":407,"text":408},"my-solution","My solution",[],{"title":392,"subtitle":393,"lang":196,"slug":389,"createdAt":307,"excerpt":411,"tags":412,"type":199},"My peak javascript",[296],"en-nuxt-graphql-static",{"id":413,"data":415,"body":421,"filePath":422,"digest":423,"rendered":424},{"title":416,"subtitle":417,"lang":196,"tags":418,"type":199,"slug":413,"createdAt":419,"updatedAt":420},"Static website and GraphQL queries with Nuxt.js","Graphql client is king.",[296],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## The problem\n\nI encountered a nasty bug while using static generation with Nuxt and [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (new tab)') client.\nI found [the issue](https://github.com/nuxt-community/apollo-module/issues/339 'Github issue on nuxt/apollo repository (new tab)') already reported on github.\n\nIt seems the module doesn't handle static generation correctly with `nuxt generate`.\n\nI could find request to my local API url after the static generation. Moreover, it also seemed like `\u003Cnuxt-link>` navigation was broken.\n\n## The solution 🙌\n\nFortunately, there is another Nuxt module that handles GraphQL requests!\n\n[Nuxt graphql request to the rescue!](https://github.com/gomah/nuxt-graphql-request)\n\n### The conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### The request\n\nThe best approach so far is to use `asyncData` in pages and `fetch` in components. Using `fetch` in pages does not work well at all with `nuxt generate`.\n\nI also install the `graphql-tag` package (only in `devDependencies`) to be able to import directly `.gql` files.\n\nQuery example:\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Inside a page\n\n```vue\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n\tasync asyncData({ $graphql }) {\n\t\tconst data = await $graphql.default.request(homepageQuery)\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```\n\n#### Inside a component\n\nIt is safer to wait until `fetch` has received a response before displaying anything. You can use `$fetchState` to be sure ([documentation](https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation on the fetch hook (new tab)')).\n\n```vue\n// Header.vue\n\u003Ctemplate>\n\t\u003Cheader v-if=\"!$fetchState.pending\">…\u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tdata: {}\n\t\t}\n\t},\n\tasync fetch() {\n\t\ttry {\n\t\t\tconst data = await this.$graphql.default.request(headerQuery)\n\t\t\tthis.data = data\n\t\t} catch (error) {\n\t\t\tconsole.error(JSON.stringify(error, undefined, 2))\n\t\t}\n\t}\n}\n\u003C/script>\n```\n\n### Options\n\nTo pass options to the request, for example for a multilingual version with [nuxt/i18n](https://i18n.nuxtjs.org/) and/or a url parameter in a dynamic page:\n\n```vue\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n\tasync asyncData({ $graphql, app, params }) {\n\t\tconst locale = app.i18n.localeProperties.iso\n\t\tconst data = await $graphql.default.request(articleQuery, {\n\t\t\tcode: locale,\n\t\t\tslug: params.slug\n\t\t})\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```","src/content/fragments/en/nuxt-graphql-static.md","c5d4f0dd6ca0e1c2",{"html":425,"metadata":426},"\u003Ch2 id=\"the-problem\">The problem\u003C/h2>\n\u003Cp>I encountered a nasty bug while using static generation with Nuxt and \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (new tab)\">nuxt apollo\u003C/a> client.\nI found \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Github issue on nuxt/apollo repository (new tab)\">the issue\u003C/a> already reported on github.\u003C/p>\n\u003Cp>It seems the module doesn’t handle static generation correctly with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I could find request to my local API url after the static generation. Moreover, it also seemed like \u003Ccode><nuxt-link>\u003C/code> navigation was broken.\u003C/p>\n\u003Ch2 id=\"the-solution\">The solution 🙌\u003C/h2>\n\u003Cp>Fortunately, there is another Nuxt module that handles GraphQL requests!\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\">Nuxt graphql request to the rescue!\u003C/a>\u003C/p>\n\u003Ch3 id=\"the-conf\">The conf\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">nuxt.config.js\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">buildModules\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">clients\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">endpoint\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">options\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">authorization\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"buildModules: [ 'nuxt-graphql-request',],graphql: { clients: { default: { endpoint: 'http://API_URL/graphql', options: { headers: { authorization: 'Bearer API_TOKEN', }, }, }, },},\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"the-request\">The request\u003C/h3>\n\u003Cp>The best approach so far is to use \u003Ccode>asyncData\u003C/code> in pages and \u003Ccode>fetch\u003C/code> in components. Using \u003Ccode>fetch\u003C/code> in pages does not work well at all with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I also install the \u003Ccode>graphql-tag\u003C/code> package (only in \u003Ccode>devDependencies\u003C/code>) to be able to import directly \u003Ccode>.gql\u003C/code> files.\u003C/p>\n\u003Cp>Query example:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">homepage.gql\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"graphql\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">query\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepage\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">subtitle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">hero\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">id\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">alt\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"query { homepage { title subtitle hero { id alt } }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"inside-a-page\">Inside a page\u003C/h4>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/homepage'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import homepageQuery from '~/graphql/queries/singles/homepage'export default { async asyncData({ $graphql }) { const data = await $graphql.default.request(homepageQuery) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"inside-a-component\">Inside a component\u003C/h4>\n\u003Cp>It is safer to wait until \u003Ccode>fetch\u003C/code> has received a response before displaying anything. You can use \u003Ccode>$fetchState\u003C/code> to be sure (\u003Ca href=\"https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation on the fetch hook (new tab)\">documentation\u003C/a>).\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">Header.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">v-if\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#56B6C2\">!\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$fetchState\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">pending\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>…</\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/header'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">fetch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">try\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">} \u003C/span>\u003Cspan style=\"--0:#CD89E1\">catch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> (\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">console\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E5C07B\">JSON\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">stringify\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">undefined\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">))\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ctemplate> \u003Cheader v-if="!$fetchState.pending">…\u003C/header>\u003C/template>\u003Cscript>import headerQuery from '~/graphql/queries/singles/header'export default { data() { return { data: {} } }, async fetch() { try { const data = await this.$graphql.default.request(headerQuery) this.data = data } catch (error) { console.error(JSON.stringify(error, undefined, 2)) } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"options\">Options\u003C/h3>\n\u003Cp>To pass options to the request, for example for a multilingual version with \u003Ca href=\"https://i18n.nuxtjs.org/\">nuxt/i18n\u003C/a> and/or a url parameter in a dynamic page:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">_slug.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/articles'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">i18n\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">localeProperties\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">iso\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">code\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E6888F\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E5C07B\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import articleQuery from '~/graphql/queries/articles'export default { async asyncData({ $graphql, app, params }) { const locale = app.i18n.localeProperties.iso const data = await $graphql.default.request(articleQuery, { code: locale, slug: params.slug }) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":427,"imagePaths":450,"frontmatter":451},[428,431,434,437,440,444,447],{"depth":30,"slug":429,"text":430},"the-problem","The problem",{"depth":30,"slug":432,"text":433},"the-solution","The solution 🙌",{"depth":88,"slug":435,"text":436},"the-conf","The conf",{"depth":88,"slug":438,"text":439},"the-request","The request",{"depth":441,"slug":442,"text":443},4,"inside-a-page","Inside a page",{"depth":441,"slug":445,"text":446},"inside-a-component","Inside a component",{"depth":88,"slug":448,"text":449},"options","Options",[],{"title":416,"subtitle":417,"lang":196,"slug":413,"createdAt":307,"updatedAt":452,"excerpt":453,"tags":454,"type":199},"2022-09-08T13:43:33.000Z","When the most used gql module doesn't work…",[296],"nuxt-graphql-static",{"id":455,"data":457,"body":463,"filePath":464,"digest":465,"rendered":466},{"title":458,"subtitle":459,"lang":15,"tags":460,"type":189,"slug":455,"createdAt":461,"updatedAt":462},"Site statique et requêtes GraphQL avec Nuxt.js","Le client graphql est roi.",[296],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## Le problème\n\nJe me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (nouvel onglet)').\nAprès quelques recherches, voici [le bug constaté par quelqu'un d'autre](https://github.com/nuxt-community/apollo-module/issues/339 'Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)') sur github.\n\nIl semblerait que le module en l'état ne gère pas correctement la génération statique avec `nuxt generate`.\n\nJe trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les `\u003Cnuxt-link>` ne fonctionnait pas.\n\n## La solution 🙌\n\nHeureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\n\n[Nuxt graphql request à la rescousse !](https://github.com/gomah/nuxt-graphql-request 'Dépôt github du module (nouvel onglet)')\n\n### La conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### La requête\n\nLa meilleure méthode à ce jour est d'utiliser `asyncData` dans les pages et `fetch` dans les composants. Utiliser `fetch` dans les pages ne fonctionne pas bien du tout avec `nuxt generate`.\n\nJ'installe également le paquet `graphql-tag` (uniquement en `devDependencies`) afin de pouvoir importer directement des fichiers `.gql`\n\nExemple de fichier :\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Dans une page\n\n```vue\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n\tasync asyncData({ $graphql }) {\n\t\tconst data = await $graphql.default.request(homepageQuery)\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```\n\n#### Dans un composant\n\nIl est plus prudent d'attendre que `fetch` ait reçu une réponse avant d'afficher quoi que ce soit. On peut utiliser `$fetchState` afin d'être tranquille ([documentation](https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation sur la méthode fetch (nouvel onglet)')).\n\n```vue\n// Header.vue\n\u003Ctemplate>\n\t\u003Cheader v-if=\"!$fetchState.pending\">…\u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tdata: {}\n\t\t}\n\t},\n\tasync fetch() {\n\t\ttry {\n\t\t\tconst data = await this.$graphql.default.request(headerQuery)\n\t\t\tthis.data = data\n\t\t} catch (error) {\n\t\t\tconsole.error(JSON.stringify(error, undefined, 2))\n\t\t}\n\t}\n}\n\u003C/script>\n```\n\n### Les options\n\nPour passer des options à la requête, par exemple pour une version multilingue avec [nuxt/i18n](https://i18n.nuxtjs.org/ 'Documentation de nuxt i18n (nouvel onglet)') et/ou un paramètre d'url dans le cadre d'une page dynamique :\n\n```vue\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n\tasync asyncData({ $graphql, app, params }) {\n\t\tconst locale = app.i18n.localeProperties.iso\n\t\tconst data = await $graphql.default.request(articleQuery, {\n\t\t\tcode: locale,\n\t\t\tslug: params.slug\n\t\t})\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```","src/content/fragments/fr/nuxt-graphql-static.md","6304f174b83f0078",{"html":467,"metadata":468},"\u003Ch2 id=\"le-problème\">Le problème\u003C/h2>\n\u003Cp>Je me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (nouvel onglet)\">nuxt apollo\u003C/a>.\nAprès quelques recherches, voici \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)\">le bug constaté par quelqu’un d’autre\u003C/a> sur github.\u003C/p>\n\u003Cp>Il semblerait que le module en l’état ne gère pas correctement la génération statique avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>Je trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les \u003Ccode><nuxt-link>\u003C/code> ne fonctionnait pas.\u003C/p>\n\u003Ch2 id=\"la-solution\">La solution 🙌\u003C/h2>\n\u003Cp>Heureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\" title=\"Dépôt github du module (nouvel onglet)\">Nuxt graphql request à la rescousse !\u003C/a>\u003C/p>\n\u003Ch3 id=\"la-conf\">La conf\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">nuxt.config.js\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">buildModules\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">clients\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">endpoint\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">options\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">authorization\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"buildModules: [ 'nuxt-graphql-request',],graphql: { clients: { default: { endpoint: 'http://API_URL/graphql', options: { headers: { authorization: 'Bearer API_TOKEN', }, }, }, },},\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"la-requête\">La requête\u003C/h3>\n\u003Cp>La meilleure méthode à ce jour est d’utiliser \u003Ccode>asyncData\u003C/code> dans les pages et \u003Ccode>fetch\u003C/code> dans les composants. Utiliser \u003Ccode>fetch\u003C/code> dans les pages ne fonctionne pas bien du tout avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>J’installe également le paquet \u003Ccode>graphql-tag\u003C/code> (uniquement en \u003Ccode>devDependencies\u003C/code>) afin de pouvoir importer directement des fichiers \u003Ccode>.gql\u003C/code>\u003C/p>\n\u003Cp>Exemple de fichier :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">homepage.gql\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"graphql\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">query\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepage\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">subtitle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">hero\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">id\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">alt\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"query { homepage { title subtitle hero { id alt } }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"dans-une-page\">Dans une page\u003C/h4>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/homepage'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import homepageQuery from '~/graphql/queries/singles/homepage'export default { async asyncData({ $graphql }) { const data = await $graphql.default.request(homepageQuery) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"dans-un-composant\">Dans un composant\u003C/h4>\n\u003Cp>Il est plus prudent d’attendre que \u003Ccode>fetch\u003C/code> ait reçu une réponse avant d’afficher quoi que ce soit. On peut utiliser \u003Ccode>$fetchState\u003C/code> afin d’être tranquille (\u003Ca href=\"https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation sur la méthode fetch (nouvel onglet)\">documentation\u003C/a>).\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">Header.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">v-if\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#56B6C2\">!\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$fetchState\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">pending\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>…</\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/header'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">fetch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">try\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">} \u003C/span>\u003Cspan style=\"--0:#CD89E1\">catch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> (\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">console\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E5C07B\">JSON\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">stringify\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">undefined\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">))\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ctemplate> \u003Cheader v-if="!$fetchState.pending">…\u003C/header>\u003C/template>\u003Cscript>import headerQuery from '~/graphql/queries/singles/header'export default { data() { return { data: {} } }, async fetch() { try { const data = await this.$graphql.default.request(headerQuery) this.data = data } catch (error) { console.error(JSON.stringify(error, undefined, 2)) } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"les-options\">Les options\u003C/h3>\n\u003Cp>Pour passer des options à la requête, par exemple pour une version multilingue avec \u003Ca href=\"https://i18n.nuxtjs.org/\" title=\"Documentation de nuxt i18n (nouvel onglet)\">nuxt/i18n\u003C/a> et/ou un paramètre d’url dans le cadre d’une page dynamique :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">_slug.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/articles'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">i18n\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">localeProperties\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">iso\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">code\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E6888F\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E5C07B\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import articleQuery from '~/graphql/queries/articles'export default { async asyncData({ $graphql, app, params }) { const locale = app.i18n.localeProperties.iso const data = await $graphql.default.request(articleQuery, { code: locale, slug: params.slug }) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":469,"imagePaths":491,"frontmatter":492},[470,473,476,479,482,485,488],{"depth":30,"slug":471,"text":472},"le-problème","Le problème",{"depth":30,"slug":474,"text":475},"la-solution","La solution 🙌",{"depth":88,"slug":477,"text":478},"la-conf","La conf",{"depth":88,"slug":480,"text":481},"la-requête","La requête",{"depth":441,"slug":483,"text":484},"dans-une-page","Dans une page",{"depth":441,"slug":486,"text":487},"dans-un-composant","Dans un composant",{"depth":88,"slug":489,"text":490},"les-options","Les options",[],{"title":458,"subtitle":459,"lang":15,"slug":455,"createdAt":307,"updatedAt":452,"excerpt":493,"tags":494,"type":189},"Quand le module gql le plus utilisé ne fonctionne pas…",[296],"en-buttons",{"id":495,"data":497,"body":502,"filePath":503,"digest":504,"rendered":505},{"title":498,"subtitle":499,"lang":196,"tags":500,"type":199,"slug":495,"createdAt":501,"code":202,"draft":202},"Buttons hover","Simple, but nice.",[198],["Date","2020-10-08T09:00:00.000Z"],"## General rules\n\nAll the buttons use these styles as a “reset”:\n\n> Don't forget to prefix if necessary!\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Add an icon\n\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('~assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double shutter down\n\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Animated gradient\n\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Non destructive scale\n\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/en/buttons.md","ea9a5513a5a4cef4",{"html":506,"metadata":507},"\u003Ch2 id=\"general-rules\">General rules\u003C/h2>\n\u003Cp>All the buttons use these styles as a “reset”:\u003C/p>\n\u003Cblockquote>\n\u003Cp>Don’t forget to prefix if necessary!\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">margin: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">padding: \u003C/span>\u003Cspan style=\"--0:#D19A66\">12\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">26\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">relative\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">display: \u003C/span>\u003Cspan style=\"--0:#D19A66\">inline-block\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">overflow: \u003C/span>\u003Cspan style=\"--0:#D19A66\">hidden\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">font-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">rem\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">; \u003C/span>\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\">/* 20px */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">line-height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">1.6\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-align: \u003C/span>\u003Cspan style=\"--0:#D19A66\">center\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-decoration: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">font-weight: \u003C/span>\u003Cspan style=\"--0:#D19A66\">bold\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">cursor: \u003C/span>\u003Cspan style=\"--0:#D19A66\">pointer\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">-moz-appearance\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">-webkit-appearance\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: background-color \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn { margin: 20px 0; padding: 12px 26px; position: relative; display: inline-block; overflow: hidden; font-size: 20rem; /* 20px */ line-height: 1.6; text-align: center; text-decoration: none; font-weight: bold; cursor: pointer; border: none; border-radius: 2px; -moz-appearance: none; -webkit-appearance: none; color: white; background-color: hotpink; transition: background-color 0.3s ease;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"add-an-icon\">Add an icon\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">url\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#98C379\">'~assets/svg/arrow-right-white.svg'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">right: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">40\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">-50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: darkorchid;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-10\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">-50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">display: \u003C/span>\u003Cspan style=\"--0:#D19A66\">inline-block\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">27\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">28\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">29\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translateX\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-10\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">30\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-icon { background-color: hotpink;}.btn-icon::before { content: url('~assets/svg/arrow-right-white.svg'); position: absolute; width: 20px; top: 50%; right: 0; transform: translate(40px, -50%); transition: transform ease 0.3s;}.btn-icon:hover,.btn-icon:focus { background-color: darkorchid;}.btn-icon:hover::before,.btn-icon:focus::before { transform: translate(-10px, -50%);}.btn-icon > span { display: inline-block; width: 100%; height: 100%; transition: transform 0.3s ease;}.btn-icon:hover > span,.btn-icon:focus > span { transform: translateX(-10px);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"double-shutter-down\">Double shutter down\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">solid\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">transparent\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: \u003C/span>\u003Cspan style=\"--0:#D19A66\">color\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: darkorchid;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">bottom: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">z-index: \u003C/span>\u003Cspan style=\"--0:#D19A66\">-1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-timing-function: \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">27\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-timing-function: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">cubic-bezier\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">0.75\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.125\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">28\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">29\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">30\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">31\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">32\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">33\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translateY\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">34\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">35\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">36\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">37\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-delay: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.175\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">38\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-rideau { border: 2px solid #10113a; color: #10113a; background-color: transparent; transition: color 0.3s ease;}.btn-rideau:hover { color: white;}.btn-rideau::before { background: hotpink;}.btn-rideau::after { background: darkorchid;}.btn-rideau::before,.btn-rideau::after { content: ''; position: absolute; height: 100%; width: 100%; bottom: 100%; left: 0; z-index: -1; transition: transform 0.3s; transition-timing-function: ease; transition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);}.btn-rideau:hover::before,.btn-rideau:hover::after,.btn-rideau:focus::before,.btn-rideau:focus::after { transform: translateY(100%);}.btn-rideau:hover::after,.btn-rideau:focus::after { transition-delay: 0.175s;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"animated-gradient\">Animated gradient\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">linear-gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-45\u003C/span>\u003Cspan style=\"--0:#E6888F\">deg\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#ee7752\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#e73c7e\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#23a6d5\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#23d5ab\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">400\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">400\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">animation: GradientReverse \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.5\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">normal\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">forwards\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">animation: Gradient \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.5\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">normal\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">forwards\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">@keyframes\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">Gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">0% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">100% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">@keyframes\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">GradientReverse\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">0% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">100% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-gradient { background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); background-size: 400% 400%; background-position: 0% 50%; animation: GradientReverse 0.5s ease 1 normal forwards;}.btn-gradient:hover,.btn-gradient:focus { animation: Gradient 0.5s ease 1 normal forwards;}@keyframes Gradient { 0% { background-position: 0% 50%; } 100% { background-position: 100% 100%; }}@keyframes GradientReverse { 0% { background-position: 100% 100%; } 100% { background-position: 0% 50%; }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"non-destructive-scale\">Non destructive scale\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">overflow: \u003C/span>\u003Cspan style=\"--0:#D19A66\">visible\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">transparent\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">bottom: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">solid\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">scale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">1.1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-scale { overflow: visible; color: #10113a; background-color: transparent;}.btn-scale::after { content: ''; position: absolute; top: 0; left: 0; bottom: 0; width: 100%; border: 2px solid #10113a; border-radius: 2px; transition: transform 0.3s ease;}.btn-scale:hover::after,.btn-scale:focus::after { transform: scale(1.1);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":508,"imagePaths":524,"frontmatter":525},[509,512,515,518,521],{"depth":30,"slug":510,"text":511},"general-rules","General rules",{"depth":30,"slug":513,"text":514},"add-an-icon","Add an icon",{"depth":30,"slug":516,"text":517},"double-shutter-down","Double shutter down",{"depth":30,"slug":519,"text":520},"animated-gradient","Animated gradient",{"depth":30,"slug":522,"text":523},"non-destructive-scale","Non destructive scale",[],{"title":498,"subtitle":499,"lang":196,"slug":495,"draft":202,"excerpt":526,"tags":527,"code":202,"type":199,"createdAt":528},"Easy to grab and use hover effects.",[198],"2020-10-08T09:00:00.000Z","en-acme-sh-tls-cert",{"id":529,"data":531,"body":537,"filePath":538,"digest":539,"rendered":540},{"title":532,"subtitle":533,"lang":196,"tags":534,"type":199,"slug":529,"createdAt":536},"Strong TLS certificates with acme.sh","384-bit of https",[535],"security",["Date","2022-06-08T14:24:06.000Z"],"## Disclaimer\n\nI'm, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs. \nThis is why I've switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nYou can learn (far) more by reading [this topic](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) and its linked resources.\n\n## Requirements\n\n### Installing acme.sh\n\nFor automation and ease of use purposes, I'm using [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# for using standalone mode, you might have to install as sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changing default authority\n\nBy default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let's Encrypt because according to acme.sh, they're the only ones offering ECC capabilities.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Using your DNS api\n\nIf available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports [a lot](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) of DNS providers.\n\n### Define an api key\n\nFollow the [docs](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) for your DNS provider, usually:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Issue the cert\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Using standalone mode\n\nIf you don't have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\n\nPort `80` must be free.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Examples\n\n### Multi domains standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domain DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Next steps\n\nThe ECC certificate alone will not grant you a high/perfect score.\n\n### TLS version\n\nLimit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a [5% compatibility gap](https://caniuse.com/?search=tls%201.) with 1.2).\n\n### HSTS\n\nUse the [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/) header.\n\n```http\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Cipher suite\n\nUse recent and strong ciphers. This is where my knowledge hits its limit… I'm having a really hard time understanding what to use and why.\n\nI've based my initial choices of ciphers on [this list](https://tls.imirhil.fr/ciphers), cross referencing it with (older?) [browser compatibility](https://tls.imirhil.fr/suite).\n\nI then asked [Aeris](https://twitter.com/aeris22), the creator of [tls.imirhil.fr](https://tls.imirhil.fr), about it and he advised me to use the following:\n\n```cypher\nECDHE+AES:ECDHE+CHACHA20\n```\n\nIn order to achieve a perfect score, we can be a little more restrictive with:\n\n```cypher\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/en/acme-sh-tls-cert.md","4dc80f1d0e800d6f",{"html":541,"metadata":542},"\u003Ch2 id=\"disclaimer\">Disclaimer\u003C/h2>\n\u003Cp>I’m, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs.\u003Cbr>\nThis is why I’ve switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>You can learn (far) more by reading \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">this topic\u003C/a> and its linked resources.\u003C/p>\n\u003Ch2 id=\"requirements\">Requirements\u003C/h2>\n\u003Ch3 id=\"installing-acmesh\">Installing acme.sh\u003C/h3>\n\u003Cp>For automation and ease of use purposes, I’m using \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\"># for using standalone mode, you might have to install as sudo\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">curl\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">https://get.acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> | \u003C/span>\u003Cspan style=\"--0:#61AFEF\">sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">email=mail@domain.tld\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl https://get.acme.sh | sh -s email=mail@domain.tld\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"changing-default-authority\">Changing default authority\u003C/h3>\n\u003Cp>By default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let’s Encrypt because according to acme.sh, they’re the only ones offering ECC capabilities.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--set-default-ca\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--server\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">letsencrypt\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --set-default-ca --server letsencrypt\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"using-your-dns-api\">Using your DNS api\u003C/h2>\n\u003Cp>If available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">a lot\u003C/a> of DNS providers.\u003C/p>\n\u003Ch3 id=\"define-an-api-key\">Define an api key\u003C/h3>\n\u003Cp>Follow the \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">docs\u003C/a> for your DNS provider, usually:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">PROVIDER_Key\u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#98C379\">\"YOUR_API_KEY\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export PROVIDER_Key="YOUR_API_KEY"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"issue-the-cert\">Issue the cert\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"using-standalone-mode\">Using standalone mode\u003C/h2>\n\u003Cp>If you don’t have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\u003C/p>\n\u003Cp>Port \u003Ccode>80\u003C/code> must be free.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"examples\">Examples\u003C/h2>\n\u003Ch3 id=\"multi-domains-standalone\">Multi domains standalone\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">www.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">subdomain.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"wildcard-domain-dns\">Wildcard domain DNS\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'*.domain.tld'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"next-steps\">Next steps\u003C/h2>\n\u003Cp>The ECC certificate alone will not grant you a high/perfect score.\u003C/p>\n\u003Ch3 id=\"tls-version\">TLS version\u003C/h3>\n\u003Cp>Limit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a \u003Ca href=\"https://caniuse.com/?search=tls%201.\">5% compatibility gap\u003C/a> with 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Use the \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a> header.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">Strict-Transport-Security\u003C/span>\u003Cspan style=\"--0:#CD89E1\">:\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">max-age=31536000; includeSubDomains\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Strict-Transport-Security: max-age=31536000; includeSubDomains\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"cipher-suite\">Cipher suite\u003C/h3>\n\u003Cp>Use recent and strong ciphers. This is where my knowledge hits its limit… I’m having a really hard time understanding what to use and why.\u003C/p>\n\u003Cp>I’ve based my initial choices of ciphers on \u003Ca href=\"https://tls.imirhil.fr/ciphers\">this list\u003C/a>, cross referencing it with (older?) \u003Ca href=\"https://tls.imirhil.fr/suite\">browser compatibility\u003C/a>.\u003C/p>\n\u003Cp>I then asked \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, the creator of \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, about it and he advised me to use the following:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>In order to achieve a perfect score, we can be a little more restrictive with:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES256\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES256:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":543,"imagePaths":589,"frontmatter":590},[544,547,550,553,556,559,562,565,568,571,574,577,580,583,586],{"depth":30,"slug":545,"text":546},"disclaimer","Disclaimer",{"depth":30,"slug":548,"text":549},"requirements","Requirements",{"depth":88,"slug":551,"text":552},"installing-acmesh","Installing acme.sh",{"depth":88,"slug":554,"text":555},"changing-default-authority","Changing default authority",{"depth":30,"slug":557,"text":558},"using-your-dns-api","Using your DNS api",{"depth":88,"slug":560,"text":561},"define-an-api-key","Define an api key",{"depth":88,"slug":563,"text":564},"issue-the-cert","Issue the cert",{"depth":30,"slug":566,"text":567},"using-standalone-mode","Using standalone mode",{"depth":30,"slug":569,"text":570},"examples","Examples",{"depth":88,"slug":572,"text":573},"multi-domains-standalone","Multi domains standalone",{"depth":88,"slug":575,"text":576},"wildcard-domain-dns","Wildcard domain DNS",{"depth":30,"slug":578,"text":579},"next-steps","Next steps",{"depth":88,"slug":581,"text":582},"tls-version","TLS version",{"depth":88,"slug":584,"text":585},"hsts","HSTS",{"depth":88,"slug":587,"text":588},"cipher-suite","Cipher suite",[],{"title":532,"subtitle":533,"lang":196,"slug":529,"createdAt":307,"excerpt":591,"tags":592,"type":199},"Real cert have curves.",[535],"acme-sh-tls-cert",{"id":593,"data":595,"body":601,"filePath":602,"digest":603,"rendered":604},{"title":596,"subtitle":597,"lang":15,"tags":598,"type":189,"slug":593,"createdAt":600},"Certificates TLS robustes avec acme.sh","384-bit de https",[599],"sécurité",["Date","2022-06-08T14:24:06.000Z"],"## Attention\n\nJe ne suis pas du tout un expert en sécurité. J'aime juste les trucs nouveaux et stylés des internets. \nC'est pourquoi j'ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J'ai maintenant un joli 100/100 sur [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nVous pouvez en apprendre (beaucoup) plus [ici](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) et sur les liens cités (en anglais).\n\n## Prérequis\n\n### Installer acme.sh\n\nPour des raisons de simplicité et d'automatisation, j'utilise [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changer l'authorité par défaut\n\nPar défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let's Encrypt car, d'après acme.sh, ils sont les seuls à proposer des certificats ECC.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Utiliser l'api DNS\n\nSi vous en avez la possibilité, la façon la plus simple de générer un certificat est via l'api de votre fournisseur DNS. acme.sh supporte [énormément](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) de fournisseurs DNS.\n\n### Definir la clé api\n\nSuivez la [documentation](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) pour votre fournisseur DNS, généralement:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Émettre le certificat\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Utiliser le mode standalone\n\nSi vous n'avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s'occupe de toutes les vérifications.\n\nLe port `80` doit être disponible.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Exemples\n\n### Multi domaines standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domaine DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Étapes supplémentaires\n\nLe certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\n\n### Version TLS\n\nLimiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu [la différence de compatibilité de 5%](https://caniuse.com/?search=tls%201.) avec 1.2).\n\n### HSTS\n\nUtiliser le header [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/).\n\n```http\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Suite cryptographique\n\nUtiliser une suite cryptographique récente et robuste. C'est ici que mes connaissances deviennent limitées… J'ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\n\nJ'avais basé ma première suite sur [cette liste](https://tls.imirhil.fr/ciphers), en la comparant avec celle de la compatibilité (d'anciens ?) [navigateurs](https://tls.imirhil.fr/suite).\n\nJ'ai ensuite demandé à [Aeris](https://twitter.com/aeris22), le créateur de [tls.imirhil.fr](https://tls.imirhil.fr), ses conseils sur cette suite. Il m'a recommandé d'utiliser :\n\n```cypher\nECDHE+AES:ECDHE+CHACHA20\n```\n\nAfin d'atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\n\n```cypher\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/fr/acme-sh-tls-cert.md","018b0c09d1fdd6cc",{"html":605,"metadata":606},"\u003Ch2 id=\"attention\">Attention\u003C/h2>\n\u003Cp>Je ne suis pas du tout un expert en sécurité. J’aime juste les trucs nouveaux et stylés des internets.\u003Cbr>\nC’est pourquoi j’ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J’ai maintenant un joli 100/100 sur \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>Vous pouvez en apprendre (beaucoup) plus \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">ici\u003C/a> et sur les liens cités (en anglais).\u003C/p>\n\u003Ch2 id=\"prérequis\">Prérequis\u003C/h2>\n\u003Ch3 id=\"installer-acmesh\">Installer acme.sh\u003C/h3>\n\u003Cp>Pour des raisons de simplicité et d’automatisation, j’utilise \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.b5f0m.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\"># pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">curl\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">https://get.acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> | \u003C/span>\u003Cspan style=\"--0:#61AFEF\">sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">email=mail@domain.tld\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl https://get.acme.sh | sh -s email=mail@domain.tld\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"changer-lauthorité-par-défaut\">Changer l’authorité par défaut\u003C/h3>\n\u003Cp>Par défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let’s Encrypt car, d’après acme.sh, ils sont les seuls à proposer des certificats ECC.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--set-default-ca\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--server\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">letsencrypt\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --set-default-ca --server letsencrypt\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"utiliser-lapi-dns\">Utiliser l’api DNS\u003C/h2>\n\u003Cp>Si vous en avez la possibilité, la façon la plus simple de générer un certificat est via l’api de votre fournisseur DNS. acme.sh supporte \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">énormément\u003C/a> de fournisseurs DNS.\u003C/p>\n\u003Ch3 id=\"definir-la-clé-api\">Definir la clé api\u003C/h3>\n\u003Cp>Suivez la \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">documentation\u003C/a> pour votre fournisseur DNS, généralement:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">PROVIDER_Key\u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#98C379\">\"YOUR_API_KEY\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export PROVIDER_Key="YOUR_API_KEY"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"émettre-le-certificat\">Émettre le certificat\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"utiliser-le-mode-standalone\">Utiliser le mode standalone\u003C/h2>\n\u003Cp>Si vous n’avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s’occupe de toutes les vérifications.\u003C/p>\n\u003Cp>Le port \u003Ccode>80\u003C/code> doit être disponible.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"exemples\">Exemples\u003C/h2>\n\u003Ch3 id=\"multi-domaines-standalone\">Multi domaines standalone\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">www.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">subdomain.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"wildcard-domaine-dns\">Wildcard domaine DNS\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'*.domain.tld'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"étapes-supplémentaires\">Étapes supplémentaires\u003C/h2>\n\u003Cp>Le certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\u003C/p>\n\u003Ch3 id=\"version-tls\">Version TLS\u003C/h3>\n\u003Cp>Limiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu \u003Ca href=\"https://caniuse.com/?search=tls%201.\">la différence de compatibilité de 5%\u003C/a> avec 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Utiliser le header \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a>.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">Strict-Transport-Security\u003C/span>\u003Cspan style=\"--0:#CD89E1\">:\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">max-age=31536000; includeSubDomains\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Strict-Transport-Security: max-age=31536000; includeSubDomains\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"suite-cryptographique\">Suite cryptographique\u003C/h3>\n\u003Cp>Utiliser une suite cryptographique récente et robuste. C’est ici que mes connaissances deviennent limitées… J’ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\u003C/p>\n\u003Cp>J’avais basé ma première suite sur \u003Ca href=\"https://tls.imirhil.fr/ciphers\">cette liste\u003C/a>, en la comparant avec celle de la compatibilité (d’anciens ?) \u003Ca href=\"https://tls.imirhil.fr/suite\">navigateurs\u003C/a>.\u003C/p>\n\u003Cp>J’ai ensuite demandé à \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, le créateur de \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, ses conseils sur cette suite. Il m’a recommandé d’utiliser :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Afin d’atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES256\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES256:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":607,"imagePaths":651,"frontmatter":652},[608,611,614,617,620,623,626,629,632,635,638,641,644,647,648],{"depth":30,"slug":609,"text":610},"attention","Attention",{"depth":30,"slug":612,"text":613},"prérequis","Prérequis",{"depth":88,"slug":615,"text":616},"installer-acmesh","Installer acme.sh",{"depth":88,"slug":618,"text":619},"changer-lauthorité-par-défaut","Changer l’authorité par défaut",{"depth":30,"slug":621,"text":622},"utiliser-lapi-dns","Utiliser l’api DNS",{"depth":88,"slug":624,"text":625},"definir-la-clé-api","Definir la clé api",{"depth":88,"slug":627,"text":628},"émettre-le-certificat","Émettre le certificat",{"depth":30,"slug":630,"text":631},"utiliser-le-mode-standalone","Utiliser le mode standalone",{"depth":30,"slug":633,"text":634},"exemples","Exemples",{"depth":88,"slug":636,"text":637},"multi-domaines-standalone","Multi domaines standalone",{"depth":88,"slug":639,"text":640},"wildcard-domaine-dns","Wildcard domaine DNS",{"depth":30,"slug":642,"text":643},"étapes-supplémentaires","Étapes supplémentaires",{"depth":88,"slug":645,"text":646},"version-tls","Version TLS",{"depth":88,"slug":584,"text":585},{"depth":88,"slug":649,"text":650},"suite-cryptographique","Suite cryptographique",[],{"title":596,"subtitle":597,"lang":15,"slug":593,"createdAt":307,"excerpt":653,"tags":654,"type":189},"La sécurité avec des courbes.",[599],"articles",["Map",657,658,691,692,725,726,747,748,758,759,775,776,790,791,803,804,816,817,827,828,175,857,885,886,902,903,946,947,957,958,967,968,984,985],"en-2022",{"id":657,"data":659,"body":665,"filePath":666,"digest":667,"rendered":668},{"title":660,"subtitle":661,"lang":196,"tags":662,"type":655,"slug":657,"createdAt":664},"Nico v2.0","2022 update of many things.",[663],"Freelance",["Date","2022-06-08T14:24:06.000Z"],"After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\n\n## Services\n\n### No more print\n\nEven though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for \"classic\" graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\n\n### Internet all the way\n\nOn the other hand, I spend my time **doing web stuff.** A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer **more specific web offerings,** in which I have specialised.\n\nThus, **accessibility** and **eco-design** become integrated expertises in my practice. They are no longer options on a quote but **my core business.**\n\n## The website\n\nI have reworked my website, especially the homepage and its content, to better reflect these decisions.\n\nI have also made several behavioural changes:\n\n- external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven't found a good reason to continue using this behaviour;\n- I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu);\n- \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\n- I only trigger animations if the user has not asked the system to reduce the amount motion [(reference)](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).\n\nI am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello [astro](https://astro.build/) 👀).\n\n## Le Nico\n\nOn a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\n\nI have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.","src/content/articles/en/2022.md","7b98592763cb0929",{"html":669,"metadata":670},"\u003Cp>After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\u003C/p>\n\u003Ch2 id=\"services\">Services\u003C/h2>\n\u003Ch3 id=\"no-more-print\">No more print\u003C/h3>\n\u003Cp>Even though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for “classic” graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\u003C/p>\n\u003Ch3 id=\"internet-all-the-way\">Internet all the way\u003C/h3>\n\u003Cp>On the other hand, I spend my time \u003Cstrong>doing web stuff.\u003C/strong> A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer \u003Cstrong>more specific web offerings,\u003C/strong> in which I have specialised.\u003C/p>\n\u003Cp>Thus, \u003Cstrong>accessibility\u003C/strong> and \u003Cstrong>eco-design\u003C/strong> become integrated expertises in my practice. They are no longer options on a quote but \u003Cstrong>my core business.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Cp>I have reworked my website, especially the homepage and its content, to better reflect these decisions.\u003C/p>\n\u003Cp>I have also made several behavioural changes:\u003C/p>\n\u003Cul>\n\u003Cli>external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven’t found a good reason to continue using this behaviour;\u003C/li>\n\u003Cli>I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a>;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\u003C/li>\n\u003Cli>I only trigger animations if the user has not asked the system to reduce the amount motion \u003Ca href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion\">(reference)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>I am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello \u003Ca href=\"https://astro.build/\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>On a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\u003C/p>\n\u003Cp>I have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.\u003C/p>",{"headings":671,"imagePaths":687,"frontmatter":688},[672,675,678,681,684],{"depth":30,"slug":673,"text":674},"services","Services",{"depth":88,"slug":676,"text":677},"no-more-print","No more print",{"depth":88,"slug":679,"text":680},"internet-all-the-way","Internet all the way",{"depth":30,"slug":682,"text":683},"the-website","The website",{"depth":30,"slug":685,"text":686},"le-nico","Le Nico",[],{"title":660,"subtitle":661,"lang":196,"slug":657,"excerpt":689,"tags":690,"type":655,"createdAt":307},"Changes in my services, the website and myself.",[663],"en-2023",{"id":691,"data":693,"body":699,"filePath":700,"digest":701,"rendered":702},{"title":694,"subtitle":695,"lang":196,"tags":696,"type":655,"slug":691,"createdAt":697,"updatedAt":698},"Nico v2.5","Update 2023.",[663],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"This article will be updated when I have something new to share during the year 2023.\n\n## The website\n\n### Technologies\n\nOops... I (re)did it again.\n\nI have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself [in 2022 !](/en/articles/2022/#the-website)\n\nI will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\n\nMy \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I'm back to a solid **95/100** without any particular optimization. With some small efforts, I've reached the good old 100/100.\n\nI then did a work of modernization of the codebase. Hello CSS variables and goodbye `media queries`. In no particular order, here are some of the improvements I made:\n\n- `flexbox` and `grid` to adapt the layout to different screen sizes;\n- CSS variables for colors, font sizes and margins;\n- some `container queries`, just to try;\n- logical CSS properties (`inline` and `block` instead of `width` and `height` for example).\n\nI took this opportunity to publish [the source code](https://git.nardu.in/nardu.in/website-astro) on my git repository.\n\n**Update #1:** I've added [an RSS feed](/en/rss.xml) as I find myself using it more and more on other websites.\n\n### Analytics\n\nI removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\n\nIt's nice to see that your site is consulted, but if there is no other purpose behind it, it's an extra resource loaded for nothing by visitors. Maybe I'll reactivate the tracking when I have a use for it (other than flattering my ego).\n\nPrevious visit reports can be found at [this link.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Content\n\n- I've added a [work](/en/work/) page to list some of my projects.\n- I've also added [a page](/en/veille/) where I list some interesting things from around the web.\n\n## Additional projects\n\nI'm still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at [3-w.fr](https://3-w.fr/) (an address I am very proud of).\n\nI have to update it more regularly but I hope that the platform will help students progress!\n\n**More to come soon!**","src/content/articles/en/2023.md","489c650e66cced63",{"html":703,"metadata":704},"\u003Cp>This article will be updated when I have something new to share during the year 2023.\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oops… I (re)did it again.\u003C/p>\n\u003Cp>I have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself \u003Ca href=\"/en/articles/2022/#the-website\">in 2022 !\u003C/a>\u003C/p>\n\u003Cp>I will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\u003C/p>\n\u003Cp>My \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I’m back to a solid \u003Cstrong>95/100\u003C/strong> without any particular optimization. With some small efforts, I’ve reached the good old 100/100.\u003C/p>\n\u003Cp>I then did a work of modernization of the codebase. Hello CSS variables and goodbye \u003Ccode>media queries\u003C/code>. In no particular order, here are some of the improvements I made:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> and \u003Ccode>grid\u003C/code> to adapt the layout to different screen sizes;\u003C/li>\n\u003Cli>CSS variables for colors, font sizes and margins;\u003C/li>\n\u003Cli>some \u003Ccode>container queries\u003C/code>, just to try;\u003C/li>\n\u003Cli>logical CSS properties (\u003Ccode>inline\u003C/code> and \u003Ccode>block\u003C/code> instead of \u003Ccode>width\u003C/code> and \u003Ccode>height\u003C/code> for example).\u003C/li>\n\u003C/ul>\n\u003Cp>I took this opportunity to publish \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">the source code\u003C/a> on my git repository.\u003C/p>\n\u003Cp>\u003Cstrong>Update #1:\u003C/strong> I’ve added \u003Ca href=\"/en/rss.xml\">an RSS feed\u003C/a> as I find myself using it more and more on other websites.\u003C/p>\n\u003Ch3 id=\"analytics\">Analytics\u003C/h3>\n\u003Cp>I removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\u003C/p>\n\u003Cp>It’s nice to see that your site is consulted, but if there is no other purpose behind it, it’s an extra resource loaded for nothing by visitors. Maybe I’ll reactivate the tracking when I have a use for it (other than flattering my ego).\u003C/p>\n\u003Cp>Previous visit reports can be found at \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">this link.\u003C/a>\u003C/p>\n\u003Ch3 id=\"content\">Content\u003C/h3>\n\u003Cul>\n\u003Cli>I’ve added a \u003Ca href=\"/en/work/\">work\u003C/a> page to list some of my projects.\u003C/li>\n\u003Cli>I’ve also added \u003Ca href=\"/en/veille/\">a page\u003C/a> where I list some interesting things from around the web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"additional-projects\">Additional projects\u003C/h2>\n\u003Cp>I’m still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (an address I am very proud of).\u003C/p>\n\u003Cp>I have to update it more regularly but I hope that the platform will help students progress!\u003C/p>\n\u003Cp>\u003Cstrong>More to come soon!\u003C/strong>\u003C/p>",{"headings":705,"imagePaths":719,"frontmatter":720},[706,707,710,713,716],{"depth":30,"slug":682,"text":683},{"depth":88,"slug":708,"text":709},"technologies","Technologies",{"depth":88,"slug":711,"text":712},"analytics","Analytics",{"depth":88,"slug":714,"text":715},"content","Content",{"depth":30,"slug":717,"text":718},"additional-projects","Additional projects",[],{"title":694,"subtitle":695,"lang":196,"slug":691,"excerpt":721,"tags":722,"type":655,"createdAt":723,"updatedAt":724},"New changes.",[663],"2023-02-03T17:41:00.000Z","2023-05-17T17:41:00.000Z","en-2025",{"id":725,"data":727,"body":732,"filePath":733,"digest":734,"rendered":735},{"title":728,"subtitle":729,"lang":196,"tags":730,"type":655,"slug":725,"createdAt":731},"Nico v3.0","This website no longer has an english version..",[663],["Date","2025-01-02T17:41:00.000Z"],"## So long \u003Ccode style=\"font-size: var(--size-2)\">lang=\"en\"\u003C/code>\n\nI have maintained an english version of my website for some years but **no more…** The effort needed to make a fully multilingual website with Astro is just too much work for my small personal website.\n\n**All previous content will remain online** ([articles](/articles/#en-articles) and [snippets](/fragments/#en-fragments)) but the interface and internal pages will only be in french.\n\nI do not have any metrics on who visits my website but I don't think it will be missed. If you do miss it, don't hesitate to send me an email!","src/content/articles/en/2025.md","669bebc4518d51e1",{"html":736,"metadata":737},"\u003Ch2 id=\"so-long-langen\">So long \u003Ccode style=\"font-size: var(--size-2)\">lang=“en”\u003C/code>\u003C/h2>\n\u003Cp>I have maintained an english version of my website for some years but \u003Cstrong>no more…\u003C/strong> The effort needed to make a fully multilingual website with Astro is just too much work for my small personal website.\u003C/p>\n\u003Cp>\u003Cstrong>All previous content will remain online\u003C/strong> (\u003Ca href=\"/articles/#en-articles\">articles\u003C/a> and \u003Ca href=\"/fragments/#en-fragments\">snippets\u003C/a>) but the interface and internal pages will only be in french.\u003C/p>\n\u003Cp>I do not have any metrics on who visits my website but I don’t think it will be missed. If you do miss it, don’t hesitate to send me an email!\u003C/p>",{"headings":738,"imagePaths":742,"frontmatter":743},[739],{"depth":30,"slug":740,"text":741},"so-long-langen","So long lang=“en”",[],{"title":728,"subtitle":729,"lang":196,"slug":725,"excerpt":744,"tags":745,"type":655,"createdAt":746},"This website no longer has an english version.",[663],"2025-01-02T17:41:00.000Z","en-after-effects-expressions",{"id":747,"data":749,"body":755,"filePath":756,"digest":757,"deferredRender":202},{"title":750,"subtitle":751,"lang":196,"tags":752,"type":655,"slug":747,"createdAt":754,"code":202},"After Effects Expressions","Animation on steroïds.",[753],"Design",["Date","2019-04-24T09:00:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## An ever lasting battle\n\nThere is very little documentation and the existing one is hard to find or very old. Very often I just don't have the time to dive into expression learning while animating even though it could help the entire project on the long term.\nSo the last time I had to do a complex animation, **I took the damn time!**\n\n## The begining of the end (of keyframes).\n\nEveryone uses expressions whether they know it or not. Most of the time it's a rather transparent process for the animator. For example: when parenting a property to another one, After Effects creates an expression for us.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/basic_expression_d81b12f1ac.jpeg'\n\twidth='728'\n\theight='80'\n\talt='Parenting the position of the form to a null creates an expression.'\n/>\n\nOver the last updates, Adobe has made an effort to make expressions more accessible to everyone. For example, the expression box is now resembling a code editor thanks to code-coloring and auto-completion features. After Effects expression feel like JavaScript with custom functions.\n\nThose custom functions can be called through a menu once you enabled the expressions on a property. It offers organized shortcut and proper syntax to all of AE native functions and a bunch of JavaScript standard ones.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/shortcut_39cc19d383.jpeg'\n\twidth='728'\n\theight='322'\n\talt='Alt + Click the stopwatch to access the shortcuts.'\n/>\n\n## So I need to learn javascript to do motion design now?\n\n### Why bother?\n\nI know that most animators don't have any kind of development background. However, if Adobe thought it best to let us use expressions, I think we ought to, at least, try.\n\n> A lot of incredible professionals like [Mt Mograph](https://www.mtmograph.com/) and [Video Copilot](https://videocopilot.net/) use expressions.\n\nLike every optimization process, building an expressions knowledge takes time. However, like all optimization process, you will benefit from it afterwards.\n\n### Where to learn\n\nI've gathered a list of my favourite learning grounds. Plenty more exist, **go get'em!**\n\n- [Adobe official expression starter guide (FR)](https://helpx.adobe.com/fr/after-effects/using/expression-language-reference.html)\n- [Adobe official expression basic (EN)](https://helpx.adobe.com/after-effects/using/expression-basics.html)\n- [Adobe forums for expressions](https://community.adobe.com/t5/after-effects/bd-p/after-effects?page=1&sort=latest_replies&filter=all&topics=label-expressions)\n- [Creative Cow expressions forums](https://creativecow.net/forums/forum/adobe-after-effects-expressions/)\n- [Youtube channel about expressions](https://www.youtube.com/playlist?list=PLvr5U5ZSt6IzHyvSL9fo0M9NRPsTvra31)\n- [All expressions explained](http://aescript.jecool.net/reference/)\n- [All expressions explained again](http://expressions.aenhancers.com/index.html)\n- [Nice examples of basic expressions](https://www.schoolofmotion.com/tutorials/amazing-expressions-in-after-effects)\n\n## Real world example\n\n### Number counter\n\nLet's say you need to animate a rather simple counter from 0% to 100%.\n\n- Start by creating a text layer. Define your typographic choices, colours, etc.\n- On the effect menu add expression options > slider control\n- Alt + Click the Source text property\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/alt-counter.mp4' type='video/mp4' />\n\u003C/video>\n\n- Parent the source text to the slider control through the pickwhip.\n\n\u003Cvideo width='462' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/pickwhip.mp4' type='video/mp4' />\n\u003C/video>\n\nYou should get something like this in the expressions panel:\n\n```javascript\neffect(\"Slider Control\")(\"Slider\")​\n```\n\n- Set two keyframes on the slider from 0 to 100. The text should update accordingly.\n- By default, After Effects does not round numbers. In the expression panel, wrap your expression with the `Math.round()` function.\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/round.mp4' type='video/mp4' />\n\u003C/video>\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\"))​\n```\n\nGreat! We have a working counter. But we wanted a percentage counter. We could add a % glyph in another text layer but let's not.\n\nStill in the expression panel, we're going to add a string containing the % glyph, using basic JavaScript concatenation: `+ '%'`\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\")) + '%'​\n```\n\n\u003Cvideo width='538' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/percent.mp4' type='video/mp4' />\n\u003C/video>\n\n**And there we go!** A fully functioning and customizable counter using a slider controller and expressions.","src/content/articles/en/after-effects-expressions.mdx","3b6f88fbf35af1a4","en-faq",{"id":758,"data":760,"body":764,"filePath":765,"digest":766,"rendered":767},{"title":761,"subtitle":195,"lang":196,"tags":762,"type":655,"slug":758,"createdAt":763,"draft":202},"Accessibility and sobriety",[663],["Date","2022-06-22T15:34:45.000Z"],"[Go back to available articles](/en/articles)","src/content/articles/en/faq.md","82d516449896f6ca",{"html":768,"metadata":769},"\u003Cp>\u003Ca href=\"/en/articles\">Go back to available articles\u003C/a>\u003C/p>",{"headings":770,"imagePaths":771,"frontmatter":772},[],[],{"title":761,"subtitle":195,"lang":196,"slug":758,"draft":202,"excerpt":773,"tags":774,"type":655,"createdAt":272},"Why, how et and especially what.",[663],"en-gratuiste",{"id":775,"data":777,"body":764,"filePath":781,"digest":782,"rendered":783},{"title":778,"subtitle":195,"lang":196,"tags":779,"type":655,"slug":775,"createdAt":780,"draft":202},"Gratuiste",[753,663],["Date","2017-05-27T07:47:36.000Z"],"src/content/articles/en/gratuiste.md","ebec75d19f0ff741",{"html":768,"metadata":784},{"headings":785,"imagePaths":786,"frontmatter":787},[],[],{"title":778,"subtitle":195,"lang":196,"slug":775,"draft":202,"excerpt":195,"tags":788,"type":655,"createdAt":789},[753,663],"2017-05-27T07:47:36.000Z","en-sci-hub-unblock",{"id":790,"data":792,"body":800,"filePath":801,"digest":802,"deferredRender":202},{"title":793,"subtitle":794,"lang":196,"tags":795,"type":655,"slug":790,"createdAt":798,"updatedAt":799},"Access blocked Sci-hub","The science of sharing.",[796,797],"Internet","Science",["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nThe current sci-hub address is: \u003Ca href=\"https://www.sci-hub.st/\" rel=\"noreferer noopener\">sci-hub.st\u003C/a>\n\n## What is this about?\n\nNot being a researcher myself, here’s an [extremely well done explanatory video](https://youtu.be/rcgxY__YXEc) on the subject of scientific publication (french audio with auto subtitle).\n\n> “This is outrageous!”​\n\nI noticed that my ISP was indeed blocking access. I have not yet been able to check for the other suppliers, but I imagine that they have all complied with the court decision.\nThe restriction in place is quite basic. This is a “DNS” block. A DNS is a server that is used to link a domain name: **www.sci-hub.tw** to an IP address: **186.2.163.90**\nIt is, in a way, the Internet phone book. Without the address, it is impossible to contact the domain. What ISPs have certainly done: block requests to the [sci-hub.se.](http://sci-hub.se/) domain name. As a result, no IP address is returned and the site is not accessible.\n\n## How to bypass this?\n\n- Either by using a VPN\n- Either by modifying the DNS servers of your computers/Internet box\n\nI would recommend the second solution because it allows you to protect yourself against future blockages/filtering/censorship from your ISP and does not require any financial compensation.\nI will focus on change from a computer because it will be effective wherever you are and not only from your home.\n\n### MacOs\n\nGo to:\n\n1. System Preferences\n1. Network\n1. (wi-fi and/or ethernet)\n1. Advanced\n1. DNS\n\nFrom there, you can add DNS servers by clicking the + icon. Click ok and apply the new settings. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS network and DNS settings'\n/>\n\n### Windows (10)\n\nGo to:\n\n1. System Settings\n1. Network & Internet\n1. Change adapter options\n1. Right click your adapter then “properties”\n1. Select “internet protocol version 4” (and/or 6)\n1. Properties\n1. Use the following DNS server addresses\n\nFrom there, you can add DNS servers. Click save. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Windows system settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows network settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows network connections settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows network adapter settings'\n/>\n\n## Which DNS?\n\nThere are many DNS servers available. The best known are Google, Cloudflare and OpenDNS. If you really want to use Google’s, I’ll let you look up their address. Here are my recommendations in order of preference.\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMy favorite since it is a [french association](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net)\n\nQuand9 is a non-profit foundation offering free public DNS servers. Their classic servers offer filtering of identified malicious domains. They do not collect data and are \u003Cabbr title=\"General Data Protection Regulation\">GDPR\u003C/abbr>-compliant.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## That's it.\n\nBy changing these settings, you are free from your ISPs and their content filtering rules.\n\nFor the moment, these restrictions are almost symbolic because if Sci-hub were to change its url, the block would no longer work. But the publishers’ victory in court shows that they have not had their last word. We are therefore not immune to a wider and stronger block in the future.\n\nIf you want to learn more about the struggle of the people who fight to ensure that research is not a paid commodity, I recommend [this documentary](https://youtu.be/y_CQATGOX2w) on Aaron Shwartz. Or [this article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) about the founder of Sci-hub.\n\nIn the meantime, good readings to all of you. We stand with you!","src/content/articles/en/sci-hub-blocage.mdx","af48e8c0c3b463bf","en-the-day-I-jamd",{"id":803,"data":805,"body":813,"filePath":814,"digest":815,"deferredRender":202},{"title":806,"subtitle":807,"lang":196,"tags":808,"type":655,"slug":803,"createdAt":811,"updatedAt":812},"The day I Jam’d","A story of unusual tools and fun gambles.",[809,810],"Dev","Jamstack",["Date","2020-10-08T09:00:00.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## The not so easy choice\n\nWhen I was still using Wordpress for my personal website, I thought it would be nice to try [OpenLiteSpeed](https://openlitespeed.org) webserver. Being a designer, I always like to have a graphical interface and I heard OLS had very nice caching and overall performances.\n\n## FIGHT!\n\nA few years later, I learned about Jamstack and its incredible potential. Not being impulsive at all, I chose to entirely remake my website with tools like [11ty](https://www.11ty.dev/) and [Strapi](https://strapi.io/).\n\nI remember Strapi still being in alpha/beta and colleagues telling me it was a risky gamble, especially since I was pretty new to the node.js world.\n\n> Open source and french? Sign me up!\n\nSo I started recreating my website identically with 11ty and Strapi. Same hosting on a Digital Ocean droplet, same webserver, same content. I had done a fair amout of performance optimizations on my wordpress install so I was eager to compare the results with the new static version.\n\nBoy did they exceed my expectations! With almost no optimization on the static side, I got the following results.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 53/100 on Wordpress.'\n/>\n\nDespite a lot of efforts I could not do better. I’m no expert in caching, do not use CDN and relied on plugins to achieve a lot of stuff (php not being my strongest skill 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 97/100 on jamstack.'\n/>\n\nAlmost **zero** special configuration (I was too anxious to test) and I reached an awesome score. I know lighthouse scores are not everything but hey, **53 vs 97**… I’ll take it!\n\n## Now kiss 🥰\n\nBoth of these approaches have their benefits and drawbacks. As a freelance, my clients often prefer or ask for Wordpress because of its reputation. I always present a Jamstack alternative when possible but it’s still scary to most compared to Wordpress. I feel however that it’s going to be easier to use Jamstack with time.\n\n## I did it again…\n\nHere we are now, a quarantine and a few months later and this website is running with… [Nuxt.js](https://nuxtjs.org/). I know, I’m sorry, I couldn’t resist the latest [nuxt content](https://content.nuxtjs.org/) functionnality.\n\nSo I re-did everything again… and let me just say: **wow**, what an experience!\nI **love** developing with Nuxt. Using nuxt content allowed me to focus on design and, well, content.\nNo more Apollo client and graphQL query, only markdown and a few promises.\n\nDon’t get me wrong, I really like working with Strapi and its graphQL capabilities but for the purpose of this website, nuxt content does it (extremely well).\n\nI’m still using Strapi as a way to upload, store and manage images, videos, gifs, etc. It might be too much for this use case but I like to know that I can still go back to it if I want to! Also, I spent quite a bit of time setting it up with OpenLiteSpeed and I’m still too attached to this accomplishment to let it go.\n\n## In the end\n\nWordpress, Jamstack, vanilla everything… Does it really matter? For me, the dev experience was far more enjoyable working with 11ty, nuxt.js and strapi than with Wordpress.\n\nOn the performance and accessibility side, it also seems to be the better/smarter choice. It might not be everytime! ¯\\\\\\_(ツ)\\_/¯\n\nCan’t wait to learn [astro](https://astro.build/) and start from scratch again!","src/content/articles/en/the-day-I-jamd.mdx","60b77e216e02f618","en-video-compression",{"id":816,"data":818,"body":824,"filePath":825,"digest":826,"deferredRender":202},{"title":819,"subtitle":820,"lang":196,"tags":821,"type":655,"slug":816,"createdAt":822,"updatedAt":823},"Video compression","Encode like you mean it.",[753],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Let's play.\n\nVideos are everywhere. **EVERYWHERE!** But videos can and will be huge when 4k becomes an internet standard. Currently, 1920x1080 is king and we usually have no problem hosting or playing this resolution.\n\n## Because we can doesn't mean we should.\n\nRight now, the (good) trend of web performance is on the rise. Everyone wants a blazing fast loading website, which might not be possible if we send requests to 100mb (or even more) videos.\n\nWith a good connection, users will not see the difference. But if we go down that path, nor will they with a 300mb one. So the goal is to make every asset as small as possible. It's already the case with images. But it's simpler and faster than video encoding.\n\n## Small size, best quality.\n\nLet's say we exported​ a 1920x1080 video from Premiere Pro with these basic settings:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-premiere-1.jpeg'\n\twidth='673'\n\theight='800'\n/>\n\nIt's gorgeous, it's Full HD, it's 1:30 minute of excellent editing but it's 50mb… What a shame.\n\n> We can already bring down the size from Premiere or Media Encoder by selecting CBR instead of VBR and using a low bitrate (like 2 or 3).\n\nLet's now use [Handbrake!](https://handbrake.fr/) It's free, open source and multi platform. You can also read this great article from [Ueno](https://loremipsum.ueno.co/dear-ueno-how-do-you-compress-videos-6657ebd9dd28?gi=930afecec398) on video encoding.\n\n**Please please PLEASE. Never export videos from within After Effects.**\n\n## Handbrake\n\n### Summary screen\n\nWhile it's not as nice as Premiere Pro, it has way more exporting capabilities. Follow these steps to use good standard settings:\n\n1. Open your source video\n1. Select a preset corresponding to your future usage like Fast 1080p30\n1. Check Web Optimized\n1. Keep MPEG-4 as the format\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-1.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Video screen\n\n1. Keep H.264 (x264) or use H.264 nvidia nvenc if you can (crazy fast encoding by nvidia)\n1. Choose Constant Quality and try a value between 20 and 30​ (higher = smaller size but lower quality)\n1. Choose Peak Framerate. If you don't know the framerate, keep the default setting\n1. Choose the type of video you are encoding (film, animation…)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-2.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Audio screen\n\nIf you don't have audio, be sure to set the audio channel to none.\nIf you have an audio channel, these settings are great and will not influence the size much​:\n\n1. Codec AAC\n1. Samplerate 44.1\n1. Bitrate 192 to 256 (your choice)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-3.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Export!\n\nI used a RF of 25 for this example and no audio.\n\n1. My Premiere Pro video was 50,6mb\n1. My Handbrake video is 5,5mb​\n\n> What a save!\n\n​I ended up dividing the original size by 10. Which is cool.\nI tried with a RF of 30. The video was still pretty good and only 3,3mb.\n\n## Exporting for the web\n\nNow that we know how to properly compress videos, let's go further. Say we have a website with a lot of videos on the same page. We still want to load the content as fast as possible. So our videos need to be as small as possible. We won't do better than previously seen using mp4/H.264. However, we can use **webm/VP9.**\nWebm is an html video format and VP9 is its latest codec.\n\nUsing Handbrake and webm/VP9, we can achieve really great compression without losing too much quality (or none at all depending on the settings). I was able to divide by 4 the size of a video using these presets:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-4.jpg'\n\twidth='728'\n\theight='313'\n\talt=''\n/>\n\nThe only down side is that it takes some time to encode. It will depend on the video length and your computing power.\n\nI tried various settings but I read [here](https://trac.ffmpeg.org/wiki/Encode/VP9) that VP9 is supposed to be used with two-pass encoding. You then have to find the right bitrate (here 1000) for your situation.","src/content/articles/en/video-compression.mdx","5bb9f69df6c651d1","2022",{"id":827,"data":829,"body":833,"filePath":834,"digest":835,"rendered":836},{"title":660,"subtitle":830,"lang":15,"tags":831,"type":655,"slug":827,"createdAt":832},"Mise à jour 2022 de plein de trucs.",[663],["Date","2022-06-08T14:24:06.000Z"],"\u003Ca href='/articles/en-2022/' lang='en'>This content exists in english.\u003C/a>\n\nAprès deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\n\n## Les services\n\n### J’arrête le print\n\nMême si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\n\n### J’internet à fond\n\nÀ l’inverse, je passe mon temps à **faire du web.** Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer **des offres web plus précises,** dans lesquelles je me suis spécialisé.\n\nAinsi, **l’accessibilité numérique** et **l’éco-conception** deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien **mon cœur de métier.**\n\n## Le site\n\nJ’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\n\nJ’ai également fait plusieurs changements de comportements :\n\n- les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\n- j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec [cette analyse](https://twitter.com/HTeuMeuLeu/status/1370310316496728065) de [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu) ;\n- [idem pour la favicon](https://twitter.com/HTeuMeuLeu/status/1370310312214339586) ;\n- je ne déclenche les animations que si l'utilisateur n'a pas demandé au système de minimiser la quantité d'animation ou de mouvement [(référence de l'option)](https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion).\n\nJe suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> 👀).\n\n## Le Nico\n\nD’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif [Good-it!](https://www.good-it.org/) et en participant activement à son développement.\n\nJ’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.","src/content/articles/fr/2022.md","58986e0446a97cfc",{"html":837,"metadata":838},"\u003Cp>\u003Ca href=\"/articles/en-2022/\" lang=\"en\">This content exists in english.\u003C/a>\u003C/p>\n\u003Cp>Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\u003C/p>\n\u003Ch2 id=\"les-services\">Les services\u003C/h2>\n\u003Ch3 id=\"jarrête-le-print\">J’arrête le print\u003C/h3>\n\u003Cp>Même si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\u003C/p>\n\u003Ch3 id=\"jinternet-à-fond\">J’internet à fond\u003C/h3>\n\u003Cp>À l’inverse, je passe mon temps à \u003Cstrong>faire du web.\u003C/strong> Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer \u003Cstrong>des offres web plus précises,\u003C/strong> dans lesquelles je me suis spécialisé.\u003C/p>\n\u003Cp>Ainsi, \u003Cstrong>l’accessibilité numérique\u003C/strong> et \u003Cstrong>l’éco-conception\u003C/strong> deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien \u003Cstrong>mon cœur de métier.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Cp>J’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\u003C/p>\n\u003Cp>J’ai également fait plusieurs changements de comportements :\u003C/p>\n\u003Cul>\n\u003Cli>les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\u003C/li>\n\u003Cli>j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\">cette analyse\u003C/a> de \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a> ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\">idem pour la favicon\u003C/a> ;\u003C/li>\n\u003Cli>je ne déclenche les animations que si l’utilisateur n’a pas demandé au système de minimiser la quantité d’animation ou de mouvement \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion\">(référence de l’option)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>Je suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>D’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif \u003Ca href=\"https://www.good-it.org/\">Good-it!\u003C/a> et en participant activement à son développement.\u003C/p>\n\u003Cp>J’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.\u003C/p>",{"headings":839,"imagePaths":853,"frontmatter":854},[840,843,846,849,852],{"depth":30,"slug":841,"text":842},"les-services","Les services",{"depth":88,"slug":844,"text":845},"jarrête-le-print","J’arrête le print",{"depth":88,"slug":847,"text":848},"jinternet-à-fond","J’internet à fond",{"depth":30,"slug":850,"text":851},"le-site","Le site",{"depth":30,"slug":685,"text":686},[],{"title":660,"subtitle":830,"lang":15,"slug":827,"excerpt":855,"tags":856,"type":655,"createdAt":307},"Évolution des services, du site et de moi-même.",[663],{"id":175,"data":858,"body":863,"filePath":864,"digest":865,"rendered":866},{"title":694,"subtitle":859,"lang":15,"tags":860,"type":655,"slug":175,"createdAt":861,"updatedAt":862},"Mise à jour 2023.",[663],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"\u003Ca href='/articles/en-2023/' lang='en'>This content exists in english.\u003C/a>\n\nCet article sera mis à jour lorsque j'aurai des nouveautés à partager au cours de l'année 2023.\n\n## Le site\n\n### Technologies\n\nOups… je l'ai encore (re)fait.\n\nJ'ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même [en 2022 !](/articles/2022/#le-site)\n\nJe ferai certainement un ou deux articles/fragments sur Astro et les extensions que j'ai utilisées. En tout cas c'était super comme expérience. Nuxt v2 n'étant plus vraiment à jour, les performances n'étaient plus au rendez-vous. Astro a complètement corrigé ça.\n\nMon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide **95/100** sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\n\nJ'ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les `media queries`. En vrac, voici certaines améliorations que j'ai mises en place :\n\n- `flexbox` et `grid` pour adapter la mise en page aux différentes tailles d'écran ;\n- variables CSS pour les couleurs, les tailles de polices et les marges ;\n- quelques \u003Cspan lang=\"en\">`container queries`\u003C/span> pour essayer ;\n- propriétés logiques CSS (\u003Cspan lang=\"en\">`inline`\u003C/span> et \u003Cspan lang=\"en\">`block`\u003C/span> à la place de \u003Cspan lang=\"en\">`width`\u003C/span> et \u003Cspan lang=\"en\">`height`\u003C/span> par exemple).\n\nJ'en ai profité pour publier [le code source](https://git.nardu.in/nardu.in/website-astro) sur mon dépôt git.\n\n**Mise à jour #1 :** J'ai ajouté [un flux RSS](/rss.xml) car j'utilise de plus en plus le RSS sur d'autres sites web.\n\n### Suivi des visites\n\nJ’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n'était collectée et je consultais rarement les rapports.\n\nC'est sympa de voir que son site est visité, mais s'il n'y a aucun autre but derrière, c'est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j'en aurai l'utilité (autre que flatter mon égo).\n\nLes rapports de visites précédents sont consultables sur [ce lien.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Contenu\n\n- J'ai ajouté une page [références](/references/) pour lister certains de mes projets.\n- J'ai également ajouté [une page](/veille/) où je répertorie des choses intéressantes trouvées sur le web.\n\n## Projets annexes\n\nJe continue d'enseigner le développement web cette année. Afin d'étoffer mes supports de cours, j'ai mis en place un mini site de documentation disponible à l'adresse [3-w.fr](https://3-w.fr/) (adresse dont je suis très fier).\n\nIl faut que j'arrive à être plus régulier dans sa mise à jour mais j'ai bon espoir que la plateforme aide les élèves à progresser !\n\n**Plus de trucs bientôt!**","src/content/articles/fr/2023.md","ea1e7bd05f4e2599",{"html":867,"metadata":868},"\u003Cp>\u003Ca href=\"/articles/en-2023/\" lang=\"en\">This content exists in english.\u003C/a>\u003C/p>\n\u003Cp>Cet article sera mis à jour lorsque j’aurai des nouveautés à partager au cours de l’année 2023.\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oups… je l’ai encore (re)fait.\u003C/p>\n\u003Cp>J’ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même \u003Ca href=\"/articles/2022/#le-site\">en 2022 !\u003C/a>\u003C/p>\n\u003Cp>Je ferai certainement un ou deux articles/fragments sur Astro et les extensions que j’ai utilisées. En tout cas c’était super comme expérience. Nuxt v2 n’étant plus vraiment à jour, les performances n’étaient plus au rendez-vous. Astro a complètement corrigé ça.\u003C/p>\n\u003Cp>Mon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide \u003Cstrong>95/100\u003C/strong> sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\u003C/p>\n\u003Cp>J’ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les \u003Ccode>media queries\u003C/code>. En vrac, voici certaines améliorations que j’ai mises en place :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> et \u003Ccode>grid\u003C/code> pour adapter la mise en page aux différentes tailles d’écran ;\u003C/li>\n\u003Cli>variables CSS pour les couleurs, les tailles de polices et les marges ;\u003C/li>\n\u003Cli>quelques \u003Cspan lang=\"en\">\u003Ccode>container queries\u003C/code>\u003C/span> pour essayer ;\u003C/li>\n\u003Cli>propriétés logiques CSS (\u003Cspan lang=\"en\">\u003Ccode>inline\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>block\u003C/code>\u003C/span> à la place de \u003Cspan lang=\"en\">\u003Ccode>width\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>height\u003C/code>\u003C/span> par exemple).\u003C/li>\n\u003C/ul>\n\u003Cp>J’en ai profité pour publier \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">le code source\u003C/a> sur mon dépôt git.\u003C/p>\n\u003Cp>\u003Cstrong>Mise à jour #1 :\u003C/strong> J’ai ajouté \u003Ca href=\"/rss.xml\">un flux RSS\u003C/a> car j’utilise de plus en plus le RSS sur d’autres sites web.\u003C/p>\n\u003Ch3 id=\"suivi-des-visites\">Suivi des visites\u003C/h3>\n\u003Cp>J’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n’était collectée et je consultais rarement les rapports.\u003C/p>\n\u003Cp>C’est sympa de voir que son site est visité, mais s’il n’y a aucun autre but derrière, c’est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j’en aurai l’utilité (autre que flatter mon égo).\u003C/p>\n\u003Cp>Les rapports de visites précédents sont consultables sur \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">ce lien.\u003C/a>\u003C/p>\n\u003Ch3 id=\"contenu\">Contenu\u003C/h3>\n\u003Cul>\n\u003Cli>J’ai ajouté une page \u003Ca href=\"/references/\">références\u003C/a> pour lister certains de mes projets.\u003C/li>\n\u003Cli>J’ai également ajouté \u003Ca href=\"/veille/\">une page\u003C/a> où je répertorie des choses intéressantes trouvées sur le web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"projets-annexes\">Projets annexes\u003C/h2>\n\u003Cp>Je continue d’enseigner le développement web cette année. Afin d’étoffer mes supports de cours, j’ai mis en place un mini site de documentation disponible à l’adresse \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (adresse dont je suis très fier).\u003C/p>\n\u003Cp>Il faut que j’arrive à être plus régulier dans sa mise à jour mais j’ai bon espoir que la plateforme aide les élèves à progresser !\u003C/p>\n\u003Cp>\u003Cstrong>Plus de trucs bientôt!\u003C/strong>\u003C/p>",{"headings":869,"imagePaths":881,"frontmatter":882},[870,871,872,875,878],{"depth":30,"slug":850,"text":851},{"depth":88,"slug":708,"text":709},{"depth":88,"slug":873,"text":874},"suivi-des-visites","Suivi des visites",{"depth":88,"slug":876,"text":877},"contenu","Contenu",{"depth":30,"slug":879,"text":880},"projets-annexes","Projets annexes",[],{"title":694,"subtitle":859,"lang":15,"slug":175,"excerpt":883,"tags":884,"type":655,"createdAt":723,"updatedAt":724},"Suite des évolutions.",[663],"after-effects-expressions",{"id":885,"data":887,"body":891,"filePath":892,"digest":893,"rendered":894},{"title":750,"subtitle":888,"lang":15,"tags":889,"type":655,"slug":885,"createdAt":890,"draft":202},"En cours de traduction, revenez bientôt ;)",[753],["Date","2019-04-24T09:00:00.000Z"],"[Retour aux articles](/articles)","src/content/articles/fr/after-effects-expressions.md","884d725859a7bab5",{"html":895,"metadata":896},"\u003Cp>\u003Ca href=\"/articles\">Retour aux articles\u003C/a>\u003C/p>",{"headings":897,"imagePaths":898,"frontmatter":899},[],[],{"title":750,"subtitle":888,"lang":15,"draft":202,"slug":885,"excerpt":888,"tags":900,"type":655,"createdAt":901},[753],"2019-04-24T09:00:00.000Z","gratuiste",{"id":902,"data":904,"body":910,"filePath":911,"digest":912,"rendered":913},{"title":778,"subtitle":905,"lang":15,"tags":906,"type":655,"slug":902,"createdAt":908,"updatedAt":909},"Ou le travail gratuit.",[907,663],"Graphisme",["Date","2017-05-27T07:47:36.000Z"],["Date","2022-12-27T15:36:06.000Z"],"## Gratuiste, qu’est-ce que c’est ?\n\nDans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc. \nDe plus en plus, la communauté s’élève contre ces pratiques et les [dénonce.](https://twitter.com/PayeTonAffiche)\n\n> “ On n’est pas des gratuistes ! ”\n\nComprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez [cette vidéo](https://youtu.be/essNmNOrQto) qui transpose ces pratiques à des métiers “ standards ” et [celle-ci](https://youtu.be/DsstOs-K7gk) qui explique en détails le processus actuel.\n\n## T’es débile du coup ?\n\nJ’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\n\nÉtant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre. \nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\n\n## Le concept\n\nJe compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux. \nCe type de prestation porte le nom de “ **pro bono publico** ” – “ **pour le bien public** ”.\n\nCette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\n\n> Graphiste pro bono, pourquoi pas ?\n\n## Quels genres de services ?\n\nEn toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\n\n### En résumé :\n\n- maquette de site web\n- intégration front-end (en dur ou via wordpress) du site\n- gestion de la mise en ligne du site\n- newsletter (design et/ou intégration)\n- flyers\n- autres petites demandes\n\nVous pouvez avoir un aperçu de mon travail [sur ce même site.](/) J’ai déjà eu l’occasion de travailler pour :\n\n- [Cygnal](/projets/cygnal)\n- [OpenMole](https://openmole.org/)\n- [Good-it](https://good-it.org)\n\n## Dans quelles conditions ?\n\n- l’association doit être active\n- elle doit porter des valeurs que je partage\n- elle doit pouvoir me montrer ses actions\n- elle ne doit pas avoir les moyens de se payer un graphiste\n\n## C’est un peu trop beau pour être vrai ton truc…\n\nIl faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\n\nSi vous êtes intéressés, [envoyez-moi un mail !](mailto:contac@nardu.in)\n\n## Qu’est-ce que t’y gagnes toi ?\n\nSimplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.","src/content/articles/fr/gratuiste.md","80c20493583a842c",{"html":914,"metadata":915},"\u003Ch2 id=\"gratuiste-quest-ce-que-cest\">Gratuiste, qu’est-ce que c’est ?\u003C/h2>\n\u003Cp>Dans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc.\u003Cbr>\nDe plus en plus, la communauté s’élève contre ces pratiques et les \u003Ca href=\"https://twitter.com/PayeTonAffiche\">dénonce.\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“ On n’est pas des gratuistes ! ”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Comprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez \u003Ca href=\"https://youtu.be/essNmNOrQto\">cette vidéo\u003C/a> qui transpose ces pratiques à des métiers “ standards ” et \u003Ca href=\"https://youtu.be/DsstOs-K7gk\">celle-ci\u003C/a> qui explique en détails le processus actuel.\u003C/p>\n\u003Ch2 id=\"tes-débile-du-coup\">T’es débile du coup ?\u003C/h2>\n\u003Cp>J’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\u003C/p>\n\u003Cp>Étant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre.\u003Cbr>\nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\u003C/p>\n\u003Ch2 id=\"le-concept\">Le concept\u003C/h2>\n\u003Cp>Je compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux.\u003Cbr>\nCe type de prestation porte le nom de “ \u003Cstrong>pro bono publico\u003C/strong> ” – “ \u003Cstrong>pour le bien public\u003C/strong> ”.\u003C/p>\n\u003Cp>Cette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Graphiste pro bono, pourquoi pas ?\u003C/p>\n\u003C/blockquote>\n\u003Ch2 id=\"quels-genres-de-services\">Quels genres de services ?\u003C/h2>\n\u003Cp>En toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\u003C/p>\n\u003Ch3 id=\"en-résumé\">En résumé :\u003C/h3>\n\u003Cul>\n\u003Cli>maquette de site web\u003C/li>\n\u003Cli>intégration front-end (en dur ou via wordpress) du site\u003C/li>\n\u003Cli>gestion de la mise en ligne du site\u003C/li>\n\u003Cli>newsletter (design et/ou intégration)\u003C/li>\n\u003Cli>flyers\u003C/li>\n\u003Cli>autres petites demandes\u003C/li>\n\u003C/ul>\n\u003Cp>Vous pouvez avoir un aperçu de mon travail \u003Ca href=\"/\">sur ce même site.\u003C/a> J’ai déjà eu l’occasion de travailler pour :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"/projets/cygnal\">Cygnal\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://openmole.org/\">OpenMole\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://good-it.org\">Good-it\u003C/a>\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"dans-quelles-conditions\">Dans quelles conditions ?\u003C/h2>\n\u003Cul>\n\u003Cli>l’association doit être active\u003C/li>\n\u003Cli>elle doit porter des valeurs que je partage\u003C/li>\n\u003Cli>elle doit pouvoir me montrer ses actions\u003C/li>\n\u003Cli>elle ne doit pas avoir les moyens de se payer un graphiste\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"cest-un-peu-trop-beau-pour-être-vrai-ton-truc\">C’est un peu trop beau pour être vrai ton truc…\u003C/h2>\n\u003Cp>Il faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\u003C/p>\n\u003Cp>Si vous êtes intéressés, \u003Ca href=\"mailto:contac@nardu.in\">envoyez-moi un mail !\u003C/a>\u003C/p>\n\u003Ch2 id=\"quest-ce-que-ty-gagnes-toi\">Qu’est-ce que t’y gagnes toi ?\u003C/h2>\n\u003Cp>Simplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.\u003C/p>",{"headings":916,"imagePaths":941,"frontmatter":942},[917,920,923,926,929,932,935,938],{"depth":30,"slug":918,"text":919},"gratuiste-quest-ce-que-cest","Gratuiste, qu’est-ce que c’est ?",{"depth":30,"slug":921,"text":922},"tes-débile-du-coup","T’es débile du coup ?",{"depth":30,"slug":924,"text":925},"le-concept","Le concept",{"depth":30,"slug":927,"text":928},"quels-genres-de-services","Quels genres de services ?",{"depth":88,"slug":930,"text":931},"en-résumé","En résumé :",{"depth":30,"slug":933,"text":934},"dans-quelles-conditions","Dans quelles conditions ?",{"depth":30,"slug":936,"text":937},"cest-un-peu-trop-beau-pour-être-vrai-ton-truc","C’est un peu trop beau pour être vrai ton truc…",{"depth":30,"slug":939,"text":940},"quest-ce-que-ty-gagnes-toi","Qu’est-ce que t’y gagnes toi ?",[],{"title":778,"subtitle":905,"lang":15,"slug":902,"excerpt":943,"tags":944,"type":655,"createdAt":789,"updatedAt":945},"J’ai cherché un moyen de mettre mes compétences au service d’autrui et je pense avoir trouvé: je vais travailler gratuitement pour des associations.",[907,663],"2022-12-27T15:36:06.000Z","sci-hub-blocage",{"id":946,"data":948,"body":954,"filePath":955,"digest":956,"deferredRender":202},{"title":949,"subtitle":950,"lang":15,"tags":951,"type":655,"slug":946,"createdAt":952,"updatedAt":953},"Sci-hub bloqué, comment contourner","La science du partage.",[796,797],["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n\u003Ca href='/articles/en-sci-hub-unblock/' lang='en'>This content exists in english.\u003C/a>\n\nL'adresse actuelle de sci-hub est : \u003Ca href=\"https://www.sci-hub.st/\" rel=\"noreferer noopener\">sci-hub.st\u003C/a>\n\n## Résumé de la situation\n\nN’étant pas moi-même directement chercheur, je vous laisse regarder [cette vidéo](https://youtu.be/rcgxY__YXEc) explicative extrêmement bien faite sur le sujet de la publication scientifique.\n\n> “ Mais c’est scandaleux ! ”​\n\nJ’ai constaté que le blocage était actif chez SFR. Je n’ai pas encore pu vérifier pour les autres fournisseurs mais j’imagine qu’ils se sont tous conformés à la décision de justice.\nLe blocage mis en place est assez basique. Il s’agit d’un blocage “ DNS ”.\n\nUn DNS est un serveur qui sert à faire le lien entre un nom de domaine : **sci-hub.tw** et une adresse IP : **186.2.163.90**.\n\nC’est en quelque sorte l’annuaire d’internet. Sans l’adresse, impossible de contacter le domaine. Ce que les FAI ont certainement fait : bloquer les requêtes au nom de domaine [sci-hub.se.](http://sci-hub.se/) Ainsi, aucune adresse IP n’est renvoyée et le site n’est pas accessible.\n\n## Comment contourner ce blocage ?\n\n- Soit en utilisant un VPN\n- Soit en modifiant les serveurs DNS de vos ordinateurs/box internet\n\nJe recommande la deuxième solution car elle permet de se prémunir contre de futurs blocages/filtrages/censures de la part de votre FAI et ne nécessite pas de contrepartie financière.\nJe vais me focaliser sur le changement depuis un ordinateur car il sera effectif où que vous soyez.\n\n### Sur MacOs\n\nOuvrez :\n\n1. Préférences système\n1. Réseau\n1. Ethernet et/ou Wi-fi\n1. Avancé\n1. DNS\n1. Serveurs DNS\n\nDe là, vous pouvez ajouter des serveurs DNS en cliquant sur l'icône +. Cliquez sur ok et appliquez les nouveaux paramètres. Vous devrez peut-être redémarrer votre ordinateur pour que les changements fonctionnent.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS réglages réseau et DNS'\n/>\n\n### Sur Windows (ici 10)\n\nOuvrez :\n\n1. Réglages\n1. Réseau et internet\n1. Modifier les options de l'adaptateur\n1. Clic droit sur les propriétés de votre interface réseau\n1. Selectionnez « protocole Internet version 4 » (et/ou 6)\n1. Propriétés\n1. Utiliser l’adresse de serveur DNS suivante\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Réglages windows'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows réglages réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows régalges connections réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows options adaptateur réseau'\n/>\n\n## Quels serveurs DNS utiliser ?\n\nIl y a de nombreux serveurs DNS accessibles. Les plus connus étant ceux de Google, Cloudflare et OpenDNS. Si vous tenez vraiment à utiliser ceux de Google, je vous laisse chercher leur adresse. Voici mes recommandations par ordre de préférence.\n\nPlusieurs fournisseurs :\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMes favoris puisqu’il s’agit d’une [association française.](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net/fr)\n\nQuand9 est une fondation à but non lucratif proposant des serveurs DNS publics et gratuits. Leurs serveur classiques offrent un filtrage de domaines malveillants identifiés. Ils ne collectent pas de données et sont conforment au \u003Cabbr title=\"Règlement général sur la protection des données\">RGPD\u003C/abbr>.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## C'est tout.\n\nEn modifiant ces réglages, vous vous affranchissez de vos fournisseurs d’accès et de leurs règles de filtrage du contenu.\n\nPour l’instant, ces blocages sont presque symboliques car si Sci-hub venait à changer d’url, le blocage ne fonctionnerait plus. Mais la victoire des éditeurs au tribunal montre qu’ils n’ont pas dit leur dernier mot. Nous ne sommes donc pas à l’abri d’un futur blocage plus large et plus dur à contrer.\n\nSi vous voulez en apprendre plus sur le combat de ces gens qui se battent pour que la recherche ne soit pas une marchandise, je vous conseille [ce documentaire](https://youtu.be/y_CQATGOX2w) sur Aaron Shwartz. Ou plus simplement [cet article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) sur la fondatrice de Sci-hub.\n\nEn attendant, bonnes lectures à tou·te·s. On est avec vous !","src/content/articles/fr/sci-hub-blocage.mdx","f7b5a20f2a594ef2","the-day-I-jamd",{"id":957,"data":959,"body":964,"filePath":965,"digest":966,"deferredRender":202},{"title":806,"subtitle":960,"lang":15,"tags":961,"type":655,"slug":957,"createdAt":962,"updatedAt":963},"Des paris, des outils et du fun.",[809,810],["Date","2020-10-08T07:47:36.000Z"],["Date","2022-12-27T15:40:06.000Z"],"\u003Ca href='/articles/en-the-day-I-jamd/' lang='en'>This content exists in english.\u003C/a>\n\nimport AstroImage from '../../../components/AstroImage.astro'\n\n## La solution de non facilité\n\nLorsque j’utilisais encore Wordpress pour mon site web personnel, j’ai voulu essayer le serveur web \u003Ca href=\"https://openlitespeed.org\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">OpenLiteSpeed (en anglais)\u003C/a>. En tant que designer, j’ai toujours aimé avoir une interface graphique et j’avais entendu dire qu’OLS jouissait de bonnes performances en général et de cache en particulier.\n\n## Battez-vous!\n\nQuelques années plus tard, je découvrais l’univers Jamstack et son incroyable potentiel. N’étant pas du tout impulsif, j’ai choisi de refaire entièrement mon site web avec des outils comme \u003Ca href=\"https://www.11ty.dev/\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">11ty (en anglais)\u003C/a> et \u003Ca href=\"https://strapi.io/\" hreflang=\"en\">Strapi (en anglais)\u003C/a>.\n\nJe me souviens que Strapi était encore en alpha/beta et que certains collègues me disaient que c’était un pari risqué, surtout que je découvrais à peine le monde de node.js.\n\n> Open source et français ? Je dis banco !\n\nJ’ai donc commencé à recréer mon site web à l’identique avec 11ty et Strapi. Même hébergement chez Digital Ocean, même serveur web, même contenu. J’avais fait pas mal d’optimisations de performances sur mon installation wordpress, j’étais donc impatient de comparer les résultats avec la nouvelle version statique.\n\nJ’en suis resté pantois ! Quasiment sans optimisation du côté statique, j’ai obtenu les résultats ci-dessous.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 53/100 sur Wordpress.'\n/>\n\nMalgré beaucoup d’efforts, je n’ai pas pu faire mieux. Je ne suis pas un expert en cache, je n’utilise pas de CDN et je me suis appuyé sur des plugins pour réaliser beaucoup de choses (php n’étant pas ma spécialité 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 97/100 en Jamstack.'\n/>\n\nPresque **zéro** configuration spéciale (j’étais trop impatient de tester) et j’ai atteint un score impressionnant. Je sais que les scores lighthouse ne font pas tout mais **53 contre 97**… Ça me va !\n\n## Embrassez-vous 🥰\n\nCes deux approches ont leurs avantages et leurs inconvénients. En tant que freelance, mes clients préfèrent ou demandent souvent Wordpress en raison de sa réputation. Je présente toujours une alternative Jamstack lorsque c’est possible, mais cela reste effrayant la plupart du temps par rapport à Wordpress. Je pense cependant qu’il sera plus facile d’utiliser la Jamstack avec le temps.\n\n## Encore et encore…\n\nNous voici maintenant une quarantaine et quelques mois plus tard et ce site fonctionne avec… [Nuxt.js](https://fr.nuxtjs.org/). Je sais, je suis désolé, je n’ai pas pu résister à la dernière fonctionnalité [\u003Cspan lang=\"en\">nuxt content\u003C/span>](https://content.nuxtjs.org/fr) de Nuxt.\n\nDu coup j’ai tout refait… et laissez-moi vous dire : **wow**, quelle expérience !\nJ’adore développer avec Nuxt. L’utilisation de \u003Cspan lang=\"en\">nuxt content\u003C/span> m’a permis de me concentrer sur le design et, évidemment, sur le contenu.\nPlus de client Apollo ni de requête graphQL, seulement du \u003Cspan lang=\"en\">markdown\u003C/span> et quelques promesses.\n\nAttention, j’aime beaucoup travailler avec Strapi et son interface graphQL mais pour les besoins de ce site, \u003Cspan lang=\"en\">nuxt content\u003C/span> fait le \u003Cspan lang=\"en\">job\u003C/span> (extrêmement bien).\n\nJ’utilise toujours Strapi pour téléverser, stocker et gérer les images, vidéos, gifs, etc. C’est peut-être trop pour ce que j’en fait mais j’aime savoir que je peux toujours y revenir si j’ai envie ! De plus, j’ai passé pas mal de temps à le mettre en place avec \u003Cspan lang=\"en\">OpenLiteSpeed\u003C/span> et je suis encore trop attaché à cette réussite pour la laisser tomber.\n\n## Et en fait à la fin\n\nWordpress, Jamstack, fait main… Est-ce vraiment important ? Pour moi, l’expérience de développement a été bien plus agréable en travaillant avec 11ty, nuxt.js et strapi qu’avec Wordpress.\n\nDu point de vue de la performance et de l’accessibilité, il semble également que ce soit le choix le plus judicieux. Ce n’est peut-être pas le cas à chaque fois ! ¯\\\\\\_(ツ)\\_/¯\n\nJ’ai hâte d’apprendre \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> et de tout recommencer à zéro !","src/content/articles/fr/the-day-I-jamd.mdx","b474c8ff88ed0b47","video-compression",{"id":967,"data":969,"body":891,"filePath":974,"digest":975,"rendered":976},{"title":970,"subtitle":888,"lang":15,"tags":971,"type":655,"slug":967,"createdAt":972,"updatedAt":973,"draft":202},"Compression vidéo",[753],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"src/content/articles/fr/video-compression.md","2296c41874b23b3d",{"html":895,"metadata":977},{"headings":978,"imagePaths":979,"frontmatter":980},[],[],{"title":970,"subtitle":888,"lang":15,"draft":202,"slug":967,"excerpt":981,"tags":982,"type":655,"createdAt":983,"updatedAt":307},"Pas encore traduit",[753],"2021-05-05T09:00:00.000Z","faq",{"id":984,"data":986,"body":991,"filePath":992,"digest":993,"rendered":994},{"title":987,"subtitle":988,"lang":15,"tags":989,"type":655,"slug":984,"createdAt":990},"Accessibilité, sobriété et F.A.Q.","Explications sur ma vision et mon fonctionnement.",[663],["Date","2022-06-22T15:34:45.000Z"],"## l'Accessibilité\n\n### Quèsaco ?\n\nD'après [access42 :](https://access42.net)\n\n> L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\n\nAinsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que **n'importe quel visiteur** puisse l'utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais **ce n'est pas le cas !**\n\nLorsqu'un site est pensé et conçu avec l'accessibilité en tête, il ne prend **pas plus de temps** qu'un projet qui ne le fait pas. En revanche, **corriger** un site existant qui n'a pas bénéficié de cette réflexion en amont **demande beaucoup plus d'efforts.**\n\n### Pourquoi c'est important ?\n\nAprès avoir été sensibilisé à l'accessibilité et aux [situations frustrantes voire bloquantes](https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles) que rencontrent les personnes handicapées sur le web, j'ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m'a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\n\n## l'Éco-conception\n\n### Quèsaco ?\n\nD'après le collectif [\u003Cspan lang=\"en\">green it\u003C/span> :](https://www.greenit.fr)\n\n> L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\n\nIl s'agit ici pour moi de créer des produits les plus sobres possibles. C'est-à-dire de développer ou d'utiliser une fonctionnalité uniquement si elle est indispensable.\n\nPar exemple, mettre en place **un formulaire de contact** sur un site web implique plusieurs choses :\n\n- développer un formulaire\n- envoyer les données au serveur\n- vérifier les données envoyées\n- envoyer les données par mail\n- confirmer l'envoi du mail (en fournissant une copie)\n- gérer les erreurs à chaque étape\n\nUn site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d'effectuer ces opérations (ou un prestataire qui s'en charge). C'est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu'un formulaire. Dans le cas d'un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\n\n### Pourquoi c'est important ?\n\nL'éco-conception fait beaucoup de bien à la qualité globale d'un site et à l'expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\n\n## F.A.Q.\n\n### Cette démarche est-elle opportuniste ?\n\n**Non.** Il est vrai que l'accessibilité et, surtout, l'éco-conception, commencent à être « tendance ». On pourrait donc croire que j'en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c'est ma responsabilité de créer des sites web accessibles et éco-conçus **par défaut.**\n\n### Un site accessible est-il plus cher ?\n\n**Oui et non.** Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l'accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j'augmente mes tarifs suite à l'obtention de certifications relatives à mon activité.\n\n### Mon site sera-t-il 100 % accessible ?\n\n**Non,** je ne suis pas en mesure de garantir ou de certifier la conformité totale d'un site au [référentiel général d'amélioration de l'accessibilité.](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d'un site. Cependant, je peux vous accompagner avant et après l'audit afin d'anticiper puis de corriger les critères d'accessibilité requis. [Access42](https://access42.net/) et [Tanaguru](https://www.tanaguru.com/) font parties de ces entreprises spécialisées.\n\n### Pourquoi ne pas utiliser un outil automatique ?\n\nCar ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom [sous peine de procès](https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/)), ne sont pas des solutions micracles. Lisez [cet article](https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/) d'une experte en accessibilité et/ou [ce test](https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/) de différents outils pour en savoir plus.\n\n### Un site éco-conçu et accessible peut-il être beau ?\n\n**Oui, évidemment.** Je vous laisse juger par vous-même avec [cette liste](https://lowww.directory/) de sites éco-conçus. En ce qui concerne l'accessibilité, elle n'impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d'un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l'utilisation d'un produit.","src/content/articles/fr/faq.md","65e9e60bcd00806c",{"html":995,"metadata":996},"\u003Ch2 id=\"laccessibilité\">l’Accessibilité\u003C/h2>\n\u003Ch3 id=\"quèsaco\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après \u003Ca href=\"https://access42.net\">access42 :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Ainsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que \u003Cstrong>n’importe quel visiteur\u003C/strong> puisse l’utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais \u003Cstrong>ce n’est pas le cas !\u003C/strong>\u003C/p>\n\u003Cp>Lorsqu’un site est pensé et conçu avec l’accessibilité en tête, il ne prend \u003Cstrong>pas plus de temps\u003C/strong> qu’un projet qui ne le fait pas. En revanche, \u003Cstrong>corriger\u003C/strong> un site existant qui n’a pas bénéficié de cette réflexion en amont \u003Cstrong>demande beaucoup plus d’efforts.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>Après avoir été sensibilisé à l’accessibilité et aux \u003Ca href=\"https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles\">situations frustrantes voire bloquantes\u003C/a> que rencontrent les personnes handicapées sur le web, j’ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m’a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\u003C/p>\n\u003Ch2 id=\"léco-conception\">l’Éco-conception\u003C/h2>\n\u003Ch3 id=\"quèsaco-1\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après le collectif \u003Ca href=\"https://www.greenit.fr\">\u003Cspan lang=\"en\">green it\u003C/span> :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Il s’agit ici pour moi de créer des produits les plus sobres possibles. C’est-à-dire de développer ou d’utiliser une fonctionnalité uniquement si elle est indispensable.\u003C/p>\n\u003Cp>Par exemple, mettre en place \u003Cstrong>un formulaire de contact\u003C/strong> sur un site web implique plusieurs choses :\u003C/p>\n\u003Cul>\n\u003Cli>développer un formulaire\u003C/li>\n\u003Cli>envoyer les données au serveur\u003C/li>\n\u003Cli>vérifier les données envoyées\u003C/li>\n\u003Cli>envoyer les données par mail\u003C/li>\n\u003Cli>confirmer l’envoi du mail (en fournissant une copie)\u003C/li>\n\u003Cli>gérer les erreurs à chaque étape\u003C/li>\n\u003C/ul>\n\u003Cp>Un site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d’effectuer ces opérations (ou un prestataire qui s’en charge). C’est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu’un formulaire. Dans le cas d’un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important-1\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>L’éco-conception fait beaucoup de bien à la qualité globale d’un site et à l’expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\u003C/p>\n\u003Ch2 id=\"faq\">F.A.Q.\u003C/h2>\n\u003Ch3 id=\"cette-démarche-est-elle-opportuniste\">Cette démarche est-elle opportuniste ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non.\u003C/strong> Il est vrai que l’accessibilité et, surtout, l’éco-conception, commencent à être « tendance ». On pourrait donc croire que j’en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c’est ma responsabilité de créer des sites web accessibles et éco-conçus \u003Cstrong>par défaut.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"un-site-accessible-est-il-plus-cher\">Un site accessible est-il plus cher ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui et non.\u003C/strong> Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l’accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j’augmente mes tarifs suite à l’obtention de certifications relatives à mon activité.\u003C/p>\n\u003Ch3 id=\"mon-site-sera-t-il-100-accessible\">Mon site sera-t-il 100 % accessible ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non,\u003C/strong> je ne suis pas en mesure de garantir ou de certifier la conformité totale d’un site au \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité.\u003C/a> Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d’un site. Cependant, je peux vous accompagner avant et après l’audit afin d’anticiper puis de corriger les critères d’accessibilité requis. \u003Ca href=\"https://access42.net/\">Access42\u003C/a> et \u003Ca href=\"https://www.tanaguru.com/\">Tanaguru\u003C/a> font parties de ces entreprises spécialisées.\u003C/p>\n\u003Ch3 id=\"pourquoi-ne-pas-utiliser-un-outil-automatique\">Pourquoi ne pas utiliser un outil automatique ?\u003C/h3>\n\u003Cp>Car ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom \u003Ca href=\"https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/\">sous peine de procès\u003C/a>), ne sont pas des solutions micracles. Lisez \u003Ca href=\"https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/\">cet article\u003C/a> d’une experte en accessibilité et/ou \u003Ca href=\"https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/\">ce test\u003C/a> de différents outils pour en savoir plus.\u003C/p>\n\u003Ch3 id=\"un-site-éco-conçu-et-accessible-peut-il-être-beau\">Un site éco-conçu et accessible peut-il être beau ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui, évidemment.\u003C/strong> Je vous laisse juger par vous-même avec \u003Ca href=\"https://lowww.directory/\">cette liste\u003C/a> de sites éco-conçus. En ce qui concerne l’accessibilité, elle n’impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d’un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l’utilisation d’un produit.\u003C/p>",{"headings":997,"imagePaths":1031,"frontmatter":1032},[998,1001,1004,1007,1010,1012,1014,1016,1019,1022,1025,1028],{"depth":30,"slug":999,"text":1000},"laccessibilité","l’Accessibilité",{"depth":88,"slug":1002,"text":1003},"quèsaco","Quèsaco ?",{"depth":88,"slug":1005,"text":1006},"pourquoi-cest-important","Pourquoi c’est important ?",{"depth":30,"slug":1008,"text":1009},"léco-conception","l’Éco-conception",{"depth":88,"slug":1011,"text":1003},"quèsaco-1",{"depth":88,"slug":1013,"text":1006},"pourquoi-cest-important-1",{"depth":30,"slug":984,"text":1015},"F.A.Q.",{"depth":88,"slug":1017,"text":1018},"cette-démarche-est-elle-opportuniste","Cette démarche est-elle opportuniste ?",{"depth":88,"slug":1020,"text":1021},"un-site-accessible-est-il-plus-cher","Un site accessible est-il plus cher ?",{"depth":88,"slug":1023,"text":1024},"mon-site-sera-t-il-100-accessible","Mon site sera-t-il 100 % accessible ?",{"depth":88,"slug":1026,"text":1027},"pourquoi-ne-pas-utiliser-un-outil-automatique","Pourquoi ne pas utiliser un outil automatique ?",{"depth":88,"slug":1029,"text":1030},"un-site-éco-conçu-et-accessible-peut-il-être-beau","Un site éco-conçu et accessible peut-il être beau ?",[],{"title":987,"subtitle":988,"lang":15,"slug":984,"excerpt":1033,"tags":1034,"type":655,"createdAt":272},"Pourquoi, comment et surtout quèsaco.",[663]] \ No newline at end of file +[["Map",1,2,9,10,86,87,198,199,214,215,599,600],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.1.8","content-config-digest","8021b3469f132349","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"site\":\"https://www.nardu.in\",\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[\"assets.nardu.in\"],\"remotePatterns\":[{\"protocol\":\"https\"}]},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":false,\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[[null,{\"theme\":\"one-dark-pro\",\"plugins\":[{\"name\":\"Line numbers\",\"styleSettings\":{\"defaultValues\":{\"lineNumbers\":{\"foreground\":\"inherit\",\"highlightForeground\":\"inherit\"}},\"cssVarExclusions\":[],\"cssVarReplacements\":[]},\"hooks\":{}},{\"name\":\"astro-expressive-code\",\"hooks\":{}}],\"defaultProps\":{\"showLineNumbers\":false,\"overridesByLang\":{\"css,html,js,ts,vue\":{\"showLineNumbers\":true}}}}]],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"responsiveImages\":false},\"legacy\":{\"collections\":false}}","references",["Map",11,12,35,36,52,53,69,70],"natureo",{"id":11,"data":13,"filePath":24,"digest":25,"rendered":26},{"title":14,"subtitle":15,"url":16,"lang":17,"slug":11,"tags":18,"createdAt":23},"Nature en Occitanie","La sobriété au naturel.","https://www.natureo.org/","fr",[19,20,21,22],"Front-end","accessibilité","éco-conception","CMS",["Date","2023-04-19T18:02:00.000Z"],"src/content/references/natureo.md","6a7169b855b57024",{"html":27,"metadata":28},"",{"headings":29,"imagePaths":30,"frontmatter":31},[],[],{"title":14,"subtitle":15,"url":16,"lang":17,"slug":11,"excerpt":32,"tags":33,"createdAt":34},"Développement web et compagnie.",[19,20,21,22],"2023-04-19T18:02:00.000Z","3w",{"id":35,"data":37,"filePath":43,"digest":44,"rendered":45},{"title":35,"subtitle":38,"url":39,"lang":17,"slug":35,"tags":40,"createdAt":42},"J'ai fait de la doc!","https://3-w.fr",[19,41],"documentation",["Date","2022-10-19T18:02:00.000Z"],"src/content/references/3w.md","0d3d94c8af754e1b",{"html":27,"metadata":46},{"headings":47,"imagePaths":48,"frontmatter":49},[],[],{"title":35,"subtitle":38,"url":39,"lang":17,"slug":35,"excerpt":32,"tags":50,"createdAt":51},[19,41],"2022-10-19T18:02:00.000Z","parole-expression",{"id":52,"data":54,"filePath":60,"digest":61,"rendered":62},{"title":55,"subtitle":56,"url":57,"lang":17,"slug":52,"tags":58,"createdAt":59},"Parole Expression","Un nouveau site pour l'association.","https://www.paroleexpression.fr/",[19,21,22],["Date","2022-04-19T17:11:00.000Z"],"src/content/references/parole-expression.md","ec95a408f8c3e99c",{"html":27,"metadata":63},{"headings":64,"imagePaths":65,"frontmatter":66},[],[],{"title":55,"subtitle":56,"url":57,"lang":17,"slug":52,"excerpt":32,"tags":67,"createdAt":68},[19,21,22],"2022-04-19T17:11:00.000Z","rose-primaire",{"id":69,"data":71,"filePath":77,"digest":78,"rendered":79},{"title":72,"subtitle":73,"url":74,"lang":17,"slug":69,"tags":75,"createdAt":76},"Rose Primaire","Une agence comme on l'aime.","https://roseprimaire.com/",[19,20,21,22],["Date","2023-04-19T17:11:00.000Z"],"src/content/references/rose-primaire.md","a0133200cf1bee58",{"html":27,"metadata":80},{"headings":81,"imagePaths":82,"frontmatter":83},[],[],{"title":72,"subtitle":73,"url":74,"lang":17,"slug":69,"excerpt":32,"tags":84,"createdAt":85},[19,20,21,22],"2023-04-19T17:11:00.000Z","HPsections",["Map",88,89,110,111,127,128,144,145,170,171],"011-offre",{"id":88,"data":90,"body":97,"filePath":98,"digest":99,"rendered":100},{"type":91,"lang":17,"uid":92,"image":93,"order":94,"quickTitle":95,"quickImage":96,"reference":52},"section","offre","/assets/images/home/offre-1.1.svg",1.1,"Mes offres en freelance","/assets/images/home/icon-desktop.svg","## L'offre site web classique\n\nCette offre est destinée à un public souhaitant **se doter d'un site web**, sans forcément intégrer l'accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du [référentiel général d'amélioration de l'accessibilité](https://accessibilite.numerique.gouv.fr/) (\u003Cabbr>RGAA\u003C/abbr>).\n\nL'objectif principal de cette offre étant d'**établir une présence en ligne** pour le client. Que cette dernière ait un but informatif et/ou éditorial.\n\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->","src/data/HP/011-offre.md","290ecd1ed94a1087",{"html":101,"metadata":102},"\u003Ch2 id=\"loffre-site-web-classique\">L’offre site web classique\u003C/h2>\n\u003Cp>Cette offre est destinée à un public souhaitant \u003Cstrong>se doter d’un site web\u003C/strong>, sans forcément intégrer l’accessibilité au cœur du projet. Le site sera malgré tout développé au plus proche des règles du \u003Ca href=\"https://accessibilite.numerique.gouv.fr/\">référentiel général d’amélioration de l’accessibilité\u003C/a> (\u003Cabbr>RGAA\u003C/abbr>).\u003C/p>\n\u003Cp>L’objectif principal de cette offre étant d’\u003Cstrong>établir une présence en ligne\u003C/strong> pour le client. Que cette dernière ait un but informatif et/ou éditorial.\u003C/p>\n\u003C!-- \u003Ca href=\"/offres/web-classique\" class=\"btn\">L'offre classique en détails\u003C/a> -->",{"headings":103,"imagePaths":108,"frontmatter":109},[104],{"depth":105,"slug":106,"text":107},2,"loffre-site-web-classique","L’offre site web classique",[],{"type":91,"uid":92,"lang":17,"image":93,"order":94,"quickTitle":95,"quickImage":96,"reference":52},"012-offre",{"id":110,"data":112,"body":115,"filePath":116,"digest":117,"rendered":118},{"type":91,"lang":17,"image":113,"order":114,"reference":69},"/assets/images/home/offre-1.2.svg",1.2,"## L'offre accessibilité avancée\n\nCette offre s'adresse plus spécifiquement aux entités pour lesquelles **l'accessibilité du site est un critère majeur.** Qu'il s'agisse d'une création ou d'une mise en conformité après un audit d'accessibilité.\n\nLorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\n\n- [Rose Primaire](https://roseprimaire.com/) pour le conseil et l'accompagnement du projet ;\n- [Sylvain Plantier](https://jedessinebien.com/) et/ou [Benoît Etchevery](http://ben-etche.com/) pour l'illustration et la direction artistique.\n\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->","src/data/HP/012-offre.md","2a3bf3411b3c171b",{"html":119,"metadata":120},"\u003Ch2 id=\"loffre-accessibilité-avancée\">L’offre accessibilité avancée\u003C/h2>\n\u003Cp>Cette offre s’adresse plus spécifiquement aux entités pour lesquelles \u003Cstrong>l’accessibilité du site est un critère majeur.\u003C/strong> Qu’il s’agisse d’une création ou d’une mise en conformité après un audit d’accessibilité.\u003C/p>\n\u003Cp>Lorsque le projet le nécessite, je fais appel à des partenaires talentueux partageant les mêmes valeurs :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://roseprimaire.com/\">Rose Primaire\u003C/a> pour le conseil et l’accompagnement du projet ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://jedessinebien.com/\">Sylvain Plantier\u003C/a> et/ou \u003Ca href=\"http://ben-etche.com/\">Benoît Etchevery\u003C/a> pour l’illustration et la direction artistique.\u003C/li>\n\u003C/ul>\n\u003C!-- \u003Ca href=\"/offres/accessibilite\" class=\"btn\">L'offre accessibilité en détails\u003C/a> -->",{"headings":121,"imagePaths":125,"frontmatter":126},[122],{"depth":105,"slug":123,"text":124},"loffre-accessibilité-avancée","L’offre accessibilité avancée",[],{"type":91,"lang":17,"order":114,"image":113,"reference":69},"013-offre",{"id":127,"data":129,"body":132,"filePath":133,"digest":134,"rendered":135},{"type":91,"lang":17,"image":130,"order":131},"/assets/images/home/offre-1.3.svg",1.3,"## Et l'éco-conception alors ?\n\nJe ne conçois pas l'éco-conception comme une offre. C'est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l'éco-conception sans accessibilité, j'applique donc ces méthodologies quelque soit le projet !","src/data/HP/013-offre.md","03e37f364ac27cb4",{"html":136,"metadata":137},"\u003Ch2 id=\"et-léco-conception-alors\">Et l’éco-conception alors ?\u003C/h2>\n\u003Cp>Je ne conçois pas l’éco-conception comme une offre. C’est plutôt une façon de travailler, voire même une vision de mon métier. On fait rarement de l’éco-conception sans accessibilité, j’applique donc ces méthodologies quelque soit le projet !\u003C/p>",{"headings":138,"imagePaths":142,"frontmatter":143},[139],{"depth":105,"slug":140,"text":141},"et-léco-conception-alors","Et l’éco-conception alors ?",[],{"type":91,"lang":17,"order":131,"image":130},"020-methodo",{"id":144,"data":146,"body":151,"filePath":152,"digest":153,"rendered":154},{"type":91,"lang":17,"uid":147,"image":148,"order":105,"quickTitle":149,"quickImage":150},"methodology","/assets/images/home/methodo.svg","Ma méthodologie","/assets/images/home/icon-methodo.svg","## Méthodologie\n\n### Accessibilité par défaut\n\nEngagé pour un web plus accessible, je crée des **sites web** en m'appuyant sur le [référentiel général d'amélioration de l'accessibilité (RGAA)](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) ainsi que sur les bonnes pratiques [Opquast.](https://www.opquast.com/rendre-le-web-meilleur/)\n\n### Sobriété par choix\n\nJe privilégie le développement de **sites statiques** en adoptant une approche [d'éco-conception numérique.](https://eco-conception.designersethiques.org/guide/fr/) \nC'est-à-dire que le site est pensé pour n'embarquer que les fonctionnalités nécessaires à son utilisation.\n\nCette approche présente de **nombreux avantages :**\n\n- chargement rapide des pages ;\n- sécurité renforcée ;\n- coûts serveur réduits ;\n- maintenance facilitée.\n\nLorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l'interface. Cela permet de garantir que **le site reste en ligne** même si le CMS venait à ne plus fonctionner.","src/data/HP/020-methodo.md","75a09b4e0b1e926b",{"html":155,"metadata":156},"\u003Ch2 id=\"méthodologie\">Méthodologie\u003C/h2>\n\u003Ch3 id=\"accessibilité-par-défaut\">Accessibilité par défaut\u003C/h3>\n\u003Cp>Engagé pour un web plus accessible, je crée des \u003Cstrong>sites web\u003C/strong> en m’appuyant sur le \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité (RGAA)\u003C/a> ainsi que sur les bonnes pratiques \u003Ca href=\"https://www.opquast.com/rendre-le-web-meilleur/\">Opquast.\u003C/a>\u003C/p>\n\u003Ch3 id=\"sobriété-par-choix\">Sobriété par choix\u003C/h3>\n\u003Cp>Je privilégie le développement de \u003Cstrong>sites statiques\u003C/strong> en adoptant une approche \u003Ca href=\"https://eco-conception.designersethiques.org/guide/fr/\">d’éco-conception numérique.\u003C/a>\u003Cbr>\nC’est-à-dire que le site est pensé pour n’embarquer que les fonctionnalités nécessaires à son utilisation.\u003C/p>\n\u003Cp>Cette approche présente de \u003Cstrong>nombreux avantages :\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>chargement rapide des pages ;\u003C/li>\n\u003Cli>sécurité renforcée ;\u003C/li>\n\u003Cli>coûts serveur réduits ;\u003C/li>\n\u003Cli>maintenance facilitée.\u003C/li>\n\u003C/ul>\n\u003Cp>Lorsque le projet le demande, je mets en place un outil de gestion des contenus (CMS) découplé de l’interface. Cela permet de garantir que \u003Cstrong>le site reste en ligne\u003C/strong> même si le CMS venait à ne plus fonctionner.\u003C/p>",{"headings":157,"imagePaths":168,"frontmatter":169},[158,161,165],{"depth":105,"slug":159,"text":160},"méthodologie","Méthodologie",{"depth":162,"slug":163,"text":164},3,"accessibilité-par-défaut","Accessibilité par défaut",{"depth":162,"slug":166,"text":167},"sobriété-par-choix","Sobriété par choix",[],{"type":91,"uid":147,"lang":17,"image":148,"order":105,"quickTitle":149,"quickImage":150},"030-about",{"id":170,"data":172,"body":177,"filePath":178,"digest":179,"rendered":180},{"type":91,"lang":17,"uid":173,"image":174,"order":162,"quickTitle":175,"quickImage":176},"about","/assets/images/home/about.svg","Moi","/assets/images/home/icon-heart.svg","## À propos\n\n### Formations personnelles\n\nAfin de solidifier mes compétences, j'ai suivi les formations et passé les certifications suivantes :\n\n- [Opquast](https://directory.opquast.com/fr/certificat/CTQSKP/) - Maîtrise de la qualité en projet web ;\n- Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\n\n### Formations des autres\n\nDepuis plusieurs années, j'interviens dans différents campus afin de dispenser des cours de développement web.\n\n### Temps libre\n\nJ’essaie de contribuer à des [projets open source](https://git.nardu.in/explore/repos) qui me tiennent à cœur et je m'engage localement avec le collectif [good-it!](https://www.good-it.org/)\n\nAh et j’écris [des articles](/articles) aussi ! Des articles sur le design, le développement web et l’informatique.","src/data/HP/030-about.md","a7abff6d744406ce",{"html":181,"metadata":182},"\u003Ch2 id=\"à-propos\">À propos\u003C/h2>\n\u003Ch3 id=\"formations-personnelles\">Formations personnelles\u003C/h3>\n\u003Cp>Afin de solidifier mes compétences, j’ai suivi les formations et passé les certifications suivantes :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://directory.opquast.com/fr/certificat/CTQSKP/\">Opquast\u003C/a> - Maîtrise de la qualité en projet web ;\u003C/li>\n\u003Cli>Access42 - Développer et coder des sites accessibles (certificat numéro : 696fa2e0-cc67-11ec-88d2-9dabf3f992d4).\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"formations-des-autres\">Formations des autres\u003C/h3>\n\u003Cp>Depuis plusieurs années, j’interviens dans différents campus afin de dispenser des cours de développement web.\u003C/p>\n\u003Ch3 id=\"temps-libre\">Temps libre\u003C/h3>\n\u003Cp>J’essaie de contribuer à des \u003Ca href=\"https://git.nardu.in/explore/repos\">projets open source\u003C/a> qui me tiennent à cœur et je m’engage localement avec le collectif \u003Ca href=\"https://www.good-it.org/\">good-it!\u003C/a>\u003C/p>\n\u003Cp>Ah et j’écris \u003Ca href=\"/articles\">des articles\u003C/a> aussi ! Des articles sur le design, le développement web et l’informatique.\u003C/p>",{"headings":183,"imagePaths":196,"frontmatter":197},[184,187,190,193],{"depth":105,"slug":185,"text":186},"à-propos","À propos",{"depth":162,"slug":188,"text":189},"formations-personnelles","Formations personnelles",{"depth":162,"slug":191,"text":192},"formations-des-autres","Formations des autres",{"depth":162,"slug":194,"text":195},"temps-libre","Temps libre",[],{"type":91,"uid":173,"lang":17,"image":174,"order":162,"quickTitle":175,"quickImage":176},"veille",["Map",200,201],"2023",{"id":200,"data":202,"body":204,"filePath":205,"digest":206,"rendered":207},{"lang":17,"title":200,"updatedAt":203},["Date","2023-04-20T17:12:06.000Z"],"- [mmm.page](https://build.mmm.page/) - Éditeur de sites web très simples, en glisser-déposer, pour n'importe quoi.\n- [Color.io](https://www.color.io/) - Éditeur photo en ligne.\n- [Addy's toolkit](https://toolkit.addy.codes/) - Outils et ressources pour les designers et développeurs sites web.\n- [L’accessibilité n’est pas une variable d’ajustement](https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/) — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n > L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\n- [3D en CSS (english)](https://garden.bradwoods.io/notes/css/3d) – Explications et exemples des propriétés 3D en CSS.\n- [Climat : Comment ne pas déprimer ?](https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html) – Podcast.\n- [Fable (english)](https://fable.app) – Application de motion design.\n- [Rive (english)](https://rive.app) – Application de motion design.\n- [Cake Desk](https://cakedesk.app/) – Application de facturation.\n- [Ombre fluide en CSS](https://shadows.brumm.af/) – Générateur.\n- [Smol CSS](https://smolcss.dev/) – Collection de fragments CSS.\n- [Ajustement optique](https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/) (english) – Aligner visuellement plutôt que techniquement.\n- [Datawrapper](https://blog.datawrapper.de/category/datavis-dos-and-donts/) (english) – Conseils pour montrer de la donnée.\n- [Assistivlabs](https://assistivlabs.com/) (english) – Service de test des technologies d'assistance (browserstack mais pour l'accessibilité).\n- [Les caractères fantaisistes et l'accessibilité](https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/) – Explications et exemples de l'enfer que sont les caractères Unicode pour les technologies d'assistance.\n- [Créer un champ `time` sur le web](https://adamsilver.io/blog/designing-a-time-input-backed-by-research/) (english) – Article.\n- [La cascade](https://la-cascade.io) – Collection d'articles sur le CSS.\n- [Tabby](https://tabby.sh) (english) – An alternative terminal app.\n- [Newglyph](https://newglyph.com/) – Fonderie indépendante.\n- [\u003Cspan lang=\"en\">Headless UI\u003C/span>](https://headlessui.com/vue/dialog) (english) – Librairie de composants vue et react.\n- [Vie privée sexy](https://privacy.sexy) (english) – Outils de confidentialité pour windows et macos.\n- [33 concepts JavaScript](https://github.com/leonardomso/33-js-concepts) (english) – Articles.\n- [Formbricks](https://formbricks.com/) (english) – Alternative open source à google form/typeform.\n- [Animations de chargement SVG](https://github.com/n3r4zzurr0/svg-spinners) – Collection.\n- [a11yphant](https://a11yphant.com/) (english) – Challenges de code pour apprendre l'accessibilité.\n- [CSS moderne](https://moderncss.dev/) (english) – Fragments CSS.\n- [Conteneur moderne en CSS](https://twitter.com/KevinJPowell/status/1501555193799925761) (english) – Tweet de Kevin Powell ❤️","src/data/veille/2023.md","1135beec386f207f",{"html":208,"metadata":209},"\u003Cul>\n\u003Cli>\u003Ca href=\"https://build.mmm.page/\">mmm.page\u003C/a> - Éditeur de sites web très simples, en glisser-déposer, pour n’importe quoi.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.color.io/\">Color.io\u003C/a> - Éditeur photo en ligne.\u003C/li>\n\u003Cli>\u003Ca href=\"https://toolkit.addy.codes/\">Addy’s toolkit\u003C/a> - Outils et ressources pour les designers et développeurs sites web.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.sophie-drouvroy.com/blog/laccessibilite-nest-pas-une-variable-dajustement/\">L’accessibilité n’est pas une variable d’ajustement\u003C/a> — Sophie Drouvroy, intégratrice front-end, partage son quotidien en tant que personne sourde dans notre société.\n\u003Cblockquote>\n\u003Cp>L’accessibilité doit être au cœur du projet et pas une cerise sur le gâteau.\u003C/p>\n\u003C/blockquote>\n\u003C/li>\n\u003Cli>\u003Ca href=\"https://garden.bradwoods.io/notes/css/3d\">3D en CSS (english)\u003C/a> – Explications et exemples des propriétés 3D en CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lemonde.fr/podcasts/article/2022/06/21/climat-comment-ne-pas-deprimer_6131347_5463015.html\">Climat : Comment ne pas déprimer ?\u003C/a> – Podcast.\u003C/li>\n\u003Cli>\u003Ca href=\"https://fable.app\">Fable (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://rive.app\">Rive (english)\u003C/a> – Application de motion design.\u003C/li>\n\u003Cli>\u003Ca href=\"https://cakedesk.app/\">Cake Desk\u003C/a> – Application de facturation.\u003C/li>\n\u003Cli>\u003Ca href=\"https://shadows.brumm.af/\">Ombre fluide en CSS\u003C/a> – Générateur.\u003C/li>\n\u003Cli>\u003Ca href=\"https://smolcss.dev/\">Smol CSS\u003C/a> – Collection de fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://marvelapp.com/blog/optical-adjustment-logic-vs-designers/\">Ajustement optique\u003C/a> (english) – Aligner visuellement plutôt que techniquement.\u003C/li>\n\u003Cli>\u003Ca href=\"https://blog.datawrapper.de/category/datavis-dos-and-donts/\">Datawrapper\u003C/a> (english) – Conseils pour montrer de la donnée.\u003C/li>\n\u003Cli>\u003Ca href=\"https://assistivlabs.com/\">Assistivlabs\u003C/a> (english) – Service de test des technologies d’assistance (browserstack mais pour l’accessibilité).\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lalutineduweb.fr/detournement-unicode-emojis-accessibilite/\">Les caractères fantaisistes et l’accessibilité\u003C/a> – Explications et exemples de l’enfer que sont les caractères Unicode pour les technologies d’assistance.\u003C/li>\n\u003Cli>\u003Ca href=\"https://adamsilver.io/blog/designing-a-time-input-backed-by-research/\">Créer un champ \u003Ccode>time\u003C/code> sur le web\u003C/a> (english) – Article.\u003C/li>\n\u003Cli>\u003Ca href=\"https://la-cascade.io\">La cascade\u003C/a> – Collection d’articles sur le CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://tabby.sh\">Tabby\u003C/a> (english) – An alternative terminal app.\u003C/li>\n\u003Cli>\u003Ca href=\"https://newglyph.com/\">Newglyph\u003C/a> – Fonderie indépendante.\u003C/li>\n\u003Cli>\u003Ca href=\"https://headlessui.com/vue/dialog\">\u003Cspan lang=\"en\">Headless UI\u003C/span>\u003C/a> (english) – Librairie de composants vue et react.\u003C/li>\n\u003Cli>\u003Ca href=\"https://privacy.sexy\">Vie privée sexy\u003C/a> (english) – Outils de confidentialité pour windows et macos.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/leonardomso/33-js-concepts\">33 concepts JavaScript\u003C/a> (english) – Articles.\u003C/li>\n\u003Cli>\u003Ca href=\"https://formbricks.com/\">Formbricks\u003C/a> (english) – Alternative open source à google form/typeform.\u003C/li>\n\u003Cli>\u003Ca href=\"https://github.com/n3r4zzurr0/svg-spinners\">Animations de chargement SVG\u003C/a> – Collection.\u003C/li>\n\u003Cli>\u003Ca href=\"https://a11yphant.com/\">a11yphant\u003C/a> (english) – Challenges de code pour apprendre l’accessibilité.\u003C/li>\n\u003Cli>\u003Ca href=\"https://moderncss.dev/\">CSS moderne\u003C/a> (english) – Fragments CSS.\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/KevinJPowell/status/1501555193799925761\">Conteneur moderne en CSS\u003C/a> (english) – Tweet de Kevin Powell ❤️\u003C/li>\n\u003C/ul>",{"headings":210,"imagePaths":211,"frontmatter":212},[],[],{"lang":17,"title":200,"updatedAt":213},"2023-04-20T17:12:06.000Z","articles",["Map",216,217,200,251,284,285,304,305,356,357,402,403,415,416,432,433,445,446,476,477,505,506,527,528,545,546,554,555,565,566,578,579,588,589],"2022",{"id":216,"data":218,"body":224,"filePath":225,"digest":226,"rendered":227},{"title":219,"subtitle":220,"lang":17,"tags":221,"type":214,"slug":216,"createdAt":223},"Nico v2.0","Mise à jour 2022 de plein de trucs.",[222],"Freelance",["Date","2022-06-08T14:24:06.000Z"],"\u003Ca href='/articles/en-2022/' lang='en'>This content exists in english.\u003C/a>\n\nAprès deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\n\n## Les services\n\n### J’arrête le print\n\nMême si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\n\n### J’internet à fond\n\nÀ l’inverse, je passe mon temps à **faire du web.** Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer **des offres web plus précises,** dans lesquelles je me suis spécialisé.\n\nAinsi, **l’accessibilité numérique** et **l’éco-conception** deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien **mon cœur de métier.**\n\n## Le site\n\nJ’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\n\nJ’ai également fait plusieurs changements de comportements :\n\n- les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\n- j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec [cette analyse](https://twitter.com/HTeuMeuLeu/status/1370310316496728065) de [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu) ;\n- [idem pour la favicon](https://twitter.com/HTeuMeuLeu/status/1370310312214339586) ;\n- je ne déclenche les animations que si l'utilisateur n'a pas demandé au système de minimiser la quantité d'animation ou de mouvement [(référence de l'option)](https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion).\n\nJe suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> 👀).\n\n## Le Nico\n\nD’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif [Good-it!](https://www.good-it.org/) et en participant activement à son développement.\n\nJ’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.","src/content/articles/fr/2022.md","58986e0446a97cfc",{"html":228,"metadata":229},"\u003Cp>\u003Ca href=\"/articles/en-2022/\" lang=\"en\">This content exists in english.\u003C/a>\u003C/p>\n\u003Cp>Après deux ans de freelance à temps plein, j’ai pris du recul sur mon activité. J’ai surtout questionné mon positionnement et les prestations que je proposais.\u003C/p>\n\u003Ch2 id=\"les-services\">Les services\u003C/h2>\n\u003Ch3 id=\"jarrête-le-print\">J’arrête le print\u003C/h3>\n\u003Cp>Même si je suis formé à l’identité visuelle, je n’en fais que très rarement et ne pratique pas la discipline sur mon temps libre. Idem pour le graphisme « classique ». Affiches, flyers et autres prospectus ont disparu de mes devis depuis bien longtemps. Il me semble ainsi logique de ne plus proposer explicitement ces services car je considère ne plus être suffisamment compétent ni intéressé.\u003C/p>\n\u003Ch3 id=\"jinternet-à-fond\">J’internet à fond\u003C/h3>\n\u003Cp>À l’inverse, je passe mon temps à \u003Cstrong>faire du web.\u003C/strong> Énormément de développement, un peu de design et pas mal de configuration serveur. Il est de fait évident pour moi de proposer \u003Cstrong>des offres web plus précises,\u003C/strong> dans lesquelles je me suis spécialisé.\u003C/p>\n\u003Cp>Ainsi, \u003Cstrong>l’accessibilité numérique\u003C/strong> et \u003Cstrong>l’éco-conception\u003C/strong> deviennent des expertises intégrées à ma pratique. Ce ne sont plus des options sur un devis mais bien \u003Cstrong>mon cœur de métier.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Cp>J’ai retravaillé mon site, notamment la page d’accueil et son contenu, pour l’accorder avec ces décisions.\u003C/p>\n\u003Cp>J’ai également fait plusieurs changements de comportements :\u003C/p>\n\u003Cul>\n\u003Cli>les liens externes ne s’ouvrent plus dans une nouvelle fenêtre. Je suis tombé sur \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\" hreflang=\"en\">cet article (en anglais)\u003C/a> traitant de l’ouverture des liens dans une nouvelle fenêtre et je n’ai pas trouvé de bonne raison de continuer à utiliser ce comportement ;\u003C/li>\n\u003Cli>j’ai supprimé les balises open graph et twitter card car je suis entièrement d’accord avec \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\">cette analyse\u003C/a> de \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a> ;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\">idem pour la favicon\u003C/a> ;\u003C/li>\n\u003Cli>je ne déclenche les animations que si l’utilisateur n’a pas demandé au système de minimiser la quantité d’animation ou de mouvement \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-reduced-motion\">(référence de l’option)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>Je suis en train de travailler pour réduire au maximum le poids de mes pages, même si je vais certainement devoir (encore) changer d’outil (coucou \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>D’un point de vue personnel, je me suis engagé pour un numérique plus responsable en rejoignant le collectif \u003Ca href=\"https://www.good-it.org/\">Good-it!\u003C/a> et en participant activement à son développement.\u003C/p>\n\u003Cp>J’ai également commencé à donner des cours dans plusieurs écoles. J’interviens essentiellement sur des cursus numériques en enseignant le design et le développement. J’en profite ainsi pour sensibiliser, dès la formation, les futures générations à l’accessibilité et l’éco-conception.\u003C/p>",{"headings":230,"imagePaths":246,"frontmatter":247},[231,234,237,240,243],{"depth":105,"slug":232,"text":233},"les-services","Les services",{"depth":162,"slug":235,"text":236},"jarrête-le-print","J’arrête le print",{"depth":162,"slug":238,"text":239},"jinternet-à-fond","J’internet à fond",{"depth":105,"slug":241,"text":242},"le-site","Le site",{"depth":105,"slug":244,"text":245},"le-nico","Le Nico",[],{"title":219,"subtitle":220,"lang":17,"slug":216,"excerpt":248,"tags":249,"type":214,"createdAt":250},"Évolution des services, du site et de moi-même.",[222],"2022-06-08T14:24:06.000Z",{"id":200,"data":252,"body":258,"filePath":259,"digest":260,"rendered":261},{"title":253,"subtitle":254,"lang":17,"tags":255,"type":214,"slug":200,"createdAt":256,"updatedAt":257},"Nico v2.5","Mise à jour 2023.",[222],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"\u003Ca href='/articles/en-2023/' lang='en'>This content exists in english.\u003C/a>\n\nCet article sera mis à jour lorsque j'aurai des nouveautés à partager au cours de l'année 2023.\n\n## Le site\n\n### Technologies\n\nOups… je l'ai encore (re)fait.\n\nJ'ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même [en 2022 !](/articles/2022/#le-site)\n\nJe ferai certainement un ou deux articles/fragments sur Astro et les extensions que j'ai utilisées. En tout cas c'était super comme expérience. Nuxt v2 n'étant plus vraiment à jour, les performances n'étaient plus au rendez-vous. Astro a complètement corrigé ça.\n\nMon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide **95/100** sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\n\nJ'ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les `media queries`. En vrac, voici certaines améliorations que j'ai mises en place :\n\n- `flexbox` et `grid` pour adapter la mise en page aux différentes tailles d'écran ;\n- variables CSS pour les couleurs, les tailles de polices et les marges ;\n- quelques \u003Cspan lang=\"en\">`container queries`\u003C/span> pour essayer ;\n- propriétés logiques CSS (\u003Cspan lang=\"en\">`inline`\u003C/span> et \u003Cspan lang=\"en\">`block`\u003C/span> à la place de \u003Cspan lang=\"en\">`width`\u003C/span> et \u003Cspan lang=\"en\">`height`\u003C/span> par exemple).\n\nJ'en ai profité pour publier [le code source](https://git.nardu.in/nardu.in/website-astro) sur mon dépôt git.\n\n**Mise à jour #1 :** J'ai ajouté [un flux RSS](/rss.xml) car j'utilise de plus en plus le RSS sur d'autres sites web.\n\n### Suivi des visites\n\nJ’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n'était collectée et je consultais rarement les rapports.\n\nC'est sympa de voir que son site est visité, mais s'il n'y a aucun autre but derrière, c'est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j'en aurai l'utilité (autre que flatter mon égo).\n\nLes rapports de visites précédents sont consultables sur [ce lien.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Contenu\n\n- J'ai ajouté une page [références](/references/) pour lister certains de mes projets.\n- J'ai également ajouté [une page](/veille/) où je répertorie des choses intéressantes trouvées sur le web.\n\n## Projets annexes\n\nJe continue d'enseigner le développement web cette année. Afin d'étoffer mes supports de cours, j'ai mis en place un mini site de documentation disponible à l'adresse [3-w.fr](https://3-w.fr/) (adresse dont je suis très fier).\n\nIl faut que j'arrive à être plus régulier dans sa mise à jour mais j'ai bon espoir que la plateforme aide les élèves à progresser !\n\n**Plus de trucs bientôt!**","src/content/articles/fr/2023.md","ea1e7bd05f4e2599",{"html":262,"metadata":263},"\u003Cp>\u003Ca href=\"/articles/en-2023/\" lang=\"en\">This content exists in english.\u003C/a>\u003C/p>\n\u003Cp>Cet article sera mis à jour lorsque j’aurai des nouveautés à partager au cours de l’année 2023.\u003C/p>\n\u003Ch2 id=\"le-site\">Le site\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oups… je l’ai encore (re)fait.\u003C/p>\n\u003Cp>J’ai entièrement re-développé mon site avec \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, comme prédit par moi-même \u003Ca href=\"/articles/2022/#le-site\">en 2022 !\u003C/a>\u003C/p>\n\u003Cp>Je ferai certainement un ou deux articles/fragments sur Astro et les extensions que j’ai utilisées. En tout cas c’était super comme expérience. Nuxt v2 n’étant plus vraiment à jour, les performances n’étaient plus au rendez-vous. Astro a complètement corrigé ça.\u003C/p>\n\u003Cp>Mon score de performance \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\" hreflang=\"en\" lang=\"en\">PageSpeed\u003C/a> était tombé à 77/100. Grâce à Astro je retrouve un solide \u003Cstrong>95/100\u003C/strong> sans optimisation particulière. Avec quelques efforts sur le poids des ressources, je retrouve ce bon vieux 100/100.\u003C/p>\n\u003Cp>J’ai ensuite fait un travail de modernisation du code. Bonjour variables CSS et au-revoir les \u003Ccode>media queries\u003C/code>. En vrac, voici certaines améliorations que j’ai mises en place :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> et \u003Ccode>grid\u003C/code> pour adapter la mise en page aux différentes tailles d’écran ;\u003C/li>\n\u003Cli>variables CSS pour les couleurs, les tailles de polices et les marges ;\u003C/li>\n\u003Cli>quelques \u003Cspan lang=\"en\">\u003Ccode>container queries\u003C/code>\u003C/span> pour essayer ;\u003C/li>\n\u003Cli>propriétés logiques CSS (\u003Cspan lang=\"en\">\u003Ccode>inline\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>block\u003C/code>\u003C/span> à la place de \u003Cspan lang=\"en\">\u003Ccode>width\u003C/code>\u003C/span> et \u003Cspan lang=\"en\">\u003Ccode>height\u003C/code>\u003C/span> par exemple).\u003C/li>\n\u003C/ul>\n\u003Cp>J’en ai profité pour publier \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">le code source\u003C/a> sur mon dépôt git.\u003C/p>\n\u003Cp>\u003Cstrong>Mise à jour #1 :\u003C/strong> J’ai ajouté \u003Ca href=\"/rss.xml\">un flux RSS\u003C/a> car j’utilise de plus en plus le RSS sur d’autres sites web.\u003C/p>\n\u003Ch3 id=\"suivi-des-visites\">Suivi des visites\u003C/h3>\n\u003Cp>J’ai supprimé le suivi des visites. J’utilisais \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\" hreflang=\"en\">umami\u003C/a> hébergé sur mon propre serveur. Aucune donnée personnelle n’était collectée et je consultais rarement les rapports.\u003C/p>\n\u003Cp>C’est sympa de voir que son site est visité, mais s’il n’y a aucun autre but derrière, c’est une ressource supplémentaire chargée pour rien par les visiteurs. Peut-être que je réactiverai le suivi lorsque j’en aurai l’utilité (autre que flatter mon égo).\u003C/p>\n\u003Cp>Les rapports de visites précédents sont consultables sur \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">ce lien.\u003C/a>\u003C/p>\n\u003Ch3 id=\"contenu\">Contenu\u003C/h3>\n\u003Cul>\n\u003Cli>J’ai ajouté une page \u003Ca href=\"/references/\">références\u003C/a> pour lister certains de mes projets.\u003C/li>\n\u003Cli>J’ai également ajouté \u003Ca href=\"/veille/\">une page\u003C/a> où je répertorie des choses intéressantes trouvées sur le web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"projets-annexes\">Projets annexes\u003C/h2>\n\u003Cp>Je continue d’enseigner le développement web cette année. Afin d’étoffer mes supports de cours, j’ai mis en place un mini site de documentation disponible à l’adresse \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (adresse dont je suis très fier).\u003C/p>\n\u003Cp>Il faut que j’arrive à être plus régulier dans sa mise à jour mais j’ai bon espoir que la plateforme aide les élèves à progresser !\u003C/p>\n\u003Cp>\u003Cstrong>Plus de trucs bientôt!\u003C/strong>\u003C/p>",{"headings":264,"imagePaths":278,"frontmatter":279},[265,266,269,272,275],{"depth":105,"slug":241,"text":242},{"depth":162,"slug":267,"text":268},"technologies","Technologies",{"depth":162,"slug":270,"text":271},"suivi-des-visites","Suivi des visites",{"depth":162,"slug":273,"text":274},"contenu","Contenu",{"depth":105,"slug":276,"text":277},"projets-annexes","Projets annexes",[],{"title":253,"subtitle":254,"lang":17,"slug":200,"excerpt":280,"tags":281,"type":214,"createdAt":282,"updatedAt":283},"Suite des évolutions.",[222],"2023-02-03T17:41:00.000Z","2023-05-17T17:41:00.000Z","after-effects-expressions",{"id":284,"data":286,"body":293,"filePath":294,"digest":295,"rendered":296},{"title":287,"subtitle":288,"lang":17,"tags":289,"type":214,"slug":284,"createdAt":291,"draft":292},"After Effects Expressions","En cours de traduction, revenez bientôt ;)",[290],"Design",["Date","2019-04-24T09:00:00.000Z"],true,"[Retour aux articles](/articles)","src/content/articles/fr/after-effects-expressions.md","884d725859a7bab5",{"html":297,"metadata":298},"\u003Cp>\u003Ca href=\"/articles\">Retour aux articles\u003C/a>\u003C/p>",{"headings":299,"imagePaths":300,"frontmatter":301},[],[],{"title":287,"subtitle":288,"lang":17,"draft":292,"slug":284,"excerpt":288,"tags":302,"type":214,"createdAt":303},[290],"2019-04-24T09:00:00.000Z","faq",{"id":304,"data":306,"body":311,"filePath":312,"digest":313,"rendered":314},{"title":307,"subtitle":308,"lang":17,"tags":309,"type":214,"slug":304,"createdAt":310},"Accessibilité, sobriété et F.A.Q.","Explications sur ma vision et mon fonctionnement.",[222],["Date","2022-06-22T15:34:45.000Z"],"## l'Accessibilité\n\n### Quèsaco ?\n\nD'après [access42 :](https://access42.net)\n\n> L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\n\nAinsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que **n'importe quel visiteur** puisse l'utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais **ce n'est pas le cas !**\n\nLorsqu'un site est pensé et conçu avec l'accessibilité en tête, il ne prend **pas plus de temps** qu'un projet qui ne le fait pas. En revanche, **corriger** un site existant qui n'a pas bénéficié de cette réflexion en amont **demande beaucoup plus d'efforts.**\n\n### Pourquoi c'est important ?\n\nAprès avoir été sensibilisé à l'accessibilité et aux [situations frustrantes voire bloquantes](https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles) que rencontrent les personnes handicapées sur le web, j'ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m'a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\n\n## l'Éco-conception\n\n### Quèsaco ?\n\nD'après le collectif [\u003Cspan lang=\"en\">green it\u003C/span> :](https://www.greenit.fr)\n\n> L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\n\nIl s'agit ici pour moi de créer des produits les plus sobres possibles. C'est-à-dire de développer ou d'utiliser une fonctionnalité uniquement si elle est indispensable.\n\nPar exemple, mettre en place **un formulaire de contact** sur un site web implique plusieurs choses :\n\n- développer un formulaire\n- envoyer les données au serveur\n- vérifier les données envoyées\n- envoyer les données par mail\n- confirmer l'envoi du mail (en fournissant une copie)\n- gérer les erreurs à chaque étape\n\nUn site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d'effectuer ces opérations (ou un prestataire qui s'en charge). C'est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu'un formulaire. Dans le cas d'un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\n\n### Pourquoi c'est important ?\n\nL'éco-conception fait beaucoup de bien à la qualité globale d'un site et à l'expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\n\n## F.A.Q.\n\n### Cette démarche est-elle opportuniste ?\n\n**Non.** Il est vrai que l'accessibilité et, surtout, l'éco-conception, commencent à être « tendance ». On pourrait donc croire que j'en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c'est ma responsabilité de créer des sites web accessibles et éco-conçus **par défaut.**\n\n### Un site accessible est-il plus cher ?\n\n**Oui et non.** Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l'accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j'augmente mes tarifs suite à l'obtention de certifications relatives à mon activité.\n\n### Mon site sera-t-il 100 % accessible ?\n\n**Non,** je ne suis pas en mesure de garantir ou de certifier la conformité totale d'un site au [référentiel général d'amélioration de l'accessibilité.](https://www.numerique.gouv.fr/publications/rgaa-accessibilite/) Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d'un site. Cependant, je peux vous accompagner avant et après l'audit afin d'anticiper puis de corriger les critères d'accessibilité requis. [Access42](https://access42.net/) et [Tanaguru](https://www.tanaguru.com/) font parties de ces entreprises spécialisées.\n\n### Pourquoi ne pas utiliser un outil automatique ?\n\nCar ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom [sous peine de procès](https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/)), ne sont pas des solutions micracles. Lisez [cet article](https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/) d'une experte en accessibilité et/ou [ce test](https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/) de différents outils pour en savoir plus.\n\n### Un site éco-conçu et accessible peut-il être beau ?\n\n**Oui, évidemment.** Je vous laisse juger par vous-même avec [cette liste](https://lowww.directory/) de sites éco-conçus. En ce qui concerne l'accessibilité, elle n'impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d'un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l'utilisation d'un produit.","src/content/articles/fr/faq.md","65e9e60bcd00806c",{"html":315,"metadata":316},"\u003Ch2 id=\"laccessibilité\">l’Accessibilité\u003C/h2>\n\u003Ch3 id=\"quèsaco\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après \u003Ca href=\"https://access42.net\">access42 :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’accessibilité numérique est un droit fondamental. C’est la possibilité pour toutes et tous d’utiliser les outils informatiques, quelle que soit leur façon d’y accéder.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Ainsi, lorsque je \u003Cspan lang=\"en\">design\u003C/span> ou développe un site web, je fais le maximum pour que \u003Cstrong>n’importe quel visiteur\u003C/strong> puisse l’utiliser. On pourrait croire que cela rajoute une charge de travail ou un délai allongé de réalisation mais \u003Cstrong>ce n’est pas le cas !\u003C/strong>\u003C/p>\n\u003Cp>Lorsqu’un site est pensé et conçu avec l’accessibilité en tête, il ne prend \u003Cstrong>pas plus de temps\u003C/strong> qu’un projet qui ne le fait pas. En revanche, \u003Cstrong>corriger\u003C/strong> un site existant qui n’a pas bénéficié de cette réflexion en amont \u003Cstrong>demande beaucoup plus d’efforts.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>Après avoir été sensibilisé à l’accessibilité et aux \u003Ca href=\"https://www.france24.com/fr/info-en-continu/20220520-internet-parcours-d-obstacles-pour-les-aveugles\">situations frustrantes voire bloquantes\u003C/a> que rencontrent les personnes handicapées sur le web, j’ai décidé de tout faire pour me former et travailler en connaissance de cause. Il m’a semblé que proposer des sites utilisables par le plus grand nombre devait être la norme.\u003C/p>\n\u003Ch2 id=\"léco-conception\">l’Éco-conception\u003C/h2>\n\u003Ch3 id=\"quèsaco-1\">Quèsaco ?\u003C/h3>\n\u003Cp>D’après le collectif \u003Ca href=\"https://www.greenit.fr\">\u003Cspan lang=\"en\">green it\u003C/span> :\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>L’éco-conception de service numérique consiste à améliorer l’efficience des applications dès leur conception pour réduire les impacts environnementaux et économiques associés tout en améliorant significativement l’expérience utilisateur.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Il s’agit ici pour moi de créer des produits les plus sobres possibles. C’est-à-dire de développer ou d’utiliser une fonctionnalité uniquement si elle est indispensable.\u003C/p>\n\u003Cp>Par exemple, mettre en place \u003Cstrong>un formulaire de contact\u003C/strong> sur un site web implique plusieurs choses :\u003C/p>\n\u003Cul>\n\u003Cli>développer un formulaire\u003C/li>\n\u003Cli>envoyer les données au serveur\u003C/li>\n\u003Cli>vérifier les données envoyées\u003C/li>\n\u003Cli>envoyer les données par mail\u003C/li>\n\u003Cli>confirmer l’envoi du mail (en fournissant une copie)\u003C/li>\n\u003Cli>gérer les erreurs à chaque étape\u003C/li>\n\u003C/ul>\n\u003Cp>Un site statique seul ne peut pas faire tout ça. Il faut obligatoirement un serveur et un langage capable d’effectuer ces opérations (ou un prestataire qui s’en charge). C’est pourquoi je recommande une adresse email et un numéro de téléphone comme moyen de contact plutôt qu’un formulaire. Dans le cas d’un questionnaire ou autre situation particulière, un formulaire est tout à fait envisageable.\u003C/p>\n\u003Ch3 id=\"pourquoi-cest-important-1\">Pourquoi c’est important ?\u003C/h3>\n\u003Cp>L’éco-conception fait beaucoup de bien à la qualité globale d’un site et à l’expérience des visiteurs. En effet, étant réalisé uniquement avec ce dont il a besoin, il aura tendance à être plus léger, mieux optimisé, plus rapide, etc.\u003C/p>\n\u003Ch2 id=\"faq\">F.A.Q.\u003C/h2>\n\u003Ch3 id=\"cette-démarche-est-elle-opportuniste\">Cette démarche est-elle opportuniste ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non.\u003C/strong> Il est vrai que l’accessibilité et, surtout, l’éco-conception, commencent à être « tendance ». On pourrait donc croire que j’en profite pour faire du \u003Cspan lang=\"en\">business\u003C/span>. Je considère cependant que c’est ma responsabilité de créer des sites web accessibles et éco-conçus \u003Cstrong>par défaut.\u003C/strong>\u003C/p>\n\u003Ch3 id=\"un-site-accessible-est-il-plus-cher\">Un site accessible est-il plus cher ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui et non.\u003C/strong> Oui car si on demande un audit, il faudra payer la société qui le réalise. De mon côté, je ne fais pas payer l’accessibilité plus cher sur mes factures étant donné que je travaille ainsi par défaut.\nEn revanche, j’augmente mes tarifs suite à l’obtention de certifications relatives à mon activité.\u003C/p>\n\u003Ch3 id=\"mon-site-sera-t-il-100-accessible\">Mon site sera-t-il 100 % accessible ?\u003C/h3>\n\u003Cp>\u003Cstrong>Non,\u003C/strong> je ne suis pas en mesure de garantir ou de certifier la conformité totale d’un site au \u003Ca href=\"https://www.numerique.gouv.fr/publications/rgaa-accessibilite/\">référentiel général d’amélioration de l’accessibilité.\u003C/a> Seul un audit exécuté par une entreprise apte à le réaliser peut certifier la conformité d’un site. Cependant, je peux vous accompagner avant et après l’audit afin d’anticiper puis de corriger les critères d’accessibilité requis. \u003Ca href=\"https://access42.net/\">Access42\u003C/a> et \u003Ca href=\"https://www.tanaguru.com/\">Tanaguru\u003C/a> font parties de ces entreprises spécialisées.\u003C/p>\n\u003Ch3 id=\"pourquoi-ne-pas-utiliser-un-outil-automatique\">Pourquoi ne pas utiliser un outil automatique ?\u003C/h3>\n\u003Cp>Car ces outils dits de “surcouche” (dont il ne faut pas prononcer le nom \u003Ca href=\"https://www.lalutineduweb.fr/aide-frais-avocate-proces-contre-faciliti/\">sous peine de procès\u003C/a>), ne sont pas des solutions micracles. Lisez \u003Ca href=\"https://www.lalutineduweb.fr/surcouche-accessibilite-web-mensonges-boules-gommes/\">cet article\u003C/a> d’une experte en accessibilité et/ou \u003Ca href=\"https://blog.empreintedigitale.fr/2021/06/01/outils-de-surcouche-daccessibilite-que-valent-ils-vraiment/\">ce test\u003C/a> de différents outils pour en savoir plus.\u003C/p>\n\u003Ch3 id=\"un-site-éco-conçu-et-accessible-peut-il-être-beau\">Un site éco-conçu et accessible peut-il être beau ?\u003C/h3>\n\u003Cp>\u003Cstrong>Oui, évidemment.\u003C/strong> Je vous laisse juger par vous-même avec \u003Ca href=\"https://lowww.directory/\">cette liste\u003C/a> de sites éco-conçus. En ce qui concerne l’accessibilité, elle n’impacte que très peu le \u003Cspan lang=\"en\">design\u003C/span> global d’un site. Même si plusieurs critères visuels existent (contrastes, taille du texte, etc.), elle se concentre essentiellement sur le fonctionnement et l’utilisation d’un produit.\u003C/p>",{"headings":317,"imagePaths":351,"frontmatter":352},[318,321,324,327,330,332,334,336,339,342,345,348],{"depth":105,"slug":319,"text":320},"laccessibilité","l’Accessibilité",{"depth":162,"slug":322,"text":323},"quèsaco","Quèsaco ?",{"depth":162,"slug":325,"text":326},"pourquoi-cest-important","Pourquoi c’est important ?",{"depth":105,"slug":328,"text":329},"léco-conception","l’Éco-conception",{"depth":162,"slug":331,"text":323},"quèsaco-1",{"depth":162,"slug":333,"text":326},"pourquoi-cest-important-1",{"depth":105,"slug":304,"text":335},"F.A.Q.",{"depth":162,"slug":337,"text":338},"cette-démarche-est-elle-opportuniste","Cette démarche est-elle opportuniste ?",{"depth":162,"slug":340,"text":341},"un-site-accessible-est-il-plus-cher","Un site accessible est-il plus cher ?",{"depth":162,"slug":343,"text":344},"mon-site-sera-t-il-100-accessible","Mon site sera-t-il 100 % accessible ?",{"depth":162,"slug":346,"text":347},"pourquoi-ne-pas-utiliser-un-outil-automatique","Pourquoi ne pas utiliser un outil automatique ?",{"depth":162,"slug":349,"text":350},"un-site-éco-conçu-et-accessible-peut-il-être-beau","Un site éco-conçu et accessible peut-il être beau ?",[],{"title":307,"subtitle":308,"lang":17,"slug":304,"excerpt":353,"tags":354,"type":214,"createdAt":355},"Pourquoi, comment et surtout quèsaco.",[222],"2022-06-22T15:34:45.000Z","gratuiste",{"id":356,"data":358,"body":365,"filePath":366,"digest":367,"rendered":368},{"title":359,"subtitle":360,"lang":17,"tags":361,"type":214,"slug":356,"createdAt":363,"updatedAt":364},"Gratuiste","Ou le travail gratuit.",[362,222],"Graphisme",["Date","2017-05-27T07:47:36.000Z"],["Date","2022-12-27T15:36:06.000Z"],"## Gratuiste, qu’est-ce que c’est ?\n\nDans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc. \nDe plus en plus, la communauté s’élève contre ces pratiques et les [dénonce.](https://twitter.com/PayeTonAffiche)\n\n> “ On n’est pas des gratuistes ! ”\n\nComprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez [cette vidéo](https://youtu.be/essNmNOrQto) qui transpose ces pratiques à des métiers “ standards ” et [celle-ci](https://youtu.be/DsstOs-K7gk) qui explique en détails le processus actuel.\n\n## T’es débile du coup ?\n\nJ’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\n\nÉtant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre. \nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\n\n## Le concept\n\nJe compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux. \nCe type de prestation porte le nom de “ **pro bono publico** ” – “ **pour le bien public** ”.\n\nCette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\n\n> Graphiste pro bono, pourquoi pas ?\n\n## Quels genres de services ?\n\nEn toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\n\n### En résumé :\n\n- maquette de site web\n- intégration front-end (en dur ou via wordpress) du site\n- gestion de la mise en ligne du site\n- newsletter (design et/ou intégration)\n- flyers\n- autres petites demandes\n\nVous pouvez avoir un aperçu de mon travail [sur ce même site.](/) J’ai déjà eu l’occasion de travailler pour :\n\n- [Cygnal](/projets/cygnal)\n- [OpenMole](https://openmole.org/)\n- [Good-it](https://good-it.org)\n\n## Dans quelles conditions ?\n\n- l’association doit être active\n- elle doit porter des valeurs que je partage\n- elle doit pouvoir me montrer ses actions\n- elle ne doit pas avoir les moyens de se payer un graphiste\n\n## C’est un peu trop beau pour être vrai ton truc…\n\nIl faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\n\nSi vous êtes intéressés, [envoyez-moi un mail !](mailto:contac@nardu.in)\n\n## Qu’est-ce que t’y gagnes toi ?\n\nSimplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.","src/content/articles/fr/gratuiste.md","80c20493583a842c",{"html":369,"metadata":370},"\u003Ch2 id=\"gratuiste-quest-ce-que-cest\">Gratuiste, qu’est-ce que c’est ?\u003C/h2>\n\u003Cp>Dans le monde francophone du graphisme, le terme gratuiste est un terme péjoratif employé pour dénoncer certaines conditions de travail. Les plus répandues sont les concours d’affiche/de logo, les clients qui demandent que vous commenciez à travailler sans vous payer et qui paieront si ça leur convient, les appels d’offre non défrayés, etc.\u003Cbr>\nDe plus en plus, la communauté s’élève contre ces pratiques et les \u003Ca href=\"https://twitter.com/PayeTonAffiche\">dénonce.\u003C/a>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“ On n’est pas des gratuistes ! ”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Comprendre : nous exerçons un métier à part entière qui requiert de nombreuses connaissances et beaucoup de travail, payez-nous. Rien d’extravagant en somme. Regardez \u003Ca href=\"https://youtu.be/essNmNOrQto\">cette vidéo\u003C/a> qui transpose ces pratiques à des métiers “ standards ” et \u003Ca href=\"https://youtu.be/DsstOs-K7gk\">celle-ci\u003C/a> qui explique en détails le processus actuel.\u003C/p>\n\u003Ch2 id=\"tes-débile-du-coup\">T’es débile du coup ?\u003C/h2>\n\u003Cp>J’aime à penser que non. Je n’aspire pas à devenir gratuiste dans ce sens là du terme. J’aimerais lui en donner un nouveau, plus positif. Dans les conditions précédentes, gratuiste est en effet une situation que personne (graphiste ou autre) n’aimerait expérimenter et encore moins promouvoir. À part peut-être des “ clients ” sans scrupules.\u003C/p>\n\u003Cp>Étant encore assez nouveau sur le marché du travail, je n’ai pas la solution de faire des dons à des associations, qu’ils soient financiers ou autre.\u003Cbr>\nNéanmoins, j’ai envie d’aider à mon échelle et selon mes capacités.\u003C/p>\n\u003Ch2 id=\"le-concept\">Le concept\u003C/h2>\n\u003Cp>Je compte proposer mes services et mes compétences gratuitement à des associations caritatives/ONG qui viennent en aide aux personnes dans le besoin ou aux animaux.\u003Cbr>\nCe type de prestation porte le nom de “ \u003Cstrong>pro bono publico\u003C/strong> ” – “ \u003Cstrong>pour le bien public\u003C/strong> ”.\u003C/p>\n\u003Cp>Cette pratique existe essentiellement dans les milieux juridiques. Je pense cependant qu’elle n’est pas incompatible avec le métier de graphiste.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Graphiste pro bono, pourquoi pas ?\u003C/p>\n\u003C/blockquote>\n\u003Ch2 id=\"quels-genres-de-services\">Quels genres de services ?\u003C/h2>\n\u003Cp>En toute logique, le type qui rend service à l’association, qui peut faire une différence. À mes yeux, essentiellement des sites internet. Je pense qu’un site web aura bien plus d’intérêt qu’un nouveau logo. Pourquoi pas des flyers/des petits visuels pour des pin’s/badges.\u003C/p>\n\u003Ch3 id=\"en-résumé\">En résumé :\u003C/h3>\n\u003Cul>\n\u003Cli>maquette de site web\u003C/li>\n\u003Cli>intégration front-end (en dur ou via wordpress) du site\u003C/li>\n\u003Cli>gestion de la mise en ligne du site\u003C/li>\n\u003Cli>newsletter (design et/ou intégration)\u003C/li>\n\u003Cli>flyers\u003C/li>\n\u003Cli>autres petites demandes\u003C/li>\n\u003C/ul>\n\u003Cp>Vous pouvez avoir un aperçu de mon travail \u003Ca href=\"/\">sur ce même site.\u003C/a> J’ai déjà eu l’occasion de travailler pour :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"/projets/cygnal\">Cygnal\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://openmole.org/\">OpenMole\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://good-it.org\">Good-it\u003C/a>\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"dans-quelles-conditions\">Dans quelles conditions ?\u003C/h2>\n\u003Cul>\n\u003Cli>l’association doit être active\u003C/li>\n\u003Cli>elle doit porter des valeurs que je partage\u003C/li>\n\u003Cli>elle doit pouvoir me montrer ses actions\u003C/li>\n\u003Cli>elle ne doit pas avoir les moyens de se payer un graphiste\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"cest-un-peu-trop-beau-pour-être-vrai-ton-truc\">C’est un peu trop beau pour être vrai ton truc…\u003C/h2>\n\u003Cp>Il faut garder à l’esprit que je compte travailler bénévolement pendant mon temps libre. Je ne cherche pas une relation client habituelle puisqu’il n’y aura pas de client à proprement parler. Cela me permettra d’éviter des délais intenables, des retours par milliers et toute obligation de finir le travail en cas de coup fourré.\nJe préfère être franc là-dessus même si je ne me fais pas trop de soucis sur les mœurs du monde associatif. Aussi, faudra-t-il être un peu patient si jamais j’ai déjà une demande en cours.\u003C/p>\n\u003Cp>Si vous êtes intéressés, \u003Ca href=\"mailto:contac@nardu.in\">envoyez-moi un mail !\u003C/a>\u003C/p>\n\u003Ch2 id=\"quest-ce-que-ty-gagnes-toi\">Qu’est-ce que t’y gagnes toi ?\u003C/h2>\n\u003Cp>Simplement la satisfaction d’avoir aidé, à mon échelle, des personnes en difficulté. Je ne fais pas ça pour me faire de la pub ou pour étayer mon portfolio. Cela me permettra en revanche de travailler sur d’autres sujets et dans un cadre différent.\u003C/p>",{"headings":371,"imagePaths":396,"frontmatter":397},[372,375,378,381,384,387,390,393],{"depth":105,"slug":373,"text":374},"gratuiste-quest-ce-que-cest","Gratuiste, qu’est-ce que c’est ?",{"depth":105,"slug":376,"text":377},"tes-débile-du-coup","T’es débile du coup ?",{"depth":105,"slug":379,"text":380},"le-concept","Le concept",{"depth":105,"slug":382,"text":383},"quels-genres-de-services","Quels genres de services ?",{"depth":162,"slug":385,"text":386},"en-résumé","En résumé :",{"depth":105,"slug":388,"text":389},"dans-quelles-conditions","Dans quelles conditions ?",{"depth":105,"slug":391,"text":392},"cest-un-peu-trop-beau-pour-être-vrai-ton-truc","C’est un peu trop beau pour être vrai ton truc…",{"depth":105,"slug":394,"text":395},"quest-ce-que-ty-gagnes-toi","Qu’est-ce que t’y gagnes toi ?",[],{"title":359,"subtitle":360,"lang":17,"slug":356,"excerpt":398,"tags":399,"type":214,"createdAt":400,"updatedAt":401},"J’ai cherché un moyen de mettre mes compétences au service d’autrui et je pense avoir trouvé: je vais travailler gratuitement pour des associations.",[362,222],"2017-05-27T07:47:36.000Z","2022-12-27T15:36:06.000Z","the-day-I-jamd",{"id":402,"data":404,"body":412,"filePath":413,"digest":414,"deferredRender":292},{"title":405,"subtitle":406,"lang":17,"tags":407,"type":214,"slug":402,"createdAt":410,"updatedAt":411},"The day I Jam’d","Des paris, des outils et du fun.",[408,409],"Dev","Jamstack",["Date","2020-10-08T07:47:36.000Z"],["Date","2022-12-27T15:40:06.000Z"],"\u003Ca href='/articles/en-the-day-I-jamd/' lang='en'>This content exists in english.\u003C/a>\n\nimport AstroImage from '../../../components/AstroImage.astro'\n\n## La solution de non facilité\n\nLorsque j’utilisais encore Wordpress pour mon site web personnel, j’ai voulu essayer le serveur web \u003Ca href=\"https://openlitespeed.org\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">OpenLiteSpeed (en anglais)\u003C/a>. En tant que designer, j’ai toujours aimé avoir une interface graphique et j’avais entendu dire qu’OLS jouissait de bonnes performances en général et de cache en particulier.\n\n## Battez-vous!\n\nQuelques années plus tard, je découvrais l’univers Jamstack et son incroyable potentiel. N’étant pas du tout impulsif, j’ai choisi de refaire entièrement mon site web avec des outils comme \u003Ca href=\"https://www.11ty.dev/\" lang=\"en\" hreflang=\"en\" rel=\"noopener noreferer\">11ty (en anglais)\u003C/a> et \u003Ca href=\"https://strapi.io/\" hreflang=\"en\">Strapi (en anglais)\u003C/a>.\n\nJe me souviens que Strapi était encore en alpha/beta et que certains collègues me disaient que c’était un pari risqué, surtout que je découvrais à peine le monde de node.js.\n\n> Open source et français ? Je dis banco !\n\nJ’ai donc commencé à recréer mon site web à l’identique avec 11ty et Strapi. Même hébergement chez Digital Ocean, même serveur web, même contenu. J’avais fait pas mal d’optimisations de performances sur mon installation wordpress, j’étais donc impatient de comparer les résultats avec la nouvelle version statique.\n\nJ’en suis resté pantois ! Quasiment sans optimisation du côté statique, j’ai obtenu les résultats ci-dessous.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 53/100 sur Wordpress.'\n/>\n\nMalgré beaucoup d’efforts, je n’ai pas pu faire mieux. Je ne suis pas un expert en cache, je n’utilise pas de CDN et je me suis appuyé sur des plugins pour réaliser beaucoup de choses (php n’étant pas ma spécialité 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Score de performance de 97/100 en Jamstack.'\n/>\n\nPresque **zéro** configuration spéciale (j’étais trop impatient de tester) et j’ai atteint un score impressionnant. Je sais que les scores lighthouse ne font pas tout mais **53 contre 97**… Ça me va !\n\n## Embrassez-vous 🥰\n\nCes deux approches ont leurs avantages et leurs inconvénients. En tant que freelance, mes clients préfèrent ou demandent souvent Wordpress en raison de sa réputation. Je présente toujours une alternative Jamstack lorsque c’est possible, mais cela reste effrayant la plupart du temps par rapport à Wordpress. Je pense cependant qu’il sera plus facile d’utiliser la Jamstack avec le temps.\n\n## Encore et encore…\n\nNous voici maintenant une quarantaine et quelques mois plus tard et ce site fonctionne avec… [Nuxt.js](https://fr.nuxtjs.org/). Je sais, je suis désolé, je n’ai pas pu résister à la dernière fonctionnalité [\u003Cspan lang=\"en\">nuxt content\u003C/span>](https://content.nuxtjs.org/fr) de Nuxt.\n\nDu coup j’ai tout refait… et laissez-moi vous dire : **wow**, quelle expérience !\nJ’adore développer avec Nuxt. L’utilisation de \u003Cspan lang=\"en\">nuxt content\u003C/span> m’a permis de me concentrer sur le design et, évidemment, sur le contenu.\nPlus de client Apollo ni de requête graphQL, seulement du \u003Cspan lang=\"en\">markdown\u003C/span> et quelques promesses.\n\nAttention, j’aime beaucoup travailler avec Strapi et son interface graphQL mais pour les besoins de ce site, \u003Cspan lang=\"en\">nuxt content\u003C/span> fait le \u003Cspan lang=\"en\">job\u003C/span> (extrêmement bien).\n\nJ’utilise toujours Strapi pour téléverser, stocker et gérer les images, vidéos, gifs, etc. C’est peut-être trop pour ce que j’en fait mais j’aime savoir que je peux toujours y revenir si j’ai envie ! De plus, j’ai passé pas mal de temps à le mettre en place avec \u003Cspan lang=\"en\">OpenLiteSpeed\u003C/span> et je suis encore trop attaché à cette réussite pour la laisser tomber.\n\n## Et en fait à la fin\n\nWordpress, Jamstack, fait main… Est-ce vraiment important ? Pour moi, l’expérience de développement a été bien plus agréable en travaillant avec 11ty, nuxt.js et strapi qu’avec Wordpress.\n\nDu point de vue de la performance et de l’accessibilité, il semble également que ce soit le choix le plus judicieux. Ce n’est peut-être pas le cas à chaque fois ! ¯\\\\\\_(ツ)\\_/¯\n\nJ’ai hâte d’apprendre \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\" >astro\u003C/a> et de tout recommencer à zéro !","src/content/articles/fr/the-day-I-jamd.mdx","b474c8ff88ed0b47","video-compression",{"id":415,"data":417,"body":293,"filePath":422,"digest":423,"rendered":424},{"title":418,"subtitle":288,"lang":17,"tags":419,"type":214,"slug":415,"createdAt":420,"updatedAt":421,"draft":292},"Compression vidéo",[290],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"src/content/articles/fr/video-compression.md","2296c41874b23b3d",{"html":297,"metadata":425},{"headings":426,"imagePaths":427,"frontmatter":428},[],[],{"title":418,"subtitle":288,"lang":17,"draft":292,"slug":415,"excerpt":429,"tags":430,"type":214,"createdAt":431,"updatedAt":250},"Pas encore traduit",[290],"2021-05-05T09:00:00.000Z","sci-hub-blocage",{"id":432,"data":434,"body":442,"filePath":443,"digest":444,"deferredRender":292},{"title":435,"subtitle":436,"lang":17,"tags":437,"type":214,"slug":432,"createdAt":440,"updatedAt":441},"Sci-hub bloqué, comment contourner","La science du partage.",[438,439],"Internet","Science",["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n\u003Ca href='/articles/en-sci-hub-unblock/' lang='en'>This content exists in english.\u003C/a>\n\nL'adresse actuelle de sci-hub est : \u003Ca href=\"https://www.sci-hub.st/\" rel=\"noreferer noopener\">sci-hub.st\u003C/a>\n\n## Résumé de la situation\n\nN’étant pas moi-même directement chercheur, je vous laisse regarder [cette vidéo](https://youtu.be/rcgxY__YXEc) explicative extrêmement bien faite sur le sujet de la publication scientifique.\n\n> “ Mais c’est scandaleux ! ”​\n\nJ’ai constaté que le blocage était actif chez SFR. Je n’ai pas encore pu vérifier pour les autres fournisseurs mais j’imagine qu’ils se sont tous conformés à la décision de justice.\nLe blocage mis en place est assez basique. Il s’agit d’un blocage “ DNS ”.\n\nUn DNS est un serveur qui sert à faire le lien entre un nom de domaine : **sci-hub.tw** et une adresse IP : **186.2.163.90**.\n\nC’est en quelque sorte l’annuaire d’internet. Sans l’adresse, impossible de contacter le domaine. Ce que les FAI ont certainement fait : bloquer les requêtes au nom de domaine [sci-hub.se.](http://sci-hub.se/) Ainsi, aucune adresse IP n’est renvoyée et le site n’est pas accessible.\n\n## Comment contourner ce blocage ?\n\n- Soit en utilisant un VPN\n- Soit en modifiant les serveurs DNS de vos ordinateurs/box internet\n\nJe recommande la deuxième solution car elle permet de se prémunir contre de futurs blocages/filtrages/censures de la part de votre FAI et ne nécessite pas de contrepartie financière.\nJe vais me focaliser sur le changement depuis un ordinateur car il sera effectif où que vous soyez.\n\n### Sur MacOs\n\nOuvrez :\n\n1. Préférences système\n1. Réseau\n1. Ethernet et/ou Wi-fi\n1. Avancé\n1. DNS\n1. Serveurs DNS\n\nDe là, vous pouvez ajouter des serveurs DNS en cliquant sur l'icône +. Cliquez sur ok et appliquez les nouveaux paramètres. Vous devrez peut-être redémarrer votre ordinateur pour que les changements fonctionnent.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS réglages réseau et DNS'\n/>\n\n### Sur Windows (ici 10)\n\nOuvrez :\n\n1. Réglages\n1. Réseau et internet\n1. Modifier les options de l'adaptateur\n1. Clic droit sur les propriétés de votre interface réseau\n1. Selectionnez « protocole Internet version 4 » (et/ou 6)\n1. Propriétés\n1. Utiliser l’adresse de serveur DNS suivante\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Réglages windows'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows réglages réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows régalges connections réseaux'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows options adaptateur réseau'\n/>\n\n## Quels serveurs DNS utiliser ?\n\nIl y a de nombreux serveurs DNS accessibles. Les plus connus étant ceux de Google, Cloudflare et OpenDNS. Si vous tenez vraiment à utiliser ceux de Google, je vous laisse chercher leur adresse. Voici mes recommandations par ordre de préférence.\n\nPlusieurs fournisseurs :\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMes favoris puisqu’il s’agit d’une [association française.](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net/fr)\n\nQuand9 est une fondation à but non lucratif proposant des serveurs DNS publics et gratuits. Leurs serveur classiques offrent un filtrage de domaines malveillants identifiés. Ils ne collectent pas de données et sont conforment au \u003Cabbr title=\"Règlement général sur la protection des données\">RGPD\u003C/abbr>.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## C'est tout.\n\nEn modifiant ces réglages, vous vous affranchissez de vos fournisseurs d’accès et de leurs règles de filtrage du contenu.\n\nPour l’instant, ces blocages sont presque symboliques car si Sci-hub venait à changer d’url, le blocage ne fonctionnerait plus. Mais la victoire des éditeurs au tribunal montre qu’ils n’ont pas dit leur dernier mot. Nous ne sommes donc pas à l’abri d’un futur blocage plus large et plus dur à contrer.\n\nSi vous voulez en apprendre plus sur le combat de ces gens qui se battent pour que la recherche ne soit pas une marchandise, je vous conseille [ce documentaire](https://youtu.be/y_CQATGOX2w) sur Aaron Shwartz. Ou plus simplement [cet article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) sur la fondatrice de Sci-hub.\n\nEn attendant, bonnes lectures à tou·te·s. On est avec vous !","src/content/articles/fr/sci-hub-blocage.mdx","f7b5a20f2a594ef2","en-2022",{"id":445,"data":447,"body":452,"filePath":453,"digest":454,"rendered":455},{"title":219,"subtitle":448,"lang":449,"tags":450,"type":214,"slug":445,"createdAt":451},"2022 update of many things.","en",[222],["Date","2022-06-08T14:24:06.000Z"],"After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\n\n## Services\n\n### No more print\n\nEven though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for \"classic\" graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\n\n### Internet all the way\n\nOn the other hand, I spend my time **doing web stuff.** A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer **more specific web offerings,** in which I have specialised.\n\nThus, **accessibility** and **eco-design** become integrated expertises in my practice. They are no longer options on a quote but **my core business.**\n\n## The website\n\nI have reworked my website, especially the homepage and its content, to better reflect these decisions.\n\nI have also made several behavioural changes:\n\n- external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven't found a good reason to continue using this behaviour;\n- I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by [@HTeuMeuLeu](https://twitter.com/HTeuMeuLeu);\n- \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\n- I only trigger animations if the user has not asked the system to reduce the amount motion [(reference)](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).\n\nI am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello [astro](https://astro.build/) 👀).\n\n## Le Nico\n\nOn a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\n\nI have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.","src/content/articles/en/2022.md","7b98592763cb0929",{"html":456,"metadata":457},"\u003Cp>After two years of full-time freelancing, I took a step back from my activity. I especially questioned my positioning and the services I was offering.\u003C/p>\n\u003Ch2 id=\"services\">Services\u003C/h2>\n\u003Ch3 id=\"no-more-print\">No more print\u003C/h3>\n\u003Cp>Even though I am trained in branding, I rarely do it and do not practice it in my free time. The same goes for “classic” graphic design. Posters, flyers and other leaflets have disappeared from my quotes for a long time. It seems logical to me to no longer explicitly offer these services because I consider that I am no longer sufficiently competent or interested.\u003C/p>\n\u003Ch3 id=\"internet-all-the-way\">Internet all the way\u003C/h3>\n\u003Cp>On the other hand, I spend my time \u003Cstrong>doing web stuff.\u003C/strong> A lot of development, some design and a fait amout of server configuration. It is therefore obvious for me to offer \u003Cstrong>more specific web offerings,\u003C/strong> in which I have specialised.\u003C/p>\n\u003Cp>Thus, \u003Cstrong>accessibility\u003C/strong> and \u003Cstrong>eco-design\u003C/strong> become integrated expertises in my practice. They are no longer options on a quote but \u003Cstrong>my core business.\u003C/strong>\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Cp>I have reworked my website, especially the homepage and its content, to better reflect these decisions.\u003C/p>\n\u003Cp>I have also made several behavioural changes:\u003C/p>\n\u003Cul>\n\u003Cli>external links no longer open in a new window. I read \u003Ca href=\"https://css-tricks.com/use-target_blank/\" rel=\"noopener noreferer\">this article\u003C/a> about opening links in a new window and I haven’t found a good reason to continue using this behaviour;\u003C/li>\n\u003Cli>I have removed the open graph and twitter card meta tags as I fully agree with \u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310316496728065\" rel=\"noopener noreferer\" hreflang=\"fr\">this opinion (in french)\u003C/a> by \u003Ca href=\"https://twitter.com/HTeuMeuLeu\">@HTeuMeuLeu\u003C/a>;\u003C/li>\n\u003Cli>\u003Ca href=\"https://twitter.com/HTeuMeuLeu/status/1370310312214339586\" rel=\"noopener noreferer\" hreflang=\"fr\">same for the favicon\u003C/a>;\u003C/li>\n\u003Cli>I only trigger animations if the user has not asked the system to reduce the amount motion \u003Ca href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion\">(reference)\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>I am working on reducing the weight of my pages as much as possible, although I will certainly have to change tools (again) (hello \u003Ca href=\"https://astro.build/\">astro\u003C/a> 👀).\u003C/p>\n\u003Ch2 id=\"le-nico\">Le Nico\u003C/h2>\n\u003Cp>On a personal level, I have committed myself to a more responsible digital world by joining the \u003Ca href=\"https://www.good-it.org/\" rel=\"noopener noreferer\" hreflang=\"fr\">Good-it! (in french)\u003C/a> collective and by actively participating in its development.\u003C/p>\n\u003Cp>I have also started teaching in several schools. I mainly intervene on digital courses by teaching design and development. I take this opportunity to to make future generations aware of accessibility and eco-design.\u003C/p>",{"headings":458,"imagePaths":472,"frontmatter":473},[459,462,465,468,471],{"depth":105,"slug":460,"text":461},"services","Services",{"depth":162,"slug":463,"text":464},"no-more-print","No more print",{"depth":162,"slug":466,"text":467},"internet-all-the-way","Internet all the way",{"depth":105,"slug":469,"text":470},"the-website","The website",{"depth":105,"slug":244,"text":245},[],{"title":219,"subtitle":448,"lang":449,"slug":445,"excerpt":474,"tags":475,"type":214,"createdAt":250},"Changes in my services, the website and myself.",[222],"en-2023",{"id":476,"data":478,"body":483,"filePath":484,"digest":485,"rendered":486},{"title":253,"subtitle":479,"lang":449,"tags":480,"type":214,"slug":476,"createdAt":481,"updatedAt":482},"Update 2023.",[222],["Date","2023-02-03T17:41:00.000Z"],["Date","2023-05-17T17:41:00.000Z"],"This article will be updated when I have something new to share during the year 2023.\n\n## The website\n\n### Technologies\n\nOops... I (re)did it again.\n\nI have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself [in 2022 !](/en/articles/2022/#the-website)\n\nI will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\n\nMy \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I'm back to a solid **95/100** without any particular optimization. With some small efforts, I've reached the good old 100/100.\n\nI then did a work of modernization of the codebase. Hello CSS variables and goodbye `media queries`. In no particular order, here are some of the improvements I made:\n\n- `flexbox` and `grid` to adapt the layout to different screen sizes;\n- CSS variables for colors, font sizes and margins;\n- some `container queries`, just to try;\n- logical CSS properties (`inline` and `block` instead of `width` and `height` for example).\n\nI took this opportunity to publish [the source code](https://git.nardu.in/nardu.in/website-astro) on my git repository.\n\n**Update #1:** I've added [an RSS feed](/en/rss.xml) as I find myself using it more and more on other websites.\n\n### Analytics\n\nI removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\n\nIt's nice to see that your site is consulted, but if there is no other purpose behind it, it's an extra resource loaded for nothing by visitors. Maybe I'll reactivate the tracking when I have a use for it (other than flattering my ego).\n\nPrevious visit reports can be found at [this link.](https://stat.nardu.in/share/nJSt1tfS/nardu.in)\n\n### Content\n\n- I've added a [work](/en/work/) page to list some of my projects.\n- I've also added [a page](/en/veille/) where I list some interesting things from around the web.\n\n## Additional projects\n\nI'm still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at [3-w.fr](https://3-w.fr/) (an address I am very proud of).\n\nI have to update it more regularly but I hope that the platform will help students progress!\n\n**More to come soon!**","src/content/articles/en/2023.md","489c650e66cced63",{"html":487,"metadata":488},"\u003Cp>This article will be updated when I have something new to share during the year 2023.\u003C/p>\n\u003Ch2 id=\"the-website\">The website\u003C/h2>\n\u003Ch3 id=\"technologies\">Technologies\u003C/h3>\n\u003Cp>Oops… I (re)did it again.\u003C/p>\n\u003Cp>I have completely redeveloped my site with \u003Ca href=\"https://astro.build/\" rel=\"noopener noreferer\" hreflang=\"en\">Astro\u003C/a>, as predicted by myself \u003Ca href=\"/en/articles/2022/#the-website\">in 2022 !\u003C/a>\u003C/p>\n\u003Cp>I will definitely do an article or two about Astro and the extensions I used. It was a great experience. Nuxt v2 is not really up to date anymore, so the performance was not good. Astro has completely fixed that.\u003C/p>\n\u003Cp>My \u003Ca href=\"https://pagespeed.web.dev/analysis/https-nardu-in/06as4el7ed?form_factor=mobile\" rel=\"noopener noreferer\">PageSpeed\u003C/a> performance score had dropped to 77/100. Thanks to Astro I’m back to a solid \u003Cstrong>95/100\u003C/strong> without any particular optimization. With some small efforts, I’ve reached the good old 100/100.\u003C/p>\n\u003Cp>I then did a work of modernization of the codebase. Hello CSS variables and goodbye \u003Ccode>media queries\u003C/code>. In no particular order, here are some of the improvements I made:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>flexbox\u003C/code> and \u003Ccode>grid\u003C/code> to adapt the layout to different screen sizes;\u003C/li>\n\u003Cli>CSS variables for colors, font sizes and margins;\u003C/li>\n\u003Cli>some \u003Ccode>container queries\u003C/code>, just to try;\u003C/li>\n\u003Cli>logical CSS properties (\u003Ccode>inline\u003C/code> and \u003Ccode>block\u003C/code> instead of \u003Ccode>width\u003C/code> and \u003Ccode>height\u003C/code> for example).\u003C/li>\n\u003C/ul>\n\u003Cp>I took this opportunity to publish \u003Ca href=\"https://git.nardu.in/nardu.in/website-astro\">the source code\u003C/a> on my git repository.\u003C/p>\n\u003Cp>\u003Cstrong>Update #1:\u003C/strong> I’ve added \u003Ca href=\"/en/rss.xml\">an RSS feed\u003C/a> as I find myself using it more and more on other websites.\u003C/p>\n\u003Ch3 id=\"analytics\">Analytics\u003C/h3>\n\u003Cp>I removed the tracking on my pages. I was using \u003Ca href=\"https://umami.is/\" rel=\"noopener noreferer\">umami\u003C/a> hosted on my own server. No personal data was collected and I rarely consulted the reports.\u003C/p>\n\u003Cp>It’s nice to see that your site is consulted, but if there is no other purpose behind it, it’s an extra resource loaded for nothing by visitors. Maybe I’ll reactivate the tracking when I have a use for it (other than flattering my ego).\u003C/p>\n\u003Cp>Previous visit reports can be found at \u003Ca href=\"https://stat.nardu.in/share/nJSt1tfS/nardu.in\">this link.\u003C/a>\u003C/p>\n\u003Ch3 id=\"content\">Content\u003C/h3>\n\u003Cul>\n\u003Cli>I’ve added a \u003Ca href=\"/en/work/\">work\u003C/a> page to list some of my projects.\u003C/li>\n\u003Cli>I’ve also added \u003Ca href=\"/en/veille/\">a page\u003C/a> where I list some interesting things from around the web.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"additional-projects\">Additional projects\u003C/h2>\n\u003Cp>I’m still teaching web development this year. In order to expand my course materials, I have set up a mini documentation site available at \u003Ca href=\"https://3-w.fr/\">3-w.fr\u003C/a> (an address I am very proud of).\u003C/p>\n\u003Cp>I have to update it more regularly but I hope that the platform will help students progress!\u003C/p>\n\u003Cp>\u003Cstrong>More to come soon!\u003C/strong>\u003C/p>",{"headings":489,"imagePaths":501,"frontmatter":502},[490,491,492,495,498],{"depth":105,"slug":469,"text":470},{"depth":162,"slug":267,"text":268},{"depth":162,"slug":493,"text":494},"analytics","Analytics",{"depth":162,"slug":496,"text":497},"content","Content",{"depth":105,"slug":499,"text":500},"additional-projects","Additional projects",[],{"title":253,"subtitle":479,"lang":449,"slug":476,"excerpt":503,"tags":504,"type":214,"createdAt":282,"updatedAt":283},"New changes.",[222],"en-2025",{"id":505,"data":507,"body":512,"filePath":513,"digest":514,"rendered":515},{"title":508,"subtitle":509,"lang":449,"tags":510,"type":214,"slug":505,"createdAt":511},"Nico v3.0","This website no longer has an english version..",[222],["Date","2025-01-02T17:41:00.000Z"],"## So long \u003Ccode style=\"font-size: var(--size-2)\">lang=\"en\"\u003C/code>\n\nI have maintained an english version of my website for some years but **no more…** The effort needed to make a fully multilingual website with Astro is just too much work for my small personal website.\n\n**All previous content will remain online** ([articles](/articles/#en-articles) and [snippets](/fragments/#en-fragments)) but the interface and internal pages will only be in french.\n\nI do not have any metrics on who visits my website but I don't think it will be missed. If you do miss it, don't hesitate to send me an email!","src/content/articles/en/2025.md","669bebc4518d51e1",{"html":516,"metadata":517},"\u003Ch2 id=\"so-long-langen\">So long \u003Ccode style=\"font-size: var(--size-2)\">lang=“en”\u003C/code>\u003C/h2>\n\u003Cp>I have maintained an english version of my website for some years but \u003Cstrong>no more…\u003C/strong> The effort needed to make a fully multilingual website with Astro is just too much work for my small personal website.\u003C/p>\n\u003Cp>\u003Cstrong>All previous content will remain online\u003C/strong> (\u003Ca href=\"/articles/#en-articles\">articles\u003C/a> and \u003Ca href=\"/fragments/#en-fragments\">snippets\u003C/a>) but the interface and internal pages will only be in french.\u003C/p>\n\u003Cp>I do not have any metrics on who visits my website but I don’t think it will be missed. If you do miss it, don’t hesitate to send me an email!\u003C/p>",{"headings":518,"imagePaths":522,"frontmatter":523},[519],{"depth":105,"slug":520,"text":521},"so-long-langen","So long lang=“en”",[],{"title":508,"subtitle":509,"lang":449,"slug":505,"excerpt":524,"tags":525,"type":214,"createdAt":526},"This website no longer has an english version.",[222],"2025-01-02T17:41:00.000Z","en-faq",{"id":527,"data":529,"body":534,"filePath":535,"digest":536,"rendered":537},{"title":530,"subtitle":531,"lang":449,"tags":532,"type":214,"slug":527,"createdAt":533,"draft":292},"Accessibility and sobriety","Translation in progress, stay tuned ;)",[222],["Date","2022-06-22T15:34:45.000Z"],"[Go back to available articles](/en/articles)","src/content/articles/en/faq.md","82d516449896f6ca",{"html":538,"metadata":539},"\u003Cp>\u003Ca href=\"/en/articles\">Go back to available articles\u003C/a>\u003C/p>",{"headings":540,"imagePaths":541,"frontmatter":542},[],[],{"title":530,"subtitle":531,"lang":449,"slug":527,"draft":292,"excerpt":543,"tags":544,"type":214,"createdAt":355},"Why, how et and especially what.",[222],"en-after-effects-expressions",{"id":545,"data":547,"body":551,"filePath":552,"digest":553,"deferredRender":292},{"title":287,"subtitle":548,"lang":449,"tags":549,"type":214,"slug":545,"createdAt":550,"code":292},"Animation on steroïds.",[290],["Date","2019-04-24T09:00:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## An ever lasting battle\n\nThere is very little documentation and the existing one is hard to find or very old. Very often I just don't have the time to dive into expression learning while animating even though it could help the entire project on the long term.\nSo the last time I had to do a complex animation, **I took the damn time!**\n\n## The begining of the end (of keyframes).\n\nEveryone uses expressions whether they know it or not. Most of the time it's a rather transparent process for the animator. For example: when parenting a property to another one, After Effects creates an expression for us.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/basic_expression_d81b12f1ac.jpeg'\n\twidth='728'\n\theight='80'\n\talt='Parenting the position of the form to a null creates an expression.'\n/>\n\nOver the last updates, Adobe has made an effort to make expressions more accessible to everyone. For example, the expression box is now resembling a code editor thanks to code-coloring and auto-completion features. After Effects expression feel like JavaScript with custom functions.\n\nThose custom functions can be called through a menu once you enabled the expressions on a property. It offers organized shortcut and proper syntax to all of AE native functions and a bunch of JavaScript standard ones.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/shortcut_39cc19d383.jpeg'\n\twidth='728'\n\theight='322'\n\talt='Alt + Click the stopwatch to access the shortcuts.'\n/>\n\n## So I need to learn javascript to do motion design now?\n\n### Why bother?\n\nI know that most animators don't have any kind of development background. However, if Adobe thought it best to let us use expressions, I think we ought to, at least, try.\n\n> A lot of incredible professionals like [Mt Mograph](https://www.mtmograph.com/) and [Video Copilot](https://videocopilot.net/) use expressions.\n\nLike every optimization process, building an expressions knowledge takes time. However, like all optimization process, you will benefit from it afterwards.\n\n### Where to learn\n\nI've gathered a list of my favourite learning grounds. Plenty more exist, **go get'em!**\n\n- [Adobe official expression starter guide (FR)](https://helpx.adobe.com/fr/after-effects/using/expression-language-reference.html)\n- [Adobe official expression basic (EN)](https://helpx.adobe.com/after-effects/using/expression-basics.html)\n- [Adobe forums for expressions](https://community.adobe.com/t5/after-effects/bd-p/after-effects?page=1&sort=latest_replies&filter=all&topics=label-expressions)\n- [Creative Cow expressions forums](https://creativecow.net/forums/forum/adobe-after-effects-expressions/)\n- [Youtube channel about expressions](https://www.youtube.com/playlist?list=PLvr5U5ZSt6IzHyvSL9fo0M9NRPsTvra31)\n- [All expressions explained](http://aescript.jecool.net/reference/)\n- [All expressions explained again](http://expressions.aenhancers.com/index.html)\n- [Nice examples of basic expressions](https://www.schoolofmotion.com/tutorials/amazing-expressions-in-after-effects)\n\n## Real world example\n\n### Number counter\n\nLet's say you need to animate a rather simple counter from 0% to 100%.\n\n- Start by creating a text layer. Define your typographic choices, colours, etc.\n- On the effect menu add expression options > slider control\n- Alt + Click the Source text property\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/alt-counter.mp4' type='video/mp4' />\n\u003C/video>\n\n- Parent the source text to the slider control through the pickwhip.\n\n\u003Cvideo width='462' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/pickwhip.mp4' type='video/mp4' />\n\u003C/video>\n\nYou should get something like this in the expressions panel:\n\n```javascript\neffect(\"Slider Control\")(\"Slider\")​\n```\n\n- Set two keyframes on the slider from 0 to 100. The text should update accordingly.\n- By default, After Effects does not round numbers. In the expression panel, wrap your expression with the `Math.round()` function.\n\n\u003Cvideo width='728' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/round.mp4' type='video/mp4' />\n\u003C/video>\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\"))​\n```\n\nGreat! We have a working counter. But we wanted a percentage counter. We could add a % glyph in another text layer but let's not.\n\nStill in the expression panel, we're going to add a string containing the % glyph, using basic JavaScript concatenation: `+ '%'`\n\n```javascript\nMath.round(effect(\"Slider Control\")(\"Slider\")) + '%'​\n```\n\n\u003Cvideo width='538' loop controls preload='metadata'>\n\t\u003Csource src='https://assets.nardu.in/percent.mp4' type='video/mp4' />\n\u003C/video>\n\n**And there we go!** A fully functioning and customizable counter using a slider controller and expressions.","src/content/articles/en/after-effects-expressions.mdx","3b6f88fbf35af1a4","en-sci-hub-unblock",{"id":554,"data":556,"body":562,"filePath":563,"digest":564,"deferredRender":292},{"title":557,"subtitle":558,"lang":449,"tags":559,"type":214,"slug":554,"createdAt":560,"updatedAt":561},"Access blocked Sci-hub","The science of sharing.",[438,439],["Date","2019-03-31T07:47:36.000Z"],["Date","2022-12-27T12:08:00.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\nThe current sci-hub address is: \u003Ca href=\"https://www.sci-hub.st/\" rel=\"noreferer noopener\">sci-hub.st\u003C/a>\n\n## What is this about?\n\nNot being a researcher myself, here’s an [extremely well done explanatory video](https://youtu.be/rcgxY__YXEc) on the subject of scientific publication (french audio with auto subtitle).\n\n> “This is outrageous!”​\n\nI noticed that my ISP was indeed blocking access. I have not yet been able to check for the other suppliers, but I imagine that they have all complied with the court decision.\nThe restriction in place is quite basic. This is a “DNS” block. A DNS is a server that is used to link a domain name: **www.sci-hub.tw** to an IP address: **186.2.163.90**\nIt is, in a way, the Internet phone book. Without the address, it is impossible to contact the domain. What ISPs have certainly done: block requests to the [sci-hub.se.](http://sci-hub.se/) domain name. As a result, no IP address is returned and the site is not accessible.\n\n## How to bypass this?\n\n- Either by using a VPN\n- Either by modifying the DNS servers of your computers/Internet box\n\nI would recommend the second solution because it allows you to protect yourself against future blockages/filtering/censorship from your ISP and does not require any financial compensation.\nI will focus on change from a computer because it will be effective wherever you are and not only from your home.\n\n### MacOs\n\nGo to:\n\n1. System Preferences\n1. Network\n1. (wi-fi and/or ethernet)\n1. Advanced\n1. DNS\n\nFrom there, you can add DNS servers by clicking the + icon. Click ok and apply the new settings. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/ef5a4b8e82a046e6a466c73c2fd9e99e.jpg'\n\twidth='728'\n\theight='1060'\n\talt='MacOS network and DNS settings'\n/>\n\n### Windows (10)\n\nGo to:\n\n1. System Settings\n1. Network & Internet\n1. Change adapter options\n1. Right click your adapter then “properties”\n1. Select “internet protocol version 4” (and/or 6)\n1. Properties\n1. Use the following DNS server addresses\n\nFrom there, you can add DNS servers. Click save. You might need to restart your computer for the changes to work.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-settings.jpg'\n\twidth='728'\n\theight='319'\n\talt='Windows system settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-network.jpg'\n\twidth='728'\n\theight='803'\n\talt='Windows network settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter.jpg'\n\twidth='728'\n\theight='327'\n\talt='Windows network connections settings'\n/>\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/sci-hub-adapter-settings.jpg'\n\twidth='728'\n\theight='434'\n\talt='Windows network adapter settings'\n/>\n\n## Which DNS?\n\nThere are many DNS servers available. The best known are Google, Cloudflare and OpenDNS. If you really want to use Google’s, I’ll let you look up their address. Here are my recommendations in order of preference.\n\n### [FDN DNS](https://www.fdn.fr/actions/dns/)\n\nMy favorite since it is a [french association](https://www.fdn.fr/)\n\n1. IPV4\n - 80.67.169.12\n - 80.67.169.40\n2. IPV6\n - 2001:910:800::12\n - 2001:910:800::40\n\n### [Quad9](https://www.quad9.net)\n\nQuand9 is a non-profit foundation offering free public DNS servers. Their classic servers offer filtering of identified malicious domains. They do not collect data and are \u003Cabbr title=\"General Data Protection Regulation\">GDPR\u003C/abbr>-compliant.\n\n1. IPV4\n - 9.9.9.9\n - 149.112.112.112\n2. IPV6\n - 2620:fe::fe\n - 2620:fe::9\n\n## That's it.\n\nBy changing these settings, you are free from your ISPs and their content filtering rules.\n\nFor the moment, these restrictions are almost symbolic because if Sci-hub were to change its url, the block would no longer work. But the publishers’ victory in court shows that they have not had their last word. We are therefore not immune to a wider and stronger block in the future.\n\nIf you want to learn more about the struggle of the people who fight to ensure that research is not a paid commodity, I recommend [this documentary](https://youtu.be/y_CQATGOX2w) on Aaron Shwartz. Or [this article](https://arstechnica.com/tech-policy/2016/04/a-spiritual-successor-to-aaron-swartz-is-angering-publishers-all-over-again/) about the founder of Sci-hub.\n\nIn the meantime, good readings to all of you. We stand with you!","src/content/articles/en/sci-hub-blocage.mdx","af48e8c0c3b463bf","en-gratuiste",{"id":565,"data":567,"body":534,"filePath":570,"digest":571,"rendered":572},{"title":359,"subtitle":531,"lang":449,"tags":568,"type":214,"slug":565,"createdAt":569,"draft":292},[290,222],["Date","2017-05-27T07:47:36.000Z"],"src/content/articles/en/gratuiste.md","ebec75d19f0ff741",{"html":538,"metadata":573},{"headings":574,"imagePaths":575,"frontmatter":576},[],[],{"title":359,"subtitle":531,"lang":449,"slug":565,"draft":292,"excerpt":531,"tags":577,"type":214,"createdAt":400},[290,222],"en-the-day-I-jamd",{"id":578,"data":580,"body":585,"filePath":586,"digest":587,"deferredRender":292},{"title":405,"subtitle":581,"lang":449,"tags":582,"type":214,"slug":578,"createdAt":583,"updatedAt":584},"A story of unusual tools and fun gambles.",[408,409],["Date","2020-10-08T09:00:00.000Z"],["Date","2022-12-27T15:40:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## The not so easy choice\n\nWhen I was still using Wordpress for my personal website, I thought it would be nice to try [OpenLiteSpeed](https://openlitespeed.org) webserver. Being a designer, I always like to have a graphical interface and I heard OLS had very nice caching and overall performances.\n\n## FIGHT!\n\nA few years later, I learned about Jamstack and its incredible potential. Not being impulsive at all, I chose to entirely remake my website with tools like [11ty](https://www.11ty.dev/) and [Strapi](https://strapi.io/).\n\nI remember Strapi still being in alpha/beta and colleagues telling me it was a risky gamble, especially since I was pretty new to the node.js world.\n\n> Open source and french? Sign me up!\n\nSo I started recreating my website identically with 11ty and Strapi. Same hosting on a Digital Ocean droplet, same webserver, same content. I had done a fair amout of performance optimizations on my wordpress install so I was eager to compare the results with the new static version.\n\nBoy did they exceed my expectations! With almost no optimization on the static side, I got the following results.\n\n### wordpress\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/wordpress_8ee6f54b98.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 53/100 on Wordpress.'\n/>\n\nDespite a lot of efforts I could not do better. I’m no expert in caching, do not use CDN and relied on plugins to achieve a lot of stuff (php not being my strongest skill 😬).\n\n### 11ty + strapi\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/static_2c0d9f1eb8.jpeg'\n\twidth='728'\n\theight='412'\n\talt='Performance score of 97/100 on jamstack.'\n/>\n\nAlmost **zero** special configuration (I was too anxious to test) and I reached an awesome score. I know lighthouse scores are not everything but hey, **53 vs 97**… I’ll take it!\n\n## Now kiss 🥰\n\nBoth of these approaches have their benefits and drawbacks. As a freelance, my clients often prefer or ask for Wordpress because of its reputation. I always present a Jamstack alternative when possible but it’s still scary to most compared to Wordpress. I feel however that it’s going to be easier to use Jamstack with time.\n\n## I did it again…\n\nHere we are now, a quarantine and a few months later and this website is running with… [Nuxt.js](https://nuxtjs.org/). I know, I’m sorry, I couldn’t resist the latest [nuxt content](https://content.nuxtjs.org/) functionnality.\n\nSo I re-did everything again… and let me just say: **wow**, what an experience!\nI **love** developing with Nuxt. Using nuxt content allowed me to focus on design and, well, content.\nNo more Apollo client and graphQL query, only markdown and a few promises.\n\nDon’t get me wrong, I really like working with Strapi and its graphQL capabilities but for the purpose of this website, nuxt content does it (extremely well).\n\nI’m still using Strapi as a way to upload, store and manage images, videos, gifs, etc. It might be too much for this use case but I like to know that I can still go back to it if I want to! Also, I spent quite a bit of time setting it up with OpenLiteSpeed and I’m still too attached to this accomplishment to let it go.\n\n## In the end\n\nWordpress, Jamstack, vanilla everything… Does it really matter? For me, the dev experience was far more enjoyable working with 11ty, nuxt.js and strapi than with Wordpress.\n\nOn the performance and accessibility side, it also seems to be the better/smarter choice. It might not be everytime! ¯\\\\\\_(ツ)\\_/¯\n\nCan’t wait to learn [astro](https://astro.build/) and start from scratch again!","src/content/articles/en/the-day-I-jamd.mdx","60b77e216e02f618","en-video-compression",{"id":588,"data":590,"body":596,"filePath":597,"digest":598,"deferredRender":292},{"title":591,"subtitle":592,"lang":449,"tags":593,"type":214,"slug":588,"createdAt":594,"updatedAt":595},"Video compression","Encode like you mean it.",[290],["Date","2021-05-05T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Let's play.\n\nVideos are everywhere. **EVERYWHERE!** But videos can and will be huge when 4k becomes an internet standard. Currently, 1920x1080 is king and we usually have no problem hosting or playing this resolution.\n\n## Because we can doesn't mean we should.\n\nRight now, the (good) trend of web performance is on the rise. Everyone wants a blazing fast loading website, which might not be possible if we send requests to 100mb (or even more) videos.\n\nWith a good connection, users will not see the difference. But if we go down that path, nor will they with a 300mb one. So the goal is to make every asset as small as possible. It's already the case with images. But it's simpler and faster than video encoding.\n\n## Small size, best quality.\n\nLet's say we exported​ a 1920x1080 video from Premiere Pro with these basic settings:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-premiere-1.jpeg'\n\twidth='673'\n\theight='800'\n/>\n\nIt's gorgeous, it's Full HD, it's 1:30 minute of excellent editing but it's 50mb… What a shame.\n\n> We can already bring down the size from Premiere or Media Encoder by selecting CBR instead of VBR and using a low bitrate (like 2 or 3).\n\nLet's now use [Handbrake!](https://handbrake.fr/) It's free, open source and multi platform. You can also read this great article from [Ueno](https://loremipsum.ueno.co/dear-ueno-how-do-you-compress-videos-6657ebd9dd28?gi=930afecec398) on video encoding.\n\n**Please please PLEASE. Never export videos from within After Effects.**\n\n## Handbrake\n\n### Summary screen\n\nWhile it's not as nice as Premiere Pro, it has way more exporting capabilities. Follow these steps to use good standard settings:\n\n1. Open your source video\n1. Select a preset corresponding to your future usage like Fast 1080p30\n1. Check Web Optimized\n1. Keep MPEG-4 as the format\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-1.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Video screen\n\n1. Keep H.264 (x264) or use H.264 nvidia nvenc if you can (crazy fast encoding by nvidia)\n1. Choose Constant Quality and try a value between 20 and 30​ (higher = smaller size but lower quality)\n1. Choose Peak Framerate. If you don't know the framerate, keep the default setting\n1. Choose the type of video you are encoding (film, animation…)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-2.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Audio screen\n\nIf you don't have audio, be sure to set the audio channel to none.\nIf you have an audio channel, these settings are great and will not influence the size much​:\n\n1. Codec AAC\n1. Samplerate 44.1\n1. Bitrate 192 to 256 (your choice)\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-3.jpeg'\n\twidth='728'\n\theight='337'\n/>\n\n### Export!\n\nI used a RF of 25 for this example and no audio.\n\n1. My Premiere Pro video was 50,6mb\n1. My Handbrake video is 5,5mb​\n\n> What a save!\n\n​I ended up dividing the original size by 10. Which is cool.\nI tried with a RF of 30. The video was still pretty good and only 3,3mb.\n\n## Exporting for the web\n\nNow that we know how to properly compress videos, let's go further. Say we have a website with a lot of videos on the same page. We still want to load the content as fast as possible. So our videos need to be as small as possible. We won't do better than previously seen using mp4/H.264. However, we can use **webm/VP9.**\nWebm is an html video format and VP9 is its latest codec.\n\nUsing Handbrake and webm/VP9, we can achieve really great compression without losing too much quality (or none at all depending on the settings). I was able to divide by 4 the size of a video using these presets:\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/video-handbrake-4.jpg'\n\twidth='728'\n\theight='313'\n\talt=''\n/>\n\nThe only down side is that it takes some time to encode. It will depend on the video length and your computing power.\n\nI tried various settings but I read [here](https://trac.ffmpeg.org/wiki/Encode/VP9) that VP9 is supposed to be used with two-pass encoding. You then have to find the right bitrate (here 1000) for your situation.","src/content/articles/en/video-compression.mdx","5bb9f69df6c651d1","fragments",["Map",601,602,613,614,624,625,679,680,696,697,714,715,724,725,735,736,746,747,759,760,794,795,818,819,860,861,900,901,934,935,998,999],"en-image-full",{"id":601,"data":603,"body":610,"filePath":611,"digest":612,"deferredRender":292},{"title":604,"subtitle":531,"lang":449,"tags":605,"type":607,"slug":601,"createdAt":608,"updatedAt":609,"draft":292},"Full width image",[606],"CSS","snippets",["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"[Go back to available snippets](/en/snippets)","src/content/fragments/en/image-full.mdx","2e3dddf593f6d72f","en-super-cookies",{"id":613,"data":615,"body":621,"filePath":622,"digest":623,"deferredRender":292},{"title":616,"subtitle":617,"lang":449,"tags":618,"type":607,"slug":613,"createdAt":620},"The best cookies","Consentless biscuits.",[619],"food",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 tablespoon of baking powder\n- 3/4 of aquafaba from 400g of chickpea (chickpea water)\n- 125 grams of coconut oil\n- 2 teaspoons of maple syrup\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- if necessary, melt the coconut oil over low heat\n- meanwhile, mix all the dry ingredients\n- add all liquid ingredients (oil, aquafaba, maple syrup)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Non vegetalian version\n\n### Ingredients\n\n- 250 grams of flour\n- 70 grams of muscovado/vergeoise sugar (unrefined)\n- 20 grams of brown sugar\n- 1 pinch of salt\n- 1 table spoon of baking powder\n- 1 egg\n- 125 grams of melted butter\n- 2 teaspoons of honey\n- 1 chocolate bar (black) cut in “ chunks ”\n\n### Method\n\n- melt butter over low heat\n- meanwhile, mix all dry ingredients\n- add all liquid ingredients (melted butter, egg, honey)\n- mix well\n- add the chocolate\n- mix well (fig. 1)\n\n### Baking\n\nForm balls with the obtained mixture on a baking sheet.\nBake for 9 minutes at 210 degrees (Celsius) - fan setting (fig. 2).\n\n## Notes\n\nChocolate can be replaced by anything like nuts, raisins, legos... (don't eat legos be reasonable).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='All ingredients mixed together to form a brown paste.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='The cookies are round and soft after baking.'\n/>","src/content/fragments/en/super-cookies.mdx","b0c67adad40c177c","en-toulouse-fun",{"id":624,"data":626,"body":632,"filePath":633,"digest":634,"rendered":635},{"title":627,"subtitle":628,"lang":449,"tags":629,"type":607,"slug":624,"createdAt":631},"Toulouse yourself","Only the bestest",[630],"lifestyle",["Date","2022-06-22T15:34:45.000Z"],"Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite. \n**It's always a good idea to make a reservation!**\n\n## Restaurants\n\n### French cuisine\n\n- [Solides](https://www.solides.fr/) — semi-gastronomic\n- [Les impulsifs](https://les-impulsifs-toulouse.eatbu.com/?lang=en) — semi-gastronomic\n- [Sixta](https://sixta-toulouse.fr/) — vege/vegan/gluten friendly\n- [Attila](https://attila.site-solocal.com/) — great **fish restaurant,** just above the Victor Hugo market\n- [Chez Emile](https://www.restaurant-emile.com/) - best [cassoulet](https://en.wikipedia.org/wiki/Cassoulet) in town (or so I'm told)\n\n### Korean\n\n- [Le ptit Louis](https://leptitlouis.fr/) — best of its kind, **only for lunch**\n- [Kongbap](https://kong-bap.com/) — street-food like\n\n### Japanese\n\n- [Iori](https://www.iori.fr/) — best ramen\n- [Japoyaki](https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402) — best sushi/sashimis\n\n## Drinks and snacks\n\n### Bars\n\n- [Le Bièrographe](https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327) — all time favourite, **check out the typical toulouse basement**\n- [A Taula](https://www.facebook.com/ataulatolosa/) — all time favourite in summer, **amazing terrace,** also: great tapas\n- [The Hopscotch Pub](https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385) — good beers, good whiskies, good cocktials, good food\n\n### Cafés & tea rooms\n\n- [Bapz](https://www.bapz.fr/contact) — Excellent pastries / hot beverages\n- [Ô thé divin](https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/) — nice lunch options\n- [Les Rêveries d’Hercule](https://www.lesreveriesdhercule.com/) — Pottery Café, relaxing activity (ceramics need to be baked, there'll be a delay to get them back)\n- Bonus: the best bakeries in [Carmes](https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872) and [Saint-Aubin](https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694) — croissants, baguettes **traditions**, chocolatines and more\n\n### Wine shops\n\n- [l'envie du sud](https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930) — amazing selection of wines and other spirits, excellent advice from the staff\n- [enoteca](https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952) — smaller selection but more beers and great advice from the staff as well\n\n## Other delights\n\n### Ice creams\n\n- [Forno gusto](https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450) — only in the summer\n- [Moustache](https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540) — lots of flavours\n\n### Cheese shop\n\n- [Xavier](https://xavier.fr/) — one of the **best of the country**, two shops in Toulouse, including one at Victor Hugo market\n- [Massembea](https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490) — a serious contender in Toulouse (weird hours)\n\n### Delicatessen\n\n- [Café Bacquié](http://cafe-bacquie.com/) — stock up on fine foods, coffees, teas and other great quality products","src/content/fragments/en/toulouse-fun.md","370491cc68079e8c",{"html":636,"metadata":637},"\u003Cp>Here is my list of great places to go to when in Toulouse. There are of course a lot of other great places to go to, these are just my all time favourite.\u003Cbr>\n\u003Cstrong>It’s always a good idea to make a reservation!\u003C/strong>\u003C/p>\n\u003Ch2 id=\"restaurants\">Restaurants\u003C/h2>\n\u003Ch3 id=\"french-cuisine\">French cuisine\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.solides.fr/\">Solides\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://les-impulsifs-toulouse.eatbu.com/?lang=en\">Les impulsifs\u003C/a> — semi-gastronomic\u003C/li>\n\u003Cli>\u003Ca href=\"https://sixta-toulouse.fr/\">Sixta\u003C/a> — vege/vegan/gluten friendly\u003C/li>\n\u003Cli>\u003Ca href=\"https://attila.site-solocal.com/\">Attila\u003C/a> — great \u003Cstrong>fish restaurant,\u003C/strong> just above the Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.restaurant-emile.com/\">Chez Emile\u003C/a> - best \u003Ca href=\"https://en.wikipedia.org/wiki/Cassoulet\">cassoulet\u003C/a> in town (or so I’m told)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"korean\">Korean\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://leptitlouis.fr/\">Le ptit Louis\u003C/a> — best of its kind, \u003Cstrong>only for lunch\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://kong-bap.com/\">Kongbap\u003C/a> — street-food like\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"japanese\">Japanese\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.iori.fr/\">Iori\u003C/a> — best ramen\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2447719414@Japoyaki#map=16.50/43.6061725/1.4473402\">Japoyaki\u003C/a> — best sushi/sashimis\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"drinks-and-snacks\">Drinks and snacks\u003C/h2>\n\u003Ch3 id=\"bars\">Bars\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:1532531236@Le_Bi%C3%A8rographe#map=16.50/43.5986892/1.4428327\">Le Bièrographe\u003C/a> — all time favourite, \u003Cstrong>check out the typical toulouse basement\u003C/strong>\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.facebook.com/ataulatolosa/\">A Taula\u003C/a> — all time favourite in summer, \u003Cstrong>amazing terrace,\u003C/strong> also: great tapas\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:5592180378@The_Hopscotch#map=18.14/43.6006796/1.4431385\">The Hopscotch Pub\u003C/a> — good beers, good whiskies, good cocktials, good food\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cafés--tea-rooms\">Cafés & tea rooms\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.bapz.fr/contact\">Bapz\u003C/a> — Excellent pastries / hot beverages\u003C/li>\n\u003Cli>\u003Ca href=\"https://fr-fr.facebook.com/%C3%94-Th%C3%A9-Divin-245018828864405/\">Ô thé divin\u003C/a> — nice lunch options\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.lesreveriesdhercule.com/\">Les Rêveries d’Hercule\u003C/a> — Pottery Café, relaxing activity (ceramics need to be baked, there’ll be a delay to get them back)\u003C/li>\n\u003Cli>Bonus: the best bakeries in \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:450165912@Boulangerie_des_Carmes#map=16.37/43.6022638/1.4439872\">Carmes\u003C/a> and \u003Ca href=\"https://www.qwant.com/maps/place/osm:node:456844404@La_P%C3%A9trie#map=18.84/43.6045088/1.4544694\">Saint-Aubin\u003C/a> — croissants, baguettes \u003Cstrong>traditions\u003C/strong>, chocolatines and more\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"wine-shops\">Wine shops\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3861692629@LEnvie#map=19.57/43.5978194/1.4443930\">l’envie du sud\u003C/a> — amazing selection of wines and other spirits, excellent advice from the staff\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:3751077562@Enoteca_31#map=16.50/43.6045636/1.4531952\">enoteca\u003C/a> — smaller selection but more beers and great advice from the staff as well\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"other-delights\">Other delights\u003C/h2>\n\u003Ch3 id=\"ice-creams\">Ice creams\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2462248749@Caf%C3%A9t%C3%A9ria_Gelateria#map=20.00/43.6027626/1.4421450\">Forno gusto\u003C/a> — only in the summer\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:2165543146@Glaces_Moustache#map=16.50/43.6036985/1.4350540\">Moustache\u003C/a> — lots of flavours\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cheese-shop\">Cheese shop\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://xavier.fr/\">Xavier\u003C/a> — one of the \u003Cstrong>best of the country\u003C/strong>, two shops in Toulouse, including one at Victor Hugo market\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.qwant.com/maps/place/osm:node:6164095797@Massembea#map=16.50/43.6043930/1.4539490\">Massembea\u003C/a> — a serious contender in Toulouse (weird hours)\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"delicatessen\">Delicatessen\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Ca href=\"http://cafe-bacquie.com/\">Café Bacquié\u003C/a> — stock up on fine foods, coffees, teas and other great quality products\u003C/li>\n\u003C/ul>",{"headings":638,"imagePaths":675,"frontmatter":676},[639,642,645,648,651,654,657,660,663,666,669,672],{"depth":105,"slug":640,"text":641},"restaurants","Restaurants",{"depth":162,"slug":643,"text":644},"french-cuisine","French cuisine",{"depth":162,"slug":646,"text":647},"korean","Korean",{"depth":162,"slug":649,"text":650},"japanese","Japanese",{"depth":105,"slug":652,"text":653},"drinks-and-snacks","Drinks and snacks",{"depth":162,"slug":655,"text":656},"bars","Bars",{"depth":162,"slug":658,"text":659},"cafés--tea-rooms","Cafés & tea rooms",{"depth":162,"slug":661,"text":662},"wine-shops","Wine shops",{"depth":105,"slug":664,"text":665},"other-delights","Other delights",{"depth":162,"slug":667,"text":668},"ice-creams","Ice creams",{"depth":162,"slug":670,"text":671},"cheese-shop","Cheese shop",{"depth":162,"slug":673,"text":674},"delicatessen","Delicatessen",[],{"title":627,"subtitle":628,"lang":449,"slug":624,"excerpt":677,"tags":678,"type":607,"createdAt":355},"Gonna have to trust me on this ¯\\_(ツ)_/¯",[630],"en-visited-links",{"id":679,"data":681,"body":610,"filePath":685,"digest":686,"rendered":687},{"title":682,"subtitle":531,"lang":449,"tags":683,"type":607,"slug":679,"createdAt":684,"draft":292},"Visited links and visuel aid",[19],["Date","2023-06-06T18:34:00.000Z"],"src/content/fragments/en/visited-links.md","cb7c11c12c25067e",{"html":688,"metadata":689},"\u003Cp>\u003Ca href=\"/en/snippets\">Go back to available snippets\u003C/a>\u003C/p>",{"headings":690,"imagePaths":691,"frontmatter":692},[],[],{"title":682,"subtitle":531,"lang":449,"draft":292,"slug":679,"excerpt":693,"tags":694,"type":607,"createdAt":695},"Petit hack CSS",[19],"2023-06-06T18:34:00.000Z","array-vs-array",{"id":696,"data":698,"body":704,"filePath":705,"digest":706,"rendered":707},{"title":699,"subtitle":700,"lang":17,"tags":701,"type":599,"slug":696,"createdAt":703,"draft":292},"Filtrer un array avec un autre array","En cours de traduction.",[702],"nuxt.js",["Date","2022-06-08T14:24:06.000Z"],"[Voir les fragments disponibles](/fragments)","src/content/fragments/fr/array-vs-array.md","7321d444177c3841",{"html":708,"metadata":709},"\u003Cp>\u003Ca href=\"/fragments\">Voir les fragments disponibles\u003C/a>\u003C/p>",{"headings":710,"imagePaths":711,"frontmatter":712},[],[],{"title":699,"subtitle":700,"lang":17,"draft":292,"slug":696,"createdAt":250,"excerpt":700,"tags":713,"type":599},[702],"buttons",{"id":714,"data":716,"body":721,"filePath":722,"digest":723,"deferredRender":292},{"title":717,"subtitle":718,"lang":17,"tags":719,"type":599,"slug":714,"createdAt":720,"code":292,"draft":292},"Effets de survol de boutons","Simples mais efficaces.",[606],["Date","2020-10-08T09:00:00.000Z"],"## Styles généraux\n\nTous les boutons présents utilisent ces styles comme base en guise de « reset » :\n\n> N'oubliez pas de préfixer si besoin !\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Ajout d'icône\n\n\u003Cbutton role='none' class='btn btn-icon'>\n\t\u003Cspan>Icône\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('./assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double volet\n\n\u003Cbutton role='none' class='btn btn-rideau'>\n\t\u003Cspan>Volet\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Dégradé animé\n\n\u003Cbutton role='none' class='btn btn-gradient'>\n\t\u003Cspan>Dégradé\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Échelle non desctructrice\n\n\u003Cbutton role='none' class='btn btn-scale'>\n\t\u003Cspan>Échelle\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/fr/buttons.mdx","f5d7b03520f96b04","image-full",{"id":724,"data":726,"body":732,"filePath":733,"digest":734,"deferredRender":292},{"title":727,"subtitle":728,"lang":17,"tags":729,"type":599,"slug":724,"createdAt":730,"updatedAt":731},"Image pleine largeur","Casser le conteneur.",[606],["Date","2020-09-15T09:00:00.000Z"],["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Image inline\n\nOn est parfois obligé d'utiliser des images dans des balises `img` plutôt que dans un `background` en css. Comment faire alors pour que l'image sorte de son conteneur pour en faire une bannière ? Exemple pratique à partir de ce même site.\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_container_9e3939b3ae.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Contexte\n\nConsidérons le html suivant :\n\n```html\n\u003C!-- index.html -->\n\u003Csection class=\"container\">\n\t\u003Cdiv class=\"hero\">\n\t\t\u003Cimg class=\"hero__image\" src=\"hero.img\" />\n\t\u003C/div>\n\u003C/section>\n```\n\nEt le style suivant :\n\n```css\n/* style.css */\n.container {\n\tpadding: 0 14px;\n\tmargin-inline: auto;\n\tmax-inline-size: 1040px;\n}\nimg {\n\tmax-inline-size: 100%;\n\tblock-size: auto;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_original_d49f0d11bf.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Déborder du conteneur\n\nAfin de faire prendre à l'image toute la largeur, on agit sur son conteneur :\n\n```css\n/* style.css */\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_full_2a902f9539.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\n### Faire une bannière\n\nOn peut alors réduire la hauteur du conteneur pour obtenir une bannière plutôt que l'image entière et faire correspondre la hauteur de l'image à la hauteur du conteneur :\n\n```css title='style.css' ins={5, 7-9}\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n\tblock-size: 200px;\n}\n.hero__image {\n\tblock-size: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_height_81b4ce969a.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nIl faut ensuite forcer l'image à prendre toute la largeur du conteneur :\n\n```css title='style.css' ins={3}\n.hero__image {\n\tblock-size: 100%;\n\tinline-size: 100%;\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_deformed_479046d2cb.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nPas top…\n\n### J'ai cassé l'image…\n\n**ENFIN** le code magique pour redonner son ratio à l'image sans la déformer :\n\n```css title='style.css' ins={4,5}\n.hero__image {\n\tblock-size: 100%;\n\tinline-size: 100%;\n\tobject-fit: cover;\n\tobject-position: center; /* à positionner comme on veut */\n}\n```\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/image_bleed_6c164e82b3.jpeg'\n\twidth='320'\n\theight='568'\n/>\n\nCette technique s'apparente à l'utilisation d'une image de background.\n\n## TL;DR\n\nLe code complet :\n\n```css\n/* style.css */\n.hero {\n\tmargin-inline-start: calc(50% - 50vw);\n\tposition: relative;\n\tinline-size: 100vw;\n\tblock-size: 200px;\n}\n.hero__image {\n\tinline-size: 100%;\n\tblock-size: 100%;\n\t-o-object-fit: cover;\n\tobject-fit: cover;\n\t-o-object-position: center;\n\tobject-position: center;\n}\n```","src/content/fragments/fr/image-full.mdx","585dcfae92fb08fb","super-cookies",{"id":735,"data":737,"body":743,"filePath":744,"digest":745,"deferredRender":292},{"title":738,"subtitle":739,"lang":17,"tags":740,"type":599,"slug":735,"createdAt":742},"Les meilleurs cookies","Des gâteaux sans consentement.",[741],"cuisine",["Date","2022-06-08T14:24:06.000Z"],"import AstroImage from '../../../components/AstroImage.astro'\n\n## Version végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 3/4 de l'aquafaba de 400g de pois chiche (l'eau des pois chiche)\n- 125 grammes d'huile de noix de coco\n- 2 cuillères à café de sirop d'érable\n- 1 plaquette de chocolat (noir) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre si besoin l'huile de noix de coco à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (huile, aquafaba, sirop d'érable)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Version non végétalienne\n\n### Ingrédients\n\n- 250 grammes de farine\n- 70 grammes de sucre muscovado/vergeoise (non raffiné)\n- 20 grammes de cassonade\n- 1 pincée de sel\n- 1 cuillère à soupe de levure\n- 1 œuf\n- 125 grammes de beurre fondu\n- 2 cuillères à café de miel\n- 1 plaquette de chocolat (noir/blanc/les deux) coupée en “ chunks ”\n\n### Méthode\n\n- faire fondre le beurre à feu doux\n- mélanger tous les ingrédients secs pendant ce temps\n- ajouter tous les ingrédients liquides (beurre fondu, œuf, miel)\n- bien mélanger\n- ajouter le chocolat\n- bien mélanger (fig. 1)\n\n### Cuisson\n\nRéaliser des boules avec la mixture obtenue sur une plaque de cuisson.\nCuire 9 minutes à 210 degrés (celsius) - chaleur tournante (fig. 2).\n\n## Notes\n\nLe chocolat peut-être remplacé par n'importe quoi comme des noix, des raisins secs, des légos… (mangez pas des légos soyez sérieux).\n\n## Figures\n\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-1.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Tous les ingrédients mélangés forment une pâte marron.'\n/>\n\u003CAstroImage\n\tsrc='https://assets.nardu.in/cookies-fig-2.jpg'\n\twidth='753'\n\theight='1248'\n\talt='Les cookies cuits sont bombés et très moelleux.'\n/>","src/content/fragments/fr/super-cookies.mdx","f7a802e0b68cb04a","toulouse-fun",{"id":746,"data":748,"body":704,"filePath":751,"digest":752,"rendered":753},{"title":627,"subtitle":700,"lang":17,"tags":749,"type":599,"slug":746,"createdAt":750,"draft":292},[630],["Date","2022-06-22T15:34:45.000Z"],"src/content/fragments/fr/toulouse-fun.md","a0c25b438b34c05e",{"html":708,"metadata":754},{"headings":755,"imagePaths":756,"frontmatter":757},[],[],{"title":627,"subtitle":700,"lang":17,"draft":292,"slug":746,"createdAt":355,"excerpt":700,"tags":758,"type":599},[630],"visited-links",{"id":759,"data":761,"body":767,"filePath":768,"digest":769,"rendered":770},{"title":762,"subtitle":763,"lang":17,"tags":764,"type":607,"slug":759,"createdAt":765,"draft":766},"Liens visités et indication visuelle","Comment différencier les liens déjà cliqués",[19],["Date","2023-06-06T18:34:00.000Z"],false,"## La théorie\n\nIl est possible sur le web d'appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu'un lien visité est violet.\n\nGénéralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L'information qu'un lien a déjà été visité ne semble pas indispensable à la navigation. C'est sûrement vrai, mais personnellement, je suis assez content d'avoir un rappel des pages que j'ai déjà consultées lorsque je navigue.\n\nUne information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J'ai alors cherché un moyen d'ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n'est certainement pas idéale, elle se rapproche plus d'une expérience, à priori inoffensive pour l'internaute.\n\n## La spécification\n\nQuand je me suis intéressé à ce qu'il était possible de faire avec les liens déjà visités, j'ai découvert qu'extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu'il était possible de récupérer l'historique de navigation d'un utilisateur grâce aux styles des liens visités. Le sélecteur `:visited` a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. [Plus d'informations dans cet article.](https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector)\n\n## La pratique\n\nQue faire alors, en terme de style, quand on ne peut changer que des couleurs ?\n\nD'après MDN, les propriétés suivantes sont modifiables :\n\n- `color`\n- `background-color`\n- `border-color` (et les propriétés détaillées associées),\n- `column-rule-color`\n- `outline-color`\n- `text-decoration-color`\n- `text-emphasis-color`\n- Les composantes de couleur liées aux attributs SVG `fill` et `stroke`.\n\nChanger la couleur d'un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\n\nEn revanche, il est possible de \" masquer \" un élément en modifiant sa couleur pour qu'elle corresponde à la couleur du fond de la page ou de l'élément parent. On pourrait ainsi imaginer masquer une `border` ou un `outline`.\n\nJ'ai personnellement choisi de faire différemment. J'ai décidé d'utiliser un pseudo-élément `::before` sur l'état non visité du lien puis de le masquer quand celui-ci devient visité.\n\n### Le code\n\n```css {5,16} title=\"style.css\"\na {\n\tposition: relative;\n\ttext-decoration: none;\n}\na::before {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 0;\n\tinline-size: 2px;\n\tblock-size: 2px;\n\tborder-radius: 4px;\n\ttransform: translate(-6px, 0);\n\tbackground-color: grey;\n}\na:visited::before {\n\tbackground-color: white;\n}\n```\n\nCes règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\n\n### Accessibilité\n\nOn pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété `content` mais les lecteurs d'écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d'écrans annoncent déjà si un lien est visité avant de lire son intitulé.\n\n## Aller plus loin\n\nAfin de pousser l'expérience un peu plus loin, j'ai tenté d'utiliser des éléments plus explicites pour signifier l'état visité du lien. Bien qu'encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\n\nL'idée est d'avoir un `::before` et un `::after`, chacun contenant une icône en base 64 blanche en tant qu'image de fond. Quand le lien est non visité, le `::before` contient un fond coloré qui fait apparaître l'icône. Quand le lien passe en visité, le fond du `::before` devient blanc et celui du `::after` devient coloré, ce qui masque la première icône et affiche la deuxième.\n\nIl est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l'une sur l'autre.\n\n[Voir la démo sur codepen.](https://codepen.io/narduin/pen/VwVwmrO)","src/content/fragments/fr/visited-links.md","c062a565e4c30dfe",{"html":771,"metadata":772},"\u003Ch2 id=\"la-théorie\">La théorie\u003C/h2>\n\u003Cp>Il est possible sur le web d’appliquer un style différent aux liens déjà visités par un utilisateur. Par défaut, un lien non visité est bleu tandis qu’un lien visité est violet.\u003C/p>\n\u003Cp>Généralement, ces styles sont modifiés, voire supprimés dans le cas des liens visités. L’information qu’un lien a déjà été visité ne semble pas indispensable à la navigation. C’est sûrement vrai, mais personnellement, je suis assez content d’avoir un rappel des pages que j’ai déjà consultées lorsque je navigue.\u003C/p>\n\u003Cp>Une information uniquement communiquée par la couleur est faillible, car certaines personnes ne distinguent pas les couleurs correctement. J’ai alors cherché un moyen d’ajouter un élément graphique supplémentaire aux liens visités/non visités. La solution démontrée ici n’est certainement pas idéale, elle se rapproche plus d’une expérience, à priori inoffensive pour l’internaute.\u003C/p>\n\u003Ch2 id=\"la-spécification\">La spécification\u003C/h2>\n\u003Cp>Quand je me suis intéressé à ce qu’il était possible de faire avec les liens déjà visités, j’ai découvert qu’extrêmement peu de propriétés \u003Cabbr>CSS\u003C/abbr> étaient autorisées. En effet, seulement des changements de couleurs sont disponibles. Ceci est dû au fait qu’il était possible de récupérer l’historique de navigation d’un utilisateur grâce aux styles des liens visités. Le sélecteur \u003Ccode>:visited\u003C/code> a donc été restreint par les navigateurs afin de lutter contre cette brèche de la vie privée. \u003Ca href=\"https://developer.mozilla.org/fr/docs/Web/CSS/Privacy_and_the_:visited_selector\">Plus d’informations dans cet article.\u003C/a>\u003C/p>\n\u003Ch2 id=\"la-pratique\">La pratique\u003C/h2>\n\u003Cp>Que faire alors, en terme de style, quand on ne peut changer que des couleurs ?\u003C/p>\n\u003Cp>D’après MDN, les propriétés suivantes sont modifiables :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>background-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>border-color\u003C/code> (et les propriétés détaillées associées),\u003C/li>\n\u003Cli>\u003Ccode>column-rule-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>outline-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-decoration-color\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode>text-emphasis-color\u003C/code>\u003C/li>\n\u003Cli>Les composantes de couleur liées aux attributs SVG \u003Ccode>fill\u003C/code> et \u003Ccode>stroke\u003C/code>.\u003C/li>\n\u003C/ul>\n\u003Cp>Changer la couleur d’un lien visité ne sera pas compris par les internautes, à moins de garder une colorimétrie proche de celle par défaut (bleu et violet).\u003C/p>\n\u003Cp>En revanche, il est possible de ” masquer ” un élément en modifiant sa couleur pour qu’elle corresponde à la couleur du fond de la page ou de l’élément parent. On pourrait ainsi imaginer masquer une \u003Ccode>border\u003C/code> ou un \u003Ccode>outline\u003C/code>.\u003C/p>\n\u003Cp>J’ai personnellement choisi de faire différemment. J’ai décidé d’utiliser un pseudo-élément \u003Ccode>::before\u003C/code> sur l’état non visité du lien puis de le masquer quand celui-ci devient visité.\u003C/p>\n\u003Ch3 id=\"le-code\">Le code\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.642km.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">style.css\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">relative\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-decoration: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line highlight mark\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#eca3a8\">a\u003C/span>\u003Cspan style=\"--0:#73c3cc\">::before\u003C/span>\u003Cspan style=\"--0:#b0b6c3\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">inline-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">block-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">4\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-6\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: grey;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line highlight mark\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#eca3a8\">a\u003C/span>\u003Cspan style=\"--0:#73c3cc\">:visited::before\u003C/span>\u003Cspan style=\"--0:#b0b6c3\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"a { position: relative; text-decoration: none;}a::before { content: ''; position: absolute; top: 50%; left: 0; inline-size: 2px; block-size: 2px; border-radius: 4px; transform: translate(-6px, 0); background-color: grey;}a:visited::before { background-color: white;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Ces règles, utilisées dans la table des matières de mes articles, ajoutent une sorte de petite puce ou pastille au début du lien. Cette puce est ensuite passée en blanc sur fond blanc une fois que le lien est visité, ce qui la masque visuellement.\u003C/p>\n\u003Ch3 id=\"accessibilité\">Accessibilité\u003C/h3>\n\u003Cp>On pourrait simplifier la règle et utiliser le caractère de puce directement dans la propriété \u003Ccode>content\u003C/code> mais les lecteurs d’écran annonceront alors ce caractère lors de leur retranscription du lien. De plus, les lecteurs d’écrans annoncent déjà si un lien est visité avant de lire son intitulé.\u003C/p>\n\u003Ch2 id=\"aller-plus-loin\">Aller plus loin\u003C/h2>\n\u003Cp>Afin de pousser l’expérience un peu plus loin, j’ai tenté d’utiliser des éléments plus explicites pour signifier l’état visité du lien. Bien qu’encore assez imparfait, il est possible de créer un indicateur plus complet de lien visité.\u003C/p>\n\u003Cp>L’idée est d’avoir un \u003Ccode>::before\u003C/code> et un \u003Ccode>::after\u003C/code>, chacun contenant une icône en base 64 blanche en tant qu’image de fond. Quand le lien est non visité, le \u003Ccode>::before\u003C/code> contient un fond coloré qui fait apparaître l’icône. Quand le lien passe en visité, le fond du \u003Ccode>::before\u003C/code> devient blanc et celui du \u003Ccode>::after\u003C/code> devient coloré, ce qui masque la première icône et affiche la deuxième.\u003C/p>\n\u003Cp>Il est nécessaire de positionner les icônes côte à côte sinon elles se retrouveront l’une sur l’autre.\u003C/p>\n\u003Cp>\u003Ca href=\"https://codepen.io/narduin/pen/VwVwmrO\">Voir la démo sur codepen.\u003C/a>\u003C/p>",{"headings":773,"imagePaths":791,"frontmatter":792},[774,777,780,783,786,788],{"depth":105,"slug":775,"text":776},"la-théorie","La théorie",{"depth":105,"slug":778,"text":779},"la-spécification","La spécification",{"depth":105,"slug":781,"text":782},"la-pratique","La pratique",{"depth":162,"slug":784,"text":785},"le-code","Le code",{"depth":162,"slug":20,"text":787},"Accessibilité",{"depth":105,"slug":789,"text":790},"aller-plus-loin","Aller plus loin",[],{"title":762,"subtitle":763,"lang":17,"draft":766,"slug":759,"excerpt":693,"tags":793,"type":607,"createdAt":695},[19],"en-array-vs-array",{"id":794,"data":796,"body":801,"filePath":802,"digest":803,"rendered":804},{"title":797,"subtitle":798,"lang":449,"tags":799,"type":607,"slug":794,"createdAt":800},"Filter an array against another array","Array vs Array.",[702],["Date","2022-06-08T14:24:06.000Z"],"## Context\n\nFor a project, I had to come up with a way to filter an array of objects based on another array of strings.\n\nIn other words, I needed to include every object which `user` property was found in the second array.\n\nHere is an example:\n\n```javascript\nconst skills = [\n\t{\n\t\tname: 'Be awesome',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Great jokes',\n\t\tuser: 'Jacques'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Jean'\n\t},\n\t{\n\t\tname: 'Heavy sleeper',\n\t\tuser: 'Beatriz'\n\t}\n]\n\nconst selectedUsers = ['Jean', 'Beatriz']\n```\n\nI thought it would be pretty easy but I guess I'm not familiar enough with javascript 😬\n\n## My solution\n\nAfter a bit of thinking, I came up with the following statement:\n\n> I need to filter the skills based on which users are selected. So I need to loop over the `selectedUsers` array and filter the skills according to their `user` value.\n\nAfter a bit more trials and errors, this is the code I ended up using in a `computed property`:\n\n```javascript\n// index.vue\nconst filteredSkills = selectedUsers.map((user) => {\n\treturn skills.filter((skill) => {\n\t\treturn skill.user === user\n\t})\n})\n```\n\nI used `map()` in order to loop on the second array and used its string value to only include the corresponding skills with `filter()`.\n\nI'm pretty sure there is a better way to do it though…","src/content/fragments/en/array-vs-array.md","c63ba57b1049cf4c",{"html":805,"metadata":806},"\u003Ch2 id=\"context\">Context\u003C/h2>\n\u003Cp>For a project, I had to come up with a way to filter an array of objects based on another array of strings.\u003C/p>\n\u003Cp>In other words, I needed to include every object which \u003Ccode>user\u003C/code> property was found in the second array.\u003C/p>\n\u003Cp>Here is an example:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.642km.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Be awesome'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Great jokes'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jacques'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">name\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Heavy sleeper'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Beatriz'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">selectedUsers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> [\u003C/span>\u003Cspan style=\"--0:#98C379\">'Jean'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#98C379\">'Beatriz'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const skills = [ { name: 'Be awesome', user: 'Jean' }, { name: 'Great jokes', user: 'Jacques' }, { name: 'Heavy sleeper', user: 'Jean' }, { name: 'Heavy sleeper', user: 'Beatriz' }]const selectedUsers = ['Jean', 'Beatriz']\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>I thought it would be pretty easy but I guess I’m not familiar enough with javascript 😬\u003C/p>\n\u003Ch2 id=\"my-solution\">My solution\u003C/h2>\n\u003Cp>After a bit of thinking, I came up with the following statement:\u003C/p>\n\u003Cblockquote>\n\u003Cp>I need to filter the skills based on which users are selected. So I need to loop over the \u003Ccode>selectedUsers\u003C/code> array and filter the skills according to their \u003Ccode>user\u003C/code> value.\u003C/p>\n\u003C/blockquote>\n\u003Cp>After a bit more trials and errors, this is the code I ended up using in a \u003Ccode>computed property\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">filteredSkills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">selectedUsers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">map\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">((\u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) \u003C/span>\u003Cspan style=\"--0:#CD89E1\">=>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skills\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">filter\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">((\u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">skill\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) \u003C/span>\u003Cspan style=\"--0:#CD89E1\">=>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">skill\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">===\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">user\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const filteredSkills = selectedUsers.map((user) => { return skills.filter((skill) => { return skill.user === user })})\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>I used \u003Ccode>map()\u003C/code> in order to loop on the second array and used its string value to only include the corresponding skills with \u003Ccode>filter()\u003C/code>.\u003C/p>\n\u003Cp>I’m pretty sure there is a better way to do it though…\u003C/p>",{"headings":807,"imagePaths":814,"frontmatter":815},[808,811],{"depth":105,"slug":809,"text":810},"context","Context",{"depth":105,"slug":812,"text":813},"my-solution","My solution",[],{"title":797,"subtitle":798,"lang":449,"slug":794,"createdAt":250,"excerpt":816,"tags":817,"type":607},"My peak javascript",[702],"en-nuxt-graphql-static",{"id":818,"data":820,"body":826,"filePath":827,"digest":828,"rendered":829},{"title":821,"subtitle":822,"lang":449,"tags":823,"type":607,"slug":818,"createdAt":824,"updatedAt":825},"Static website and GraphQL queries with Nuxt.js","Graphql client is king.",[702],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## The problem\n\nI encountered a nasty bug while using static generation with Nuxt and [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (new tab)') client.\nI found [the issue](https://github.com/nuxt-community/apollo-module/issues/339 'Github issue on nuxt/apollo repository (new tab)') already reported on github.\n\nIt seems the module doesn't handle static generation correctly with `nuxt generate`.\n\nI could find request to my local API url after the static generation. Moreover, it also seemed like `\u003Cnuxt-link>` navigation was broken.\n\n## The solution 🙌\n\nFortunately, there is another Nuxt module that handles GraphQL requests!\n\n[Nuxt graphql request to the rescue!](https://github.com/gomah/nuxt-graphql-request)\n\n### The conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### The request\n\nThe best approach so far is to use `asyncData` in pages and `fetch` in components. Using `fetch` in pages does not work well at all with `nuxt generate`.\n\nI also install the `graphql-tag` package (only in `devDependencies`) to be able to import directly `.gql` files.\n\nQuery example:\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Inside a page\n\n```vue\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n\tasync asyncData({ $graphql }) {\n\t\tconst data = await $graphql.default.request(homepageQuery)\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```\n\n#### Inside a component\n\nIt is safer to wait until `fetch` has received a response before displaying anything. You can use `$fetchState` to be sure ([documentation](https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation on the fetch hook (new tab)')).\n\n```vue\n// Header.vue\n\u003Ctemplate>\n\t\u003Cheader v-if=\"!$fetchState.pending\">…\u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tdata: {}\n\t\t}\n\t},\n\tasync fetch() {\n\t\ttry {\n\t\t\tconst data = await this.$graphql.default.request(headerQuery)\n\t\t\tthis.data = data\n\t\t} catch (error) {\n\t\t\tconsole.error(JSON.stringify(error, undefined, 2))\n\t\t}\n\t}\n}\n\u003C/script>\n```\n\n### Options\n\nTo pass options to the request, for example for a multilingual version with [nuxt/i18n](https://i18n.nuxtjs.org/) and/or a url parameter in a dynamic page:\n\n```vue\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n\tasync asyncData({ $graphql, app, params }) {\n\t\tconst locale = app.i18n.localeProperties.iso\n\t\tconst data = await $graphql.default.request(articleQuery, {\n\t\t\tcode: locale,\n\t\t\tslug: params.slug\n\t\t})\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```","src/content/fragments/en/nuxt-graphql-static.md","c5d4f0dd6ca0e1c2",{"html":830,"metadata":831},"\u003Ch2 id=\"the-problem\">The problem\u003C/h2>\n\u003Cp>I encountered a nasty bug while using static generation with Nuxt and \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (new tab)\">nuxt apollo\u003C/a> client.\nI found \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Github issue on nuxt/apollo repository (new tab)\">the issue\u003C/a> already reported on github.\u003C/p>\n\u003Cp>It seems the module doesn’t handle static generation correctly with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I could find request to my local API url after the static generation. Moreover, it also seemed like \u003Ccode><nuxt-link>\u003C/code> navigation was broken.\u003C/p>\n\u003Ch2 id=\"the-solution\">The solution 🙌\u003C/h2>\n\u003Cp>Fortunately, there is another Nuxt module that handles GraphQL requests!\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\">Nuxt graphql request to the rescue!\u003C/a>\u003C/p>\n\u003Ch3 id=\"the-conf\">The conf\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.642km.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">nuxt.config.js\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">buildModules\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">clients\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">endpoint\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">options\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">authorization\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"buildModules: [ 'nuxt-graphql-request',],graphql: { clients: { default: { endpoint: 'http://API_URL/graphql', options: { headers: { authorization: 'Bearer API_TOKEN', }, }, }, },},\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"the-request\">The request\u003C/h3>\n\u003Cp>The best approach so far is to use \u003Ccode>asyncData\u003C/code> in pages and \u003Ccode>fetch\u003C/code> in components. Using \u003Ccode>fetch\u003C/code> in pages does not work well at all with \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>I also install the \u003Ccode>graphql-tag\u003C/code> package (only in \u003Ccode>devDependencies\u003C/code>) to be able to import directly \u003Ccode>.gql\u003C/code> files.\u003C/p>\n\u003Cp>Query example:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">homepage.gql\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"graphql\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">query\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepage\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">subtitle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">hero\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">id\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">alt\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"query { homepage { title subtitle hero { id alt } }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"inside-a-page\">Inside a page\u003C/h4>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/homepage'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import homepageQuery from '~/graphql/queries/singles/homepage'export default { async asyncData({ $graphql }) { const data = await $graphql.default.request(homepageQuery) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"inside-a-component\">Inside a component\u003C/h4>\n\u003Cp>It is safer to wait until \u003Ccode>fetch\u003C/code> has received a response before displaying anything. You can use \u003Ccode>$fetchState\u003C/code> to be sure (\u003Ca href=\"https://nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation on the fetch hook (new tab)\">documentation\u003C/a>).\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">Header.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">v-if\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#56B6C2\">!\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$fetchState\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">pending\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>…</\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/header'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">fetch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">try\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">} \u003C/span>\u003Cspan style=\"--0:#CD89E1\">catch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> (\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">console\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E5C07B\">JSON\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">stringify\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">undefined\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">))\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ctemplate> \u003Cheader v-if="!$fetchState.pending">…\u003C/header>\u003C/template>\u003Cscript>import headerQuery from '~/graphql/queries/singles/header'export default { data() { return { data: {} } }, async fetch() { try { const data = await this.$graphql.default.request(headerQuery) this.data = data } catch (error) { console.error(JSON.stringify(error, undefined, 2)) } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"options\">Options\u003C/h3>\n\u003Cp>To pass options to the request, for example for a multilingual version with \u003Ca href=\"https://i18n.nuxtjs.org/\">nuxt/i18n\u003C/a> and/or a url parameter in a dynamic page:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">_slug.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/articles'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">i18n\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">localeProperties\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">iso\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">code\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E6888F\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E5C07B\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import articleQuery from '~/graphql/queries/articles'export default { async asyncData({ $graphql, app, params }) { const locale = app.i18n.localeProperties.iso const data = await $graphql.default.request(articleQuery, { code: locale, slug: params.slug }) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":832,"imagePaths":855,"frontmatter":856},[833,836,839,842,845,849,852],{"depth":105,"slug":834,"text":835},"the-problem","The problem",{"depth":105,"slug":837,"text":838},"the-solution","The solution 🙌",{"depth":162,"slug":840,"text":841},"the-conf","The conf",{"depth":162,"slug":843,"text":844},"the-request","The request",{"depth":846,"slug":847,"text":848},4,"inside-a-page","Inside a page",{"depth":846,"slug":850,"text":851},"inside-a-component","Inside a component",{"depth":162,"slug":853,"text":854},"options","Options",[],{"title":821,"subtitle":822,"lang":449,"slug":818,"createdAt":250,"updatedAt":857,"excerpt":858,"tags":859,"type":607},"2022-09-08T13:43:33.000Z","When the most used gql module doesn't work…",[702],"nuxt-graphql-static",{"id":860,"data":862,"body":868,"filePath":869,"digest":870,"rendered":871},{"title":863,"subtitle":864,"lang":17,"tags":865,"type":599,"slug":860,"createdAt":866,"updatedAt":867},"Site statique et requêtes GraphQL avec Nuxt.js","Le client graphql est roi.",[702],["Date","2022-06-08T14:24:06.000Z"],["Date","2022-09-08T13:43:33.000Z"],"## Le problème\n\nJe me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client [nuxt apollo](https://github.com/nuxt-community/apollo-module 'Dépôt github du module nuxt apollo (nouvel onglet)').\nAprès quelques recherches, voici [le bug constaté par quelqu'un d'autre](https://github.com/nuxt-community/apollo-module/issues/339 'Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)') sur github.\n\nIl semblerait que le module en l'état ne gère pas correctement la génération statique avec `nuxt generate`.\n\nJe trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les `\u003Cnuxt-link>` ne fonctionnait pas.\n\n## La solution 🙌\n\nHeureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\n\n[Nuxt graphql request à la rescousse !](https://github.com/gomah/nuxt-graphql-request 'Dépôt github du module (nouvel onglet)')\n\n### La conf\n\n```javascript\n// nuxt.config.js\nbuildModules: [\n 'nuxt-graphql-request',\n],\ngraphql: {\n clients: {\n default: {\n endpoint: 'http://API_URL/graphql',\n options: {\n headers: {\n authorization: 'Bearer API_TOKEN',\n },\n },\n },\n },\n},\n```\n\n### La requête\n\nLa meilleure méthode à ce jour est d'utiliser `asyncData` dans les pages et `fetch` dans les composants. Utiliser `fetch` dans les pages ne fonctionne pas bien du tout avec `nuxt generate`.\n\nJ'installe également le paquet `graphql-tag` (uniquement en `devDependencies`) afin de pouvoir importer directement des fichiers `.gql`\n\nExemple de fichier :\n\n```graphql\n# homepage.gql\nquery {\n\thomepage {\n\t\ttitle\n\t\tsubtitle\n\t\thero {\n\t\t\tid\n\t\t\talt\n\t\t}\n\t}\n}\n```\n\n#### Dans une page\n\n```vue\n// index.vue\n\u003Cscript>\nimport homepageQuery from '~/graphql/queries/singles/homepage'\n\nexport default {\n\tasync asyncData({ $graphql }) {\n\t\tconst data = await $graphql.default.request(homepageQuery)\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```\n\n#### Dans un composant\n\nIl est plus prudent d'attendre que `fetch` ait reçu une réponse avant d'afficher quoi que ce soit. On peut utiliser `$fetchState` afin d'être tranquille ([documentation](https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch 'Documentation sur la méthode fetch (nouvel onglet)')).\n\n```vue\n// Header.vue\n\u003Ctemplate>\n\t\u003Cheader v-if=\"!$fetchState.pending\">…\u003C/header>\n\u003C/template>\n\n\u003Cscript>\nimport headerQuery from '~/graphql/queries/singles/header'\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tdata: {}\n\t\t}\n\t},\n\tasync fetch() {\n\t\ttry {\n\t\t\tconst data = await this.$graphql.default.request(headerQuery)\n\t\t\tthis.data = data\n\t\t} catch (error) {\n\t\t\tconsole.error(JSON.stringify(error, undefined, 2))\n\t\t}\n\t}\n}\n\u003C/script>\n```\n\n### Les options\n\nPour passer des options à la requête, par exemple pour une version multilingue avec [nuxt/i18n](https://i18n.nuxtjs.org/ 'Documentation de nuxt i18n (nouvel onglet)') et/ou un paramètre d'url dans le cadre d'une page dynamique :\n\n```vue\n// _slug.vue\n\u003Cscript>\nimport articleQuery from '~/graphql/queries/articles'\n\nexport default {\n\tasync asyncData({ $graphql, app, params }) {\n\t\tconst locale = app.i18n.localeProperties.iso\n\t\tconst data = await $graphql.default.request(articleQuery, {\n\t\t\tcode: locale,\n\t\t\tslug: params.slug\n\t\t})\n\t\treturn { data }\n\t}\n}\n\u003C/script>\n```","src/content/fragments/fr/nuxt-graphql-static.md","6304f174b83f0078",{"html":872,"metadata":873},"\u003Ch2 id=\"le-problème\">Le problème\u003C/h2>\n\u003Cp>Je me suis heurté à un villain bug en utilisant Nuxt en mode génération statique complète et le client \u003Ca href=\"https://github.com/nuxt-community/apollo-module\" title=\"Dépôt github du module nuxt apollo (nouvel onglet)\">nuxt apollo\u003C/a>.\nAprès quelques recherches, voici \u003Ca href=\"https://github.com/nuxt-community/apollo-module/issues/339\" title=\"Bug visible sur le dépôt github du module nuxt/apollo (nouvel onglet)\">le bug constaté par quelqu’un d’autre\u003C/a> sur github.\u003C/p>\n\u003Cp>Il semblerait que le module en l’état ne gère pas correctement la génération statique avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>Je trouvais toujours des appels à mon API locale après la génération statique et la navigation depuis les \u003Ccode><nuxt-link>\u003C/code> ne fonctionnait pas.\u003C/p>\n\u003Ch2 id=\"la-solution\">La solution 🙌\u003C/h2>\n\u003Cp>Heureusement, il existe un autre module Nuxt pour gérer les requêtes GraphQL !\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/gomah/nuxt-graphql-request\" title=\"Dépôt github du module (nouvel onglet)\">Nuxt graphql request à la rescousse !\u003C/a>\u003C/p>\n\u003Ch3 id=\"la-conf\">La conf\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.642km.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">nuxt.config.js\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">buildModules\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'nuxt-graphql-request'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">clients\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">endpoint\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'http://API_URL/graphql'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">options\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headers\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">authorization\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#98C379\">'Bearer API_TOKEN'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"buildModules: [ 'nuxt-graphql-request',],graphql: { clients: { default: { endpoint: 'http://API_URL/graphql', options: { headers: { authorization: 'Bearer API_TOKEN', }, }, }, },},\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"la-requête\">La requête\u003C/h3>\n\u003Cp>La meilleure méthode à ce jour est d’utiliser \u003Ccode>asyncData\u003C/code> dans les pages et \u003Ccode>fetch\u003C/code> dans les composants. Utiliser \u003Ccode>fetch\u003C/code> dans les pages ne fonctionne pas bien du tout avec \u003Ccode>nuxt generate\u003C/code>.\u003C/p>\n\u003Cp>J’installe également le paquet \u003Ccode>graphql-tag\u003C/code> (uniquement en \u003Ccode>devDependencies\u003C/code>) afin de pouvoir importer directement des fichiers \u003Ccode>.gql\u003C/code>\u003C/p>\n\u003Cp>Exemple de fichier :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">homepage.gql\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"graphql\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">query\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepage\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">subtitle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">hero\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">id\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">alt\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"query { homepage { title subtitle hero { id alt } }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"dans-une-page\">Dans une page\u003C/h4>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">index.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/homepage'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">homepageQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import homepageQuery from '~/graphql/queries/singles/homepage'export default { async asyncData({ $graphql }) { const data = await $graphql.default.request(homepageQuery) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch4 id=\"dans-un-composant\">Dans un composant\u003C/h4>\n\u003Cp>Il est plus prudent d’attendre que \u003Ccode>fetch\u003C/code> ait reçu une réponse avant d’afficher quoi que ce soit. On peut utiliser \u003Ccode>$fetchState\u003C/code> afin d’être tranquille (\u003Ca href=\"https://fr.nuxtjs.org/docs/2.x/components-glossary/pages-fetch\" title=\"Documentation sur la méthode fetch (nouvel onglet)\">documentation\u003C/a>).\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">Header.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">v-if\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#56B6C2\">!\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$fetchState\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">pending\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">\"\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>…</\u003C/span>\u003Cspan style=\"--0:#E6888F\">header\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">template\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/singles/header'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: {}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">fetch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">try\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">headerQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">this\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">} \u003C/span>\u003Cspan style=\"--0:#CD89E1\">catch\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> (\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">console\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E5C07B\">JSON\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">stringify\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">error\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">undefined\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">))\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ctemplate> \u003Cheader v-if="!$fetchState.pending">…\u003C/header>\u003C/template>\u003Cscript>import headerQuery from '~/graphql/queries/singles/header'export default { data() { return { data: {} } }, async fetch() { try { const data = await this.$graphql.default.request(headerQuery) this.data = data } catch (error) { console.error(JSON.stringify(error, undefined, 2)) } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"les-options\">Les options\u003C/h3>\n\u003Cp>Pour passer des options à la requête, par exemple pour une version multilingue avec \u003Ca href=\"https://i18n.nuxtjs.org/\" title=\"Documentation de nuxt i18n (nouvel onglet)\">nuxt/i18n\u003C/a> et/ou un paramètre d’url dans le cadre d’une page dynamique :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">_slug.vue\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"vue\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"><\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">import\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">from\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'~/graphql/queries/articles'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">async\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#61AFEF\">asyncData\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">({ \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">app\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">i18n\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">localeProperties\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">iso\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">const\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">await\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E5C07B\">$graphql\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E5C07B\">default\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#61AFEF\">request\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#E6888F\">articleQuery\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">code\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E6888F\">locale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#E5C07B\">params\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">.\u003C/span>\u003Cspan style=\"--0:#E6888F\">slug\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#CD89E1\">return\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> { \u003C/span>\u003Cspan style=\"--0:#E6888F\">data\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\"></\u003C/span>\u003Cspan style=\"--0:#E6888F\">script\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript>import articleQuery from '~/graphql/queries/articles'export default { async asyncData({ $graphql, app, params }) { const locale = app.i18n.localeProperties.iso const data = await $graphql.default.request(articleQuery, { code: locale, slug: params.slug }) return { data } }}\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":874,"imagePaths":896,"frontmatter":897},[875,878,881,884,887,890,893],{"depth":105,"slug":876,"text":877},"le-problème","Le problème",{"depth":105,"slug":879,"text":880},"la-solution","La solution 🙌",{"depth":162,"slug":882,"text":883},"la-conf","La conf",{"depth":162,"slug":885,"text":886},"la-requête","La requête",{"depth":846,"slug":888,"text":889},"dans-une-page","Dans une page",{"depth":846,"slug":891,"text":892},"dans-un-composant","Dans un composant",{"depth":162,"slug":894,"text":895},"les-options","Les options",[],{"title":863,"subtitle":864,"lang":17,"slug":860,"createdAt":250,"updatedAt":857,"excerpt":898,"tags":899,"type":599},"Quand le module gql le plus utilisé ne fonctionne pas…",[702],"en-buttons",{"id":900,"data":902,"body":907,"filePath":908,"digest":909,"rendered":910},{"title":903,"subtitle":904,"lang":449,"tags":905,"type":607,"slug":900,"createdAt":906,"code":292,"draft":292},"Buttons hover","Simple, but nice.",[606],["Date","2020-10-08T09:00:00.000Z"],"## General rules\n\nAll the buttons use these styles as a “reset”:\n\n> Don't forget to prefix if necessary!\n\n```css\n.btn {\n\tmargin: 20px 0;\n\tpadding: 12px 26px;\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tfont-size: 20rem; /* 20px */\n\tline-height: 1.6;\n\ttext-align: center;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcursor: pointer;\n\tborder: none;\n\tborder-radius: 2px;\n\t-moz-appearance: none;\n\t-webkit-appearance: none;\n\tcolor: white;\n\tbackground-color: hotpink;\n\ttransition: background-color 0.3s ease;\n}\n```\n\n## Add an icon\n\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\n```css\n.btn-icon {\n\tbackground-color: hotpink;\n}\n.btn-icon::before {\n\tcontent: url('~assets/svg/arrow-right-white.svg');\n\tposition: absolute;\n\twidth: 20px;\n\ttop: 50%;\n\tright: 0;\n\ttransform: translate(40px, -50%);\n\ttransition: transform ease 0.3s;\n}\n.btn-icon:hover,\n.btn-icon:focus {\n\tbackground-color: darkorchid;\n}\n.btn-icon:hover::before,\n.btn-icon:focus::before {\n\ttransform: translate(-10px, -50%);\n}\n.btn-icon > span {\n\tdisplay: inline-block;\n\twidth: 100%;\n\theight: 100%;\n\ttransition: transform 0.3s ease;\n}\n.btn-icon:hover > span,\n.btn-icon:focus > span {\n\ttransform: translateX(-10px);\n}\n```\n\n## Double shutter down\n\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\n```css\n.btn-rideau {\n\tborder: 2px solid #10113a;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n\ttransition: color 0.3s ease;\n}\n.btn-rideau:hover {\n\tcolor: white;\n}\n.btn-rideau::before {\n\tbackground: hotpink;\n}\n.btn-rideau::after {\n\tbackground: darkorchid;\n}\n.btn-rideau::before,\n.btn-rideau::after {\n\tcontent: '';\n\tposition: absolute;\n\theight: 100%;\n\twidth: 100%;\n\tbottom: 100%;\n\tleft: 0;\n\tz-index: -1;\n\ttransition: transform 0.3s;\n\ttransition-timing-function: ease;\n\ttransition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);\n}\n.btn-rideau:hover::before,\n.btn-rideau:hover::after,\n.btn-rideau:focus::before,\n.btn-rideau:focus::after {\n\ttransform: translateY(100%);\n}\n.btn-rideau:hover::after,\n.btn-rideau:focus::after {\n\ttransition-delay: 0.175s;\n}\n```\n\n## Animated gradient\n\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\n```css\n.btn-gradient {\n\tbackground: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);\n\tbackground-size: 400% 400%;\n\tbackground-position: 0% 50%;\n\tanimation: GradientReverse 0.5s ease 1 normal forwards;\n}\n.btn-gradient:hover,\n.btn-gradient:focus {\n\tanimation: Gradient 0.5s ease 1 normal forwards;\n}\n@keyframes Gradient {\n\t0% {\n\t\tbackground-position: 0% 50%;\n\t}\n\t100% {\n\t\tbackground-position: 100% 100%;\n\t}\n}\n@keyframes GradientReverse {\n\t0% {\n\t\tbackground-position: 100% 100%;\n\t}\n\t100% {\n\t\tbackground-position: 0% 50%;\n\t}\n}\n```\n\n## Non destructive scale\n\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\n```css\n.btn-scale {\n\toverflow: visible;\n\tcolor: #10113a;\n\tbackground-color: transparent;\n}\n.btn-scale::after {\n\tcontent: '';\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tborder: 2px solid #10113a;\n\tborder-radius: 2px;\n\ttransition: transform 0.3s ease;\n}\n.btn-scale:hover::after,\n.btn-scale:focus::after {\n\ttransform: scale(1.1);\n}\n```","src/content/fragments/en/buttons.md","ea9a5513a5a4cef4",{"html":911,"metadata":912},"\u003Ch2 id=\"general-rules\">General rules\u003C/h2>\n\u003Cp>All the buttons use these styles as a “reset”:\u003C/p>\n\u003Cblockquote>\n\u003Cp>Don’t forget to prefix if necessary!\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.642km.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">margin: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">padding: \u003C/span>\u003Cspan style=\"--0:#D19A66\">12\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">26\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">relative\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">display: \u003C/span>\u003Cspan style=\"--0:#D19A66\">inline-block\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">overflow: \u003C/span>\u003Cspan style=\"--0:#D19A66\">hidden\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">font-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">rem\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">; \u003C/span>\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\">/* 20px */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">line-height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">1.6\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-align: \u003C/span>\u003Cspan style=\"--0:#D19A66\">center\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">text-decoration: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">font-weight: \u003C/span>\u003Cspan style=\"--0:#D19A66\">bold\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">cursor: \u003C/span>\u003Cspan style=\"--0:#D19A66\">pointer\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">-moz-appearance\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#56B6C2\">-webkit-appearance\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">: \u003C/span>\u003Cspan style=\"--0:#D19A66\">none\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: background-color \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn { margin: 20px 0; padding: 12px 26px; position: relative; display: inline-block; overflow: hidden; font-size: 20rem; /* 20px */ line-height: 1.6; text-align: center; text-decoration: none; font-weight: bold; cursor: pointer; border: none; border-radius: 2px; -moz-appearance: none; -webkit-appearance: none; color: white; background-color: hotpink; transition: background-color 0.3s ease;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"add-an-icon\">Add an icon\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-icon\">\n \u003Cspan>Icon\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">url\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#98C379\">'~assets/svg/arrow-right-white.svg'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">20\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">right: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">40\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">-50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: darkorchid;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translate\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-10\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">-50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">display: \u003C/span>\u003Cspan style=\"--0:#D19A66\">inline-block\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">27\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">28\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-icon\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#ABB2BF\">>\u003C/span>\u003Cspan style=\"--0:#CD89E1\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">span\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">29\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translateX\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-10\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">30\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-icon { background-color: hotpink;}.btn-icon::before { content: url('~assets/svg/arrow-right-white.svg'); position: absolute; width: 20px; top: 50%; right: 0; transform: translate(40px, -50%); transition: transform ease 0.3s;}.btn-icon:hover,.btn-icon:focus { background-color: darkorchid;}.btn-icon:hover::before,.btn-icon:focus::before { transform: translate(-10px, -50%);}.btn-icon > span { display: inline-block; width: 100%; height: 100%; transition: transform 0.3s ease;}.btn-icon:hover > span,.btn-icon:focus > span { transform: translateX(-10px);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"double-shutter-down\">Double shutter down\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-rideau\">\n \u003Cspan>Shutter\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">solid\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">transparent\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: \u003C/span>\u003Cspan style=\"--0:#D19A66\">color\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">white\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: hotpink;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: darkorchid;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">height: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">bottom: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">z-index: \u003C/span>\u003Cspan style=\"--0:#D19A66\">-1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-timing-function: \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">27\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-timing-function: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">cubic-bezier\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">0.75\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.125\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">28\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">29\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">30\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">31\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::before\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">32\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">33\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">translateY\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">34\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">35\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">36\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-rideau\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">37\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition-delay: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.175\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">38\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-rideau { border: 2px solid #10113a; color: #10113a; background-color: transparent; transition: color 0.3s ease;}.btn-rideau:hover { color: white;}.btn-rideau::before { background: hotpink;}.btn-rideau::after { background: darkorchid;}.btn-rideau::before,.btn-rideau::after { content: ''; position: absolute; height: 100%; width: 100%; bottom: 100%; left: 0; z-index: -1; transition: transform 0.3s; transition-timing-function: ease; transition-timing-function: cubic-bezier(0.75, 0, 0.125, 1);}.btn-rideau:hover::before,.btn-rideau:hover::after,.btn-rideau:focus::before,.btn-rideau:focus::after { transform: translateY(100%);}.btn-rideau:hover::after,.btn-rideau:focus::after { transition-delay: 0.175s;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"animated-gradient\">Animated gradient\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-gradient\">\n \u003Cspan>Gradient\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">linear-gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">-45\u003C/span>\u003Cspan style=\"--0:#E6888F\">deg\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#ee7752\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#e73c7e\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#23a6d5\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">, \u003C/span>\u003Cspan style=\"--0:#D19A66\">#23d5ab\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-size: \u003C/span>\u003Cspan style=\"--0:#D19A66\">400\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">400\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">animation: GradientReverse \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.5\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">normal\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">forwards\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-gradient\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">animation: Gradient \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.5\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">normal\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">forwards\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">@keyframes\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">Gradient\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">0% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">100% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">@keyframes\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F;--0fs:italic\">GradientReverse\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">0% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">21\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">22\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">23\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">100% {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">24\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">50\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">25\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">26\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-gradient { background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); background-size: 400% 400%; background-position: 0% 50%; animation: GradientReverse 0.5s ease 1 normal forwards;}.btn-gradient:hover,.btn-gradient:focus { animation: Gradient 0.5s ease 1 normal forwards;}@keyframes Gradient { 0% { background-position: 0% 50%; } 100% { background-position: 100% 100%; }}@keyframes GradientReverse { 0% { background-position: 100% 100%; } 100% { background-position: 0% 50%; }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"non-destructive-scale\">Non destructive scale\u003C/h2>\n\u003Cbutton role=\"none\" class=\"btn btn-scale\">\n \u003Cspan>Scale\u003C/span>\n\u003C/button>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">1\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">2\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">overflow: \u003C/span>\u003Cspan style=\"--0:#D19A66\">visible\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">3\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">4\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">background-color: \u003C/span>\u003Cspan style=\"--0:#D19A66\">transparent\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">5\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">6\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">7\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">content: \u003C/span>\u003Cspan style=\"--0:#98C379\">''\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">8\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">position: \u003C/span>\u003Cspan style=\"--0:#D19A66\">absolute\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">9\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">top: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">10\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">left: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">11\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">bottom: \u003C/span>\u003Cspan style=\"--0:#D19A66\">0\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">12\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">width: \u003C/span>\u003Cspan style=\"--0:#D19A66\">100\u003C/span>\u003Cspan style=\"--0:#E6888F\">%\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">13\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">solid\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">#10113a\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">14\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">border-radius: \u003C/span>\u003Cspan style=\"--0:#D19A66\">2\u003C/span>\u003Cspan style=\"--0:#E6888F\">px\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">15\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transition: transform \u003C/span>\u003Cspan style=\"--0:#D19A66\">0.3\u003C/span>\u003Cspan style=\"--0:#E6888F\">s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">ease\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">16\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">17\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:hover::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">18\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D19A66\">.btn-scale\u003C/span>\u003Cspan style=\"--0:#56B6C2\">:focus::after\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">19\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">transform: \u003C/span>\u003Cspan style=\"--0:#56B6C2\">scale\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">(\u003C/span>\u003Cspan style=\"--0:#D19A66\">1.1\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"gutter\">\u003Cdiv class=\"ln\" aria-hidden=\"true\">20\u003C/div>\u003C/div>\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#ABB2BF\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".btn-scale { overflow: visible; color: #10113a; background-color: transparent;}.btn-scale::after { content: ''; position: absolute; top: 0; left: 0; bottom: 0; width: 100%; border: 2px solid #10113a; border-radius: 2px; transition: transform 0.3s ease;}.btn-scale:hover::after,.btn-scale:focus::after { transform: scale(1.1);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":913,"imagePaths":929,"frontmatter":930},[914,917,920,923,926],{"depth":105,"slug":915,"text":916},"general-rules","General rules",{"depth":105,"slug":918,"text":919},"add-an-icon","Add an icon",{"depth":105,"slug":921,"text":922},"double-shutter-down","Double shutter down",{"depth":105,"slug":924,"text":925},"animated-gradient","Animated gradient",{"depth":105,"slug":927,"text":928},"non-destructive-scale","Non destructive scale",[],{"title":903,"subtitle":904,"lang":449,"slug":900,"draft":292,"excerpt":931,"tags":932,"code":292,"type":607,"createdAt":933},"Easy to grab and use hover effects.",[606],"2020-10-08T09:00:00.000Z","en-acme-sh-tls-cert",{"id":934,"data":936,"body":942,"filePath":943,"digest":944,"rendered":945},{"title":937,"subtitle":938,"lang":449,"tags":939,"type":607,"slug":934,"createdAt":941},"Strong TLS certificates with acme.sh","384-bit of https",[940],"security",["Date","2022-06-08T14:24:06.000Z"],"## Disclaimer\n\nI'm, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs. \nThis is why I've switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nYou can learn (far) more by reading [this topic](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) and its linked resources.\n\n## Requirements\n\n### Installing acme.sh\n\nFor automation and ease of use purposes, I'm using [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# for using standalone mode, you might have to install as sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changing default authority\n\nBy default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let's Encrypt because according to acme.sh, they're the only ones offering ECC capabilities.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Using your DNS api\n\nIf available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports [a lot](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) of DNS providers.\n\n### Define an api key\n\nFollow the [docs](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) for your DNS provider, usually:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Issue the cert\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Using standalone mode\n\nIf you don't have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\n\nPort `80` must be free.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Examples\n\n### Multi domains standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domain DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Next steps\n\nThe ECC certificate alone will not grant you a high/perfect score.\n\n### TLS version\n\nLimit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a [5% compatibility gap](https://caniuse.com/?search=tls%201.) with 1.2).\n\n### HSTS\n\nUse the [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/) header.\n\n```http\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Cipher suite\n\nUse recent and strong ciphers. This is where my knowledge hits its limit… I'm having a really hard time understanding what to use and why.\n\nI've based my initial choices of ciphers on [this list](https://tls.imirhil.fr/ciphers), cross referencing it with (older?) [browser compatibility](https://tls.imirhil.fr/suite).\n\nI then asked [Aeris](https://twitter.com/aeris22), the creator of [tls.imirhil.fr](https://tls.imirhil.fr), about it and he advised me to use the following:\n\n```cypher\nECDHE+AES:ECDHE+CHACHA20\n```\n\nIn order to achieve a perfect score, we can be a little more restrictive with:\n\n```cypher\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/en/acme-sh-tls-cert.md","4dc80f1d0e800d6f",{"html":946,"metadata":947},"\u003Ch2 id=\"disclaimer\">Disclaimer\u003C/h2>\n\u003Cp>I’m, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs.\u003Cbr>\nThis is why I’ve switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>You can learn (far) more by reading \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">this topic\u003C/a> and its linked resources.\u003C/p>\n\u003Ch2 id=\"requirements\">Requirements\u003C/h2>\n\u003Ch3 id=\"installing-acmesh\">Installing acme.sh\u003C/h3>\n\u003Cp>For automation and ease of use purposes, I’m using \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.642km.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\"># for using standalone mode, you might have to install as sudo\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">curl\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">https://get.acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> | \u003C/span>\u003Cspan style=\"--0:#61AFEF\">sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">email=mail@domain.tld\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl https://get.acme.sh | sh -s email=mail@domain.tld\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"changing-default-authority\">Changing default authority\u003C/h3>\n\u003Cp>By default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let’s Encrypt because according to acme.sh, they’re the only ones offering ECC capabilities.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--set-default-ca\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--server\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">letsencrypt\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --set-default-ca --server letsencrypt\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"using-your-dns-api\">Using your DNS api\u003C/h2>\n\u003Cp>If available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">a lot\u003C/a> of DNS providers.\u003C/p>\n\u003Ch3 id=\"define-an-api-key\">Define an api key\u003C/h3>\n\u003Cp>Follow the \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">docs\u003C/a> for your DNS provider, usually:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">PROVIDER_Key\u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#98C379\">\"YOUR_API_KEY\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export PROVIDER_Key="YOUR_API_KEY"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"issue-the-cert\">Issue the cert\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"using-standalone-mode\">Using standalone mode\u003C/h2>\n\u003Cp>If you don’t have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications.\u003C/p>\n\u003Cp>Port \u003Ccode>80\u003C/code> must be free.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"examples\">Examples\u003C/h2>\n\u003Ch3 id=\"multi-domains-standalone\">Multi domains standalone\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">www.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">subdomain.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"wildcard-domain-dns\">Wildcard domain DNS\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'*.domain.tld'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"next-steps\">Next steps\u003C/h2>\n\u003Cp>The ECC certificate alone will not grant you a high/perfect score.\u003C/p>\n\u003Ch3 id=\"tls-version\">TLS version\u003C/h3>\n\u003Cp>Limit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a \u003Ca href=\"https://caniuse.com/?search=tls%201.\">5% compatibility gap\u003C/a> with 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Use the \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a> header.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">Strict-Transport-Security\u003C/span>\u003Cspan style=\"--0:#CD89E1\">:\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">max-age=31536000; includeSubDomains\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Strict-Transport-Security: max-age=31536000; includeSubDomains\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"cipher-suite\">Cipher suite\u003C/h3>\n\u003Cp>Use recent and strong ciphers. This is where my knowledge hits its limit… I’m having a really hard time understanding what to use and why.\u003C/p>\n\u003Cp>I’ve based my initial choices of ciphers on \u003Ca href=\"https://tls.imirhil.fr/ciphers\">this list\u003C/a>, cross referencing it with (older?) \u003Ca href=\"https://tls.imirhil.fr/suite\">browser compatibility\u003C/a>.\u003C/p>\n\u003Cp>I then asked \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, the creator of \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, about it and he advised me to use the following:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>In order to achieve a perfect score, we can be a little more restrictive with:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES256\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES256:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":948,"imagePaths":994,"frontmatter":995},[949,952,955,958,961,964,967,970,973,976,979,982,985,988,991],{"depth":105,"slug":950,"text":951},"disclaimer","Disclaimer",{"depth":105,"slug":953,"text":954},"requirements","Requirements",{"depth":162,"slug":956,"text":957},"installing-acmesh","Installing acme.sh",{"depth":162,"slug":959,"text":960},"changing-default-authority","Changing default authority",{"depth":105,"slug":962,"text":963},"using-your-dns-api","Using your DNS api",{"depth":162,"slug":965,"text":966},"define-an-api-key","Define an api key",{"depth":162,"slug":968,"text":969},"issue-the-cert","Issue the cert",{"depth":105,"slug":971,"text":972},"using-standalone-mode","Using standalone mode",{"depth":105,"slug":974,"text":975},"examples","Examples",{"depth":162,"slug":977,"text":978},"multi-domains-standalone","Multi domains standalone",{"depth":162,"slug":980,"text":981},"wildcard-domain-dns","Wildcard domain DNS",{"depth":105,"slug":983,"text":984},"next-steps","Next steps",{"depth":162,"slug":986,"text":987},"tls-version","TLS version",{"depth":162,"slug":989,"text":990},"hsts","HSTS",{"depth":162,"slug":992,"text":993},"cipher-suite","Cipher suite",[],{"title":937,"subtitle":938,"lang":449,"slug":934,"createdAt":250,"excerpt":996,"tags":997,"type":607},"Real cert have curves.",[940],"acme-sh-tls-cert",{"id":998,"data":1000,"body":1006,"filePath":1007,"digest":1008,"rendered":1009},{"title":1001,"subtitle":1002,"lang":17,"tags":1003,"type":599,"slug":998,"createdAt":1005},"Certificates TLS robustes avec acme.sh","384-bit de https",[1004],"sécurité",["Date","2022-06-08T14:24:06.000Z"],"## Attention\n\nJe ne suis pas du tout un expert en sécurité. J'aime juste les trucs nouveaux et stylés des internets. \nC'est pourquoi j'ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J'ai maintenant un joli 100/100 sur [tls.imirhil.fr](https://tls.imirhil.fr/)\n\nVous pouvez en apprendre (beaucoup) plus [ici](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) et sur les liens cités (en anglais).\n\n## Prérequis\n\n### Installer acme.sh\n\nPour des raisons de simplicité et d'automatisation, j'utilise [acme.sh](https://github.com/acmesh-official/acme.sh)\n\n```bash\n# pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\ncurl https://get.acme.sh | sh -s email=mail@domain.tld\n```\n\n### Changer l'authorité par défaut\n\nPar défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let's Encrypt car, d'après acme.sh, ils sont les seuls à proposer des certificats ECC.\n\n```bash\nacme.sh --set-default-ca --server letsencrypt\n```\n\n## Utiliser l'api DNS\n\nSi vous en avez la possibilité, la façon la plus simple de générer un certificat est via l'api de votre fournisseur DNS. acme.sh supporte [énormément](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) de fournisseurs DNS.\n\n### Definir la clé api\n\nSuivez la [documentation](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) pour votre fournisseur DNS, généralement:\n\n```bash\nexport PROVIDER_Key=\"YOUR_API_KEY\"\n```\n\n### Émettre le certificat\n\n```bash\nacme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\n```\n\n## Utiliser le mode standalone\n\nSi vous n'avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s'occupe de toutes les vérifications.\n\nLe port `80` doit être disponible.\n\n```bash\nacme.sh --issue --standalone -d domain.tld --keylength ec-384\n```\n\n## Exemples\n\n### Multi domaines standalone\n\n```bash\nacme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\n```\n\n### Wildcard domaine DNS\n\n```bash\nacme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\n```\n\n## Étapes supplémentaires\n\nLe certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\n\n### Version TLS\n\nLimiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu [la différence de compatibilité de 5%](https://caniuse.com/?search=tls%201.) avec 1.2).\n\n### HSTS\n\nUtiliser le header [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/).\n\n```http\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\n### Suite cryptographique\n\nUtiliser une suite cryptographique récente et robuste. C'est ici que mes connaissances deviennent limitées… J'ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\n\nJ'avais basé ma première suite sur [cette liste](https://tls.imirhil.fr/ciphers), en la comparant avec celle de la compatibilité (d'anciens ?) [navigateurs](https://tls.imirhil.fr/suite).\n\nJ'ai ensuite demandé à [Aeris](https://twitter.com/aeris22), le créateur de [tls.imirhil.fr](https://tls.imirhil.fr), ses conseils sur cette suite. Il m'a recommandé d'utiliser :\n\n```cypher\nECDHE+AES:ECDHE+CHACHA20\n```\n\nAfin d'atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\n\n```cypher\nECDHE+AES256:ECDHE+CHACHA20\n```","src/content/fragments/fr/acme-sh-tls-cert.md","018b0c09d1fdd6cc",{"html":1010,"metadata":1011},"\u003Ch2 id=\"attention\">Attention\u003C/h2>\n\u003Cp>Je ne suis pas du tout un expert en sécurité. J’aime juste les trucs nouveaux et stylés des internets.\u003Cbr>\nC’est pourquoi j’ai modifié mes certificats TLS par défaut pour utiliser la cryptographie à courbe elliptique (ECC) au lieu de RSA. J’ai maintenant un joli 100/100 sur \u003Ca href=\"https://tls.imirhil.fr/\">tls.imirhil.fr\u003C/a>\u003C/p>\n\u003Cp>Vous pouvez en apprendre (beaucoup) plus \u003Ca href=\"https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa\">ici\u003C/a> et sur les liens cités (en anglais).\u003C/p>\n\u003Ch2 id=\"prérequis\">Prérequis\u003C/h2>\n\u003Ch3 id=\"installer-acmesh\">Installer acme.sh\u003C/h3>\n\u003Cp>Pour des raisons de simplicité et d’automatisation, j’utilise \u003Ca href=\"https://github.com/acmesh-official/acme.sh\">acme.sh\u003C/a>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.642km.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.8zarh.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#9FA3AA;--0fs:italic\"># pour utiliser le mode standalone, il peut être nécessaire d'installer en sudo\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">curl\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">https://get.acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> | \u003C/span>\u003Cspan style=\"--0:#61AFEF\">sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-s\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">email=mail@domain.tld\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl https://get.acme.sh | sh -s email=mail@domain.tld\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"changer-lauthorité-par-défaut\">Changer l’authorité par défaut\u003C/h3>\n\u003Cp>Par défaut, acme.sh utilise ZeroSSL pour signer les certificats. Il faut changer ce paramètre pour Let’s Encrypt car, d’après acme.sh, ils sont les seuls à proposer des certificats ECC.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--set-default-ca\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--server\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">letsencrypt\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --set-default-ca --server letsencrypt\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"utiliser-lapi-dns\">Utiliser l’api DNS\u003C/h2>\n\u003Cp>Si vous en avez la possibilité, la façon la plus simple de générer un certificat est via l’api de votre fournisseur DNS. acme.sh supporte \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">énormément\u003C/a> de fournisseurs DNS.\u003C/p>\n\u003Ch3 id=\"definir-la-clé-api\">Definir la clé api\u003C/h3>\n\u003Cp>Suivez la \u003Ca href=\"https://github.com/acmesh-official/acme.sh/wiki/dnsapi\">documentation\u003C/a> pour votre fournisseur DNS, généralement:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#CD89E1\">export\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#E6888F\">PROVIDER_Key\u003C/span>\u003Cspan style=\"--0:#56B6C2\">=\u003C/span>\u003Cspan style=\"--0:#98C379\">\"YOUR_API_KEY\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export PROVIDER_Key="YOUR_API_KEY"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"émettre-le-certificat\">Émettre le certificat\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"utiliser-le-mode-standalone\">Utiliser le mode standalone\u003C/h2>\n\u003Cp>Si vous n’avez pas accès aux réglages DNS, le mode standalone permet de lancer un serveur web temporaire qui s’occupe de toutes les vérifications.\u003C/p>\n\u003Cp>Le port \u003Ccode>80\u003C/code> doit être disponible.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"exemples\">Exemples\u003C/h2>\n\u003Ch3 id=\"multi-domaines-standalone\">Multi domaines standalone\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--standalone\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">www.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">subdomain.domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"wildcard-domaine-dns\">Wildcard domaine DNS\u003C/h3>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#61AFEF\">acme.sh\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--issue\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">domain.tld\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">-d\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">'*.domain.tld'\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--dns\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">dns_provider\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#D19A66\">--keylength\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">ec-384\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"acme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch2 id=\"étapes-supplémentaires\">Étapes supplémentaires\u003C/h2>\n\u003Cp>Le certificat ECC seul ne suffira pas à obtenir un score élevé/parfait.\u003C/p>\n\u003Ch3 id=\"version-tls\">Version TLS\u003C/h3>\n\u003Cp>Limiter la version TLS à 1.2 et 1.3 (voire uniquement 1.3 vu \u003Ca href=\"https://caniuse.com/?search=tls%201.\">la différence de compatibilité de 5%\u003C/a> avec 1.2).\u003C/p>\n\u003Ch3 id=\"hsts\">HSTS\u003C/h3>\n\u003Cp>Utiliser le header \u003Ca href=\"https://scotthelme.co.uk/hsts-the-missing-link-in-tls/\">strict transport security\u003C/a>.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">Strict-Transport-Security\u003C/span>\u003Cspan style=\"--0:#CD89E1\">:\u003C/span>\u003Cspan style=\"--0:#ABB2BF\"> \u003C/span>\u003Cspan style=\"--0:#98C379\">max-age=31536000; includeSubDomains\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Strict-Transport-Security: max-age=31536000; includeSubDomains\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Ch3 id=\"suite-cryptographique\">Suite cryptographique\u003C/h3>\n\u003Cp>Utiliser une suite cryptographique récente et robuste. C’est ici que mes connaissances deviennent limitées… J’ai encore un peu de mal à comprendre quelles suites fonctionnent bien et pourquoi.\u003C/p>\n\u003Cp>J’avais basé ma première suite sur \u003Ca href=\"https://tls.imirhil.fr/ciphers\">cette liste\u003C/a>, en la comparant avec celle de la compatibilité (d’anciens ?) \u003Ca href=\"https://tls.imirhil.fr/suite\">navigateurs\u003C/a>.\u003C/p>\n\u003Cp>J’ai ensuite demandé à \u003Ca href=\"https://twitter.com/aeris22\">Aeris\u003C/a>, le créateur de \u003Ca href=\"https://tls.imirhil.fr\">tls.imirhil.fr\u003C/a>, ses conseils sur cette suite. Il m’a recommandé d’utiliser :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Afin d’atteindre un score de 100/100, il est possible de restreindre un peu plus la suite comme ceci :\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"cypher\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">AES256\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">:\u003C/span>\u003Cspan style=\"--0:#E6888F\">ECDHE\u003C/span>\u003Cspan style=\"--0:#ABB2BF\">+\u003C/span>\u003Cspan style=\"--0:#E6888F\">CHACHA20\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ECDHE+AES256:ECDHE+CHACHA20\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":1012,"imagePaths":1056,"frontmatter":1057},[1013,1016,1019,1022,1025,1028,1031,1034,1037,1040,1043,1046,1049,1052,1053],{"depth":105,"slug":1014,"text":1015},"attention","Attention",{"depth":105,"slug":1017,"text":1018},"prérequis","Prérequis",{"depth":162,"slug":1020,"text":1021},"installer-acmesh","Installer acme.sh",{"depth":162,"slug":1023,"text":1024},"changer-lauthorité-par-défaut","Changer l’authorité par défaut",{"depth":105,"slug":1026,"text":1027},"utiliser-lapi-dns","Utiliser l’api DNS",{"depth":162,"slug":1029,"text":1030},"definir-la-clé-api","Definir la clé api",{"depth":162,"slug":1032,"text":1033},"émettre-le-certificat","Émettre le certificat",{"depth":105,"slug":1035,"text":1036},"utiliser-le-mode-standalone","Utiliser le mode standalone",{"depth":105,"slug":1038,"text":1039},"exemples","Exemples",{"depth":162,"slug":1041,"text":1042},"multi-domaines-standalone","Multi domaines standalone",{"depth":162,"slug":1044,"text":1045},"wildcard-domaine-dns","Wildcard domaine DNS",{"depth":105,"slug":1047,"text":1048},"étapes-supplémentaires","Étapes supplémentaires",{"depth":162,"slug":1050,"text":1051},"version-tls","Version TLS",{"depth":162,"slug":989,"text":990},{"depth":162,"slug":1054,"text":1055},"suite-cryptographique","Suite cryptographique",[],{"title":1001,"subtitle":1002,"lang":17,"slug":998,"createdAt":250,"excerpt":1058,"tags":1059,"type":599},"La sécurité avec des courbes.",[1004]] \ No newline at end of file diff --git a/.astro/settings.json b/.astro/settings.json index 5b5bd70..554adf3 100644 --- a/.astro/settings.json +++ b/.astro/settings.json @@ -1,5 +1,5 @@ { "_variables": { - "lastUpdateCheck": 1735403503212 + "lastUpdateCheck": 1737382034437 } } \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index 7240b4a97d57c5db936200212f10130e56c900cd..890d2c8b5f4a6f9c628533382949cb3a2c88ae42 100755 GIT binary patch delta 45881 zcmeFacR*Cf_cp%w$|{SZpdz5CD5!{nfOKRLD~P=z2ueqgCPe|oUF?F`t~&PKdx;HW z>^1hNG4>K;?;YFkIkyP$P4fMGKkx7TFPl93%sF#r=FFLL=dQclR}(8An^I}Aqy38a z$Cd{FVskaB)vo52o1Rt9&c9c|b<2;#ZJj*Z96lS^)XT7(ie9(4DShhbu3h0oNqRF; zsq`5GBGc0#{=}NxqCI=!jGSgF$ZVl_IkQad|KOw_m zNJf%MWs6p;L7rJz*k9gJ*96(ru~Tr0>Q75g$Vg7iPz{btNQy-@6Ho^gzXGNJ>A~dB zHrP|SN2rVPi}6N*p9?(&EGs1;E+IDNTRm_pD}Df6gpX7{HajymB}S!F#l#LyO2tsc z#16`egnvoF%vfGL^e7=Id1Yvq(@6UZWKnncN`>nbGj{NG&OVgD?-MU>o-ALUlk_pyP&q9%) z5Vvk9MIsLsQ$z-VsX&cJlE)@?Di!M1zlKbUV+uhJdLDq@?`b#!|&q;ROwq225j| zn;IjAKGk1p@Ez=EQY!j~knz8MeJg3wU57wJ^a~ivvYLL#fQ0A)4r$5jTT2a8Y$J59 z&`{T{tyG_?jZ|)MLS}4SmP$oT4aQ}}4n`0%(o!=rqcbv8HtnT$EWy)M0#gA@6{M#oC1qj5 zoZkbRIpkcKgTb^q-N5z1W?-75Z@Wu#?N^z1$UGa29Y;S*=6*8!gKJ}5=xr$hHU!h; zecVmrGcs=l*Mfcyn3nYjFinjtFb(-}ylF^|OO>WbT&%dUy7rZ(T1+f1Rmf=qnd}BM z7tK^zDX}TK!APe?W)7giPEJS`$2>-y0d#Fl$w*C#gkf}gPFiMadSpyOHVUT>h|CxO z`xW8RREkbd&Bz#%p_&Yt8i*c{Ixrz7GCe&uGA1S=J#AKmr0)Ty#f3{`d{SzZs&^#z zC7MKS<&2w=lE>bV=~@z%9vK~*p;E2Gm7DBdfvJMF(NcwxDLKiJ=<6mq0+|_bIWBr& zWAlBjXdIanMi}UH(AHJ=-L4>gn_vBxq`6B7+(lg*Wn_ zB};mxUun?O;)s#+VFuB*7>7m&As*?mSs4j&IjUpO zSA)I)>w)UO2(E&`)4R(BTB0KS|7}h>L#P5dCLs>7p;O1;$RtF@0(zReQIQ$34(_fh zY$>rB7|rNZOc{)n0rJVw=%kEnDi@WS9h(9knJGDX7EBR0#};KoizgZi@@OR#RB#@c zLVFl`V!ALBr-G@cp)yAgh)hDzRNZ8`J(wz1>ibhe(A&Zt+IE!s-=a|+jrn6Fs9
      j3FnrNRp*#(p4i3}? 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 diff --git a/package.json b/package.json index 9d00e78..496610e 100755 --- a/package.json +++ b/package.json @@ -10,19 +10,18 @@ "astro": "astro" }, "dependencies": { - "@astrojs/mdx": "4.0.3", - "@astrojs/rss": "4.0.10", + "@astrojs/mdx": "4.0.7", + "@astrojs/rss": "4.0.11", "@astrojs/sitemap": "3.2.1", "@astrojs/ts-plugin": "^1.10.4", - "@expressive-code/plugin-line-numbers": "^0.38.3", - "astro": "5.1.1", - "astro-expressive-code": "^0.38.3", + "@expressive-code/plugin-line-numbers": "^0.40.1", + "astro": "5.1.8", + "astro-expressive-code": "^0.40.1", "sharp": "^0.33.5" }, "devDependencies": { - "@shikijs/transformers": "^1.24.4", "autoprefixer": "^10.4.20", - "postcss": "^8.4.49", + "postcss": "^8.5.1", "prettier": "^3.4.2", "prettier-plugin-astro": "^0.14.1", "prettier-plugin-organize-imports": "^4.1.0" diff --git a/src/components/CardEditorial.astro b/src/components/CardEditorial.astro index 626e1b0..3e60a55 100755 --- a/src/components/CardEditorial.astro +++ b/src/components/CardEditorial.astro @@ -87,6 +87,8 @@ const isReference = routeName === 'references' &::after { transform: translateX(0); opacity: 1; + transition-duration: 0.6s; + transition-timing-function: var(--timing-bounce); } h3 a { @@ -100,12 +102,12 @@ const isReference = routeName === 'references' transition: box-shadow 0.2s ease; } &::before { - transition: transform 0.2s ease-in-out; + transition: transform 0.4s var(--timing-out-expo); } &::after { - transition: - opacity ease 0.2s, - transform ease 0.2s; + transition-property: opacity, transform; + transition-duration: 0.3s; + transition-timing-function: ease-in-out; } h3 a { transition: color ease 0.2s; diff --git a/src/components/Footer.astro b/src/components/Footer.astro index ffffdae..15cdd8b 100755 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -1,8 +1,10 @@ --- +import { Picture } from 'astro:assets' import SocialRel from '../components/SocialRel.astro' +import fight from '../images/fight-fascism.webp' --- -

      +

      Nicolas Arduin

      @@ -15,6 +17,15 @@ import SocialRel from '../components/SocialRel.astro'
    +
    + + + +

};I0iRQ&&7x=<@xE|l_U9S`G#=zMO~5Sy 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 KNZ$XU|Na*fxSjI= diff --git a/package.json b/package.json index df2307b..960bd98 100755 --- a/package.json +++ b/package.json @@ -13,15 +13,14 @@ "i18n:sync": "astro-i18n sync" }, "dependencies": { - "@astrojs/mdx": "^1.1.0", - "@astrojs/rss": "^3.0.0", - "@astrojs/sitemap": "^3.0.0", - "astro": "3.1.4", - "astro-i18n": "1.8.1", - "sharp": "^0.32.6" + "@astrojs/mdx": "4.0.3", + "@astrojs/rss": "4.0.10", + "@astrojs/sitemap": "3.2.1", + "astro": "5.1.1", + "sharp": "^0.33.4" }, "devDependencies": { - "autoprefixer": "^10.4.13", - "postcss": "^8.4.20" + "autoprefixer": "^10.4.19", + "postcss": "^8.4.38" } } diff --git a/src/components/EditorialContent.astro b/src/components/EditorialContent.astro index f2bd32c..9363412 100755 --- a/src/components/EditorialContent.astro +++ b/src/components/EditorialContent.astro @@ -1,11 +1,11 @@ --- -// import { renderContent } from "astro-i18n"; +import { render } from "astro:content"; + import MetaDate from "./MetaDate.astro"; import TOC from "./TOC.astro"; const { content } = Astro.props; -const { Content, headings } = await content.render(); -// const { html, headings } = await renderContent(Astro, content); +const { Content, headings } = await render(content); const toc = headings.map((heading) => { return heading; diff --git a/src/content/config.ts b/src/content.config.ts similarity index 86% rename from src/content/config.ts rename to src/content.config.ts index d300ed6..91f8389 100755 --- a/src/content/config.ts +++ b/src/content.config.ts @@ -1,6 +1,8 @@ import { z, defineCollection } from "astro:content"; +import { glob } from 'astro/loaders'; const articles = defineCollection({ + loader: glob({ pattern: '**/[^_]*.md', base: "./src/content/articles" }), schema: z.object({ title: z.string(), subtitle: z.string(), @@ -20,6 +22,7 @@ const articles = defineCollection({ }); const fragments = defineCollection({ + loader: glob({ pattern: '**/[^_]*.md', base: "./src/content/fragments" }), schema: z.object({ title: z.string(), subtitle: z.string(), @@ -39,6 +42,7 @@ const fragments = defineCollection({ }); const references = defineCollection({ + loader: glob({ pattern: '**/[^_]*.md', base: "./src/content/references" }), schema: z.object({ title: z.string(), subtitle: z.string(), diff --git a/src/pages/articles/[slug].astro b/src/pages/articles/[id].astro similarity index 95% rename from src/pages/articles/[slug].astro rename to src/pages/articles/[id].astro index 3205fc1..3afee5d 100755 --- a/src/pages/articles/[slug].astro +++ b/src/pages/articles/[id].astro @@ -13,7 +13,7 @@ export const getStaticPaths = createStaticPaths( return data.lang === langCode; }); return articles.map((article) => ({ - params: { slug: article.data.permalink }, + params: { id: article.data.permalink }, props: { article }, })); }, diff --git a/src/pages/en/articles/[slug].astro b/src/pages/en/articles/[slug].astro deleted file mode 100755 index e3ae02e..0000000 --- a/src/pages/en/articles/[slug].astro +++ /dev/null @@ -1,15 +0,0 @@ ---- -import Page from "../../articles/[slug].astro" -import { getStaticPaths as proxyGetStaticPaths } from "../../articles/[slug].astro" -import { extractRouteLangCode } from "astro-i18n" - -/* @ts-ignore */ -export const getStaticPaths = (props) => proxyGetStaticPaths({ - ...props, - langCode: extractRouteLangCode(import.meta.url), -}) - -const { props } = Astro ---- - - \ No newline at end of file diff --git a/src/pages/en/articles/index.astro b/src/pages/en/articles/index.astro deleted file mode 100755 index c0884db..0000000 --- a/src/pages/en/articles/index.astro +++ /dev/null @@ -1,6 +0,0 @@ ---- -import Page from "../../articles/index.astro" -const { props } = Astro ---- - - \ No newline at end of file diff --git a/src/pages/en/index.astro b/src/pages/en/index.astro deleted file mode 100755 index 6dbe9cb..0000000 --- a/src/pages/en/index.astro +++ /dev/null @@ -1,6 +0,0 @@ ---- -import Page from "../index.astro" -const { props } = Astro ---- - - \ No newline at end of file diff --git a/src/pages/en/sitemap.astro b/src/pages/en/sitemap.astro deleted file mode 100755 index ce341ca..0000000 --- a/src/pages/en/sitemap.astro +++ /dev/null @@ -1,6 +0,0 @@ ---- -import Page from "../plan-du-site.astro" -const { props } = Astro ---- - - \ No newline at end of file diff --git a/src/pages/en/snippets/[slug].astro b/src/pages/en/snippets/[slug].astro deleted file mode 100755 index edfda1f..0000000 --- a/src/pages/en/snippets/[slug].astro +++ /dev/null @@ -1,15 +0,0 @@ ---- -import Page from "../../fragments/[slug].astro" -import { getStaticPaths as proxyGetStaticPaths } from "../../fragments/[slug].astro" -import { extractRouteLangCode } from "astro-i18n" - -/* @ts-ignore */ -export const getStaticPaths = (props) => proxyGetStaticPaths({ - ...props, - langCode: extractRouteLangCode(import.meta.url), -}) - -const { props } = Astro ---- - - \ No newline at end of file diff --git a/src/pages/en/snippets/index.astro b/src/pages/en/snippets/index.astro deleted file mode 100755 index f2672a4..0000000 --- a/src/pages/en/snippets/index.astro +++ /dev/null @@ -1,6 +0,0 @@ ---- -import Page from "../../fragments/index.astro" -const { props } = Astro ---- - - \ No newline at end of file diff --git a/src/pages/en/veille/index.astro b/src/pages/en/veille/index.astro deleted file mode 100755 index a2676da..0000000 --- a/src/pages/en/veille/index.astro +++ /dev/null @@ -1,6 +0,0 @@ ---- -import Page from "../../veille/index.astro" -const { props } = Astro ---- - - \ No newline at end of file diff --git a/src/pages/en/work/index.astro b/src/pages/en/work/index.astro deleted file mode 100755 index 3e3654b..0000000 --- a/src/pages/en/work/index.astro +++ /dev/null @@ -1,6 +0,0 @@ ---- -import Page from "../../references/index.astro" -const { props } = Astro ---- - - \ No newline at end of file diff --git a/src/pages/fragments/[slug].astro b/src/pages/fragments/[id].astro similarity index 95% rename from src/pages/fragments/[slug].astro rename to src/pages/fragments/[id].astro index c8935d3..c3a67bf 100755 --- a/src/pages/fragments/[slug].astro +++ b/src/pages/fragments/[id].astro @@ -13,7 +13,7 @@ export const getStaticPaths = createStaticPaths( return data.lang === langCode; }); return snippets.map((snippet) => ({ - params: { slug: snippet.data.permalink }, + params: { id: snippet.data.permalink }, props: { snippet }, })); }, diff --git a/src/pages/index.astro b/src/pages/index.astro index bae2acc..7382c51 100755 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,7 +1,8 @@ --- // init i18n -import { l, t, astroI18n } from "astro-i18n"; -astroI18n.init(Astro); +import { getLocale } from "astro-i18n-aut"; + +const locale = getLocale(Astro.url); // import stuff import BaseLayout from "../layouts/BaseLayout.astro"; @@ -11,17 +12,19 @@ import ListCards from "../components/ListCards.astro"; const pageTitle = t("accueil"); // get all HP sections -const allSections = await Astro.glob("../data/HP/**/*.md"); +const allSections = Object.values( + import.meta.glob("../data/HP/**/*.md", { eager: true }) +); // only keep the right locale version const localizedSections = allSections.filter((section) => { - return section.frontmatter.lang === astroI18n.langCode; + return section.frontmatter.lang === locale; }); // New astro content collections import { getCollection } from "astro:content"; // Only return posts with correct lang in the frontmatter const localizedArticles = await getCollection("articles", ({ data }) => { - return data.lang === astroI18n.langCode && !data.draft; + return data.lang === locale && !data.draft; }); // sort articles by descending publication date const sortedArticles = localizedArticles.sort( @@ -29,14 +32,14 @@ const sortedArticles = localizedArticles.sort( ); // Only return snippets with correct lang in the frontmatter const localizedSnippets = await getCollection("fragments", ({ data }) => { - return data.lang === astroI18n.langCode && !data.draft; + return data.lang === locale && !data.draft; }); // sort articles by descending publication date const sortedSnippets = localizedSnippets.sort( (a, b) => b.data.createdAt - a.data.createdAt ); const localizedReferences = await getCollection("references", ({ data }) => { - return data.lang === astroI18n.langCode && !data.draft; + return data.lang === locale && !data.draft; }); --- diff --git a/src/pages/veille/index.astro b/src/pages/veille/index.astro index b30db14..02dd5c3 100755 --- a/src/pages/veille/index.astro +++ b/src/pages/veille/index.astro @@ -8,7 +8,9 @@ import BaseLayout from "../../layouts/BaseLayout.astro"; import MetaDate from "../../components/MetaDate.astro"; // get all content -const allSections = await Astro.glob("../../data/veille/**/*.md"); +const allSections = Object.values( + import.meta.glob("../../data/veille/**/*.md", { eager: true }) +); // only keep the right locale version const localizedSections = allSections.filter((section) => { return section.frontmatter.lang === astroI18n.langCode; diff --git a/tsconfig.json b/tsconfig.json index e5993f9..e71eb5a 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,7 @@ { "extends": "astro/tsconfigs/base", + "include": [".astro/types.d.ts", "**/*"], + "exclude": ["dist"], "compilerOptions": { "strictNullChecks": true } -- 2.45.2 From b7ce5b7f20bb5db3ed78a3db80839b945ffaeea3 Mon Sep 17 00:00:00 2001 From: nico Date: Sat, 28 Dec 2024 11:52:32 +0100 Subject: [PATCH 02/16] astro native i18n + i18n utils --- .astro-i18n/generated.d.ts | 52 ---------- .prettierignore | 2 + .prettierrc.mjs | 34 ++++++ .vscode/launch.json | 11 -- .vscode/settings.json | 22 ++-- astro.config.mjs | 4 + astro.i18n.config.ts | 20 ---- bun.lockb | Bin 210419 -> 221901 bytes package.json | 10 +- src/components/LangSwitcher.astro | 34 +----- src/i18n/ui.ts | 150 +++++++++++++++++++++++++++ src/layouts/BaseLayout.astro | 5 +- src/layouts/MarkdownPostLayout.astro | 32 +++--- src/pages/index.astro | 5 +- src/utils/i18n.ts | 28 +++++ tsconfig.json | 20 +++- 16 files changed, 266 insertions(+), 163 deletions(-) delete mode 100755 .astro-i18n/generated.d.ts create mode 100644 .prettierignore create mode 100644 .prettierrc.mjs delete mode 100755 .vscode/launch.json delete mode 100755 astro.i18n.config.ts create mode 100644 src/i18n/ui.ts create mode 100644 src/utils/i18n.ts diff --git a/.astro-i18n/generated.d.ts b/.astro-i18n/generated.d.ts deleted file mode 100755 index 1750f79..0000000 --- a/.astro-i18n/generated.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -type DefaultLangCode = "fr" -type SupportedLangCode = "en" -type LangCode = DefaultLangCode | SupportedLangCode -type RouteUri = | "/articles/[slug]" | "/articles" | "/agments/[slug]" | "/agments" | "/references" | "/veille" | "/" | "/plan-du-site" -type RouteParams = {"/articles/[slug]": { "slug": string; }; "/articles": undefined; "/agments/[slug]": { "slug": string; }; "/agments": undefined; "/references": undefined; "/veille": undefined; "/": undefined; "/plan-du-site": undefined; } -type TranslationPath = "accueil" | "tagline" | "copyright" | "contact.title" | "contact.email" | "contact.tel" | "contenuVide" | "header.skipLink" | "header.mainNav" | "header.homeLink" | "sitemap" | "prevNext.contenus" | "prevNext.precedent" | "prevNext.suivant" | "article.titre" | "article.tagline" | "article.published" | "meta.publication" | "meta.modification" | "meta.credit" | "fragments.titre" | "fragments.tagline" | "references.titre" | "references.slug" | "references.cta" | "references.tagline" | "veille.titre" | "veille.tagline" | "erreur.introuvable" | "erreur.autre" | "erreur.lienRetour" | "seo.meta.description" | "seo.article.title" | "seo.article.description" | "seo.code.title" | "seo.code.description" | "seo.references.title" | "seo.references.description" | "index.articles.pageName" | "index.articles.subtitle" | "index.fragments.pageName" | "index.fragments.subtitle" | "index.references.pageName" | "index.references.subtitle" | "index.veille.pageName" | "index.veille.subtitle" | "index.title" | "index.subtitle" | "index.quoi" | "index.comment" | "index.opensource" | "index.writing" | "index.latestProjects" | "index.latestArticles" | "index.allProjects" | "index.allArticles" | "index.latestSnippets" | "index.allSnippets" | "index.toc" | "contact.contenuVide" -type TranslationOptions = { "accueil": {} | undefined; "tagline": {} | undefined; "copyright": {} | undefined; "contact.title": {} | undefined; "contact.email": {} | undefined; "contact.tel": {} | undefined; "contenuVide": {} | undefined; "header.skipLink": {} | undefined; "header.mainNav": {} | undefined; "header.homeLink": {} | undefined; "sitemap": {} | undefined; "prevNext.contenus": {} | undefined; "prevNext.precedent": {} | undefined; "prevNext.suivant": {} | undefined; "article.titre": {} | undefined; "article.tagline": {} | undefined; "article.published": { datetime: unknown; options: unknown; }; "meta.publication": {} | undefined; "meta.modification": {} | undefined; "meta.credit": {} | undefined; "fragments.titre": {} | undefined; "fragments.tagline": {} | undefined; "references.titre": {} | undefined; "references.slug": {} | undefined; "references.cta": {} | undefined; "references.tagline": {} | undefined; "veille.titre": {} | undefined; "veille.tagline": {} | undefined; "erreur.introuvable": {} | undefined; "erreur.autre": {} | undefined; "erreur.lienRetour": {} | undefined; "seo.meta.description": {} | undefined; "seo.article.title": {} | undefined; "seo.article.description": {} | undefined; "seo.code.title": {} | undefined; "seo.code.description": {} | undefined; "seo.references.title": {} | undefined; "seo.references.description": {} | undefined; "index.articles.pageName": {} | undefined; "index.articles.subtitle": {} | undefined; "index.fragments.pageName": {} | undefined; "index.fragments.subtitle": {} | undefined; "index.references.pageName": {} | undefined; "index.references.subtitle": {} | undefined; "index.veille.pageName": {} | undefined; "index.veille.subtitle": {} | undefined; "index.title": {} | undefined; "index.subtitle": {} | undefined; "index.quoi": {} | undefined; "index.comment": {} | undefined; "index.opensource": {} | undefined; "index.writing": {} | undefined; "index.latestProjects": {} | undefined; "index.latestArticles": {} | undefined; "index.allProjects": {} | undefined; "index.allArticles": {} | undefined; "index.latestSnippets": {} | undefined; "index.allSnippets": {} | undefined; "index.toc": {} | undefined; "contact.contenuVide": {} | undefined; } - -declare module "astro-i18n" { - export * from "astro-i18n/" - - export function l( - route: Uri | string & {}, - ...args: Uri extends keyof RouteParams - ? undefined extends RouteParams[Uri] - ? [params?: Record, targetLangCode?: LangCode, routeLangCode?: LangCode] - : [params: RouteParams[Uri], targetLangCode?: LangCode, routeLangCode?: LangCode] - : [params?: Record, targetLangCode?: LangCode, routeLangCode?: LangCode] - ): string - - export function t( - path: Path | string & {}, - ...args: undefined extends TranslationOptions[Path] - ? [options?: keyof TranslationOptions extends Path ? Record : TranslationOptions[Path], langCode?: LangCode] - : [options: TranslationOptions[Path], langCode?: LangCode] - ): string - - export function extractRouteLangCode(route: string): LangCode | undefined - - type Translation = string | { [translationKey: string]: string | Translation } - type Translations = { [langCode: string]: Record } - type RouteTranslations = { [langCode: string]: Record } - type InterpolationFormatter = (value: unknown, ...args: unknown[]) => string - class AstroI18n { - defaultLangCode: DefaultLangCode - supportedLangCodes: SupportedLangCode[] - showDefaultLangCode: boolean - translations: Translations - routeTranslations: RouteTranslations - get langCodes(): LangCode[] - get langCode(): LangCode - set langCode(langCode: LangCode) - get formatters(): Record - init(Astro: { url: URL }, formatters?: Record): void - addTranslations(translations: Translations): void - addRouteTranslations(routeTranslations: RouteTranslations): void - getFormatter(name: string): InterpolationFormatter | undefined - setFormatter(name: string, formatter: InterpolationFormatter): void - deleteFormatter(name: string): void - } - export const astroI18n: AstroI18n -} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..3947946 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +**/*.d.ts +eslintrc-auto-import.mjs diff --git a/.prettierrc.mjs b/.prettierrc.mjs new file mode 100644 index 0000000..18563a5 --- /dev/null +++ b/.prettierrc.mjs @@ -0,0 +1,34 @@ +/** @type {import("prettier").Config} */ + +const config = { + arrowParens: 'always', + bracketSameLine: false, + bracketSpacing: true, + embeddedLanguageFormatting: 'auto', + endOfLine: 'lf', + htmlWhitespaceSensitivity: 'css', + insertPragma: false, + jsxSingleQuote: true, + printWidth: 80, + proseWrap: 'preserve', + quoteProps: 'as-needed', + requirePragma: false, + semi: false, + singleAttributePerLine: false, + singleQuote: true, + tabWidth: 2, + trailingComma: 'none', + useTabs: true, + vueIndentScriptAndStyle: false, + plugins: ['prettier-plugin-organize-imports', 'prettier-plugin-astro'], + overrides: [ + { + files: '*.astro', + options: { + parser: 'astro' + } + } + ] +} + +export default config diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100755 index d642209..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "command": "./node_modules/.bin/astro dev", - "name": "Development server", - "request": "launch", - "type": "node-terminal" - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json index 91789b7..28ac688 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,17 +1,7 @@ { - "cssvar.files": [ - "./node_modules/open-props/open-props.min.css", - // if you have an alternative path to where your styles are located - // you can add it in this array of files - "assets/styles/variables.css" - ], - - // Do not ignore node_modules css files, which is ignored by default - "cssvar.ignore": [], - - // add support for autocomplete in JS or JS like files - "cssvar.extensions": [ - "css", "jsx", "tsx" - ], - "editor.formatOnSave": true -} \ No newline at end of file + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.insertSpaces": false, + "editor.detectIndentation": false, + "editor.tabSize": 2 +} diff --git a/astro.config.mjs b/astro.config.mjs index f3c1ce1..8bb12a7 100755 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -9,6 +9,10 @@ export default defineConfig({ site: "https://www.nardu.in", build: { format: "directory", + }, + i18n: { + locales: ["fr", "en"], + defaultLocale: "fr", }, image: { domains: ["assets.nardu.in"], diff --git a/astro.i18n.config.ts b/astro.i18n.config.ts deleted file mode 100755 index f349767..0000000 --- a/astro.i18n.config.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { defineAstroI18nConfig } from "astro-i18n"; - -export default defineAstroI18nConfig({ - defaultLangCode: "fr", - supportedLangCodes: ["en"], - showDefaultLangCode: false, - trailingSlash: "never", - translations: { - fr: "src/i18n/fr.json", - en: "src/i18n/en.json", - }, - routeTranslations: { - en: { - "sci-hub-blocage": "sci-hub-unblock", - fragments: "snippets", - "plan-du-site": "sitemap", - references: "work", - }, - }, -}); diff --git a/bun.lockb b/bun.lockb index 6519f634b8c3ee17add6c61fbf601145b8299768..44152a49937e42750d551455e4844b246724d021 100755 GIT binary patch delta 48579 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 Ro*l5(>bV#iw^+6Ae*w1l7&rg` delta 42112 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 locale !== astroI18n.langCode -); -// current path -const currentRoute = Astro.url.pathname; - -function localeName(locale) { - let localeName = ""; - switch (locale) { - case "fr": - localeName = "Français"; - break; - case "en": - localeName = "English"; - break; - } - return localeName; -} +import { languages } from '../i18n/ui' --- -