diff --git a/package.json b/package.json index c23a406b8c55e..d699db8fb99af 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "canvaskit-wasm": "^0.37.0", "chroma-js": "^2.4.2", "dedent-js": "^1.0.1", + "domhandler": "^4.3.1", "eslint": "^8.21.0", "eslint-plugin-astro": "^0.14.0", "fast-glob": "^3.2.11", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eb51a058a946c..3052d9f71fb3d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,7 @@ specifiers: canvaskit-wasm: ^0.37.0 chroma-js: ^2.4.2 dedent-js: ^1.0.1 + domhandler: ^4.3.1 eslint: ^8.21.0 eslint-plugin-astro: ^0.14.0 fast-glob: ^3.2.11 @@ -101,6 +102,7 @@ devDependencies: canvaskit-wasm: 0.37.0 chroma-js: 2.4.2 dedent-js: 1.0.1 + domhandler: 4.3.1 eslint: 8.21.0 eslint-plugin-astro: 0.14.0_eslint@8.21.0 fast-glob: 3.2.11 diff --git a/scripts/lib/linkcheck/checks/good-link-label.ts b/scripts/lib/linkcheck/checks/good-link-label.ts new file mode 100644 index 0000000000000..514bb4c05ebfe --- /dev/null +++ b/scripts/lib/linkcheck/checks/good-link-label.ts @@ -0,0 +1,38 @@ +import { DomUtils } from 'htmlparser2'; +import kleur from 'kleur'; +import { dedentMd } from '../../output.mjs'; +import { CheckBase, CheckHtmlPageContext } from '../base/check'; +import { IssueType } from '../base/issue'; + +/** List of labels that are insufficiently descriptive for a link. */ +const blocklist = new Set(['read more', 'click here', 'here', 'more']); + +export class GoodLabels extends CheckBase { + private static readonly BadLabel = new IssueType({ + title: 'link(s) with vague or nondescript labels', + prefix: kleur.gray(`[${kleur.yellow().bold('lbl')}]`), + sortOrder: 1000, + }); + + checkHtmlPage(context: CheckHtmlPageContext) { + // Skip all checks if the current page is a language fallback page + // to avoid reporting duplicates for all missing translations + if (context.page.isLanguageFallback) return; + + context.page.anchors.forEach((anchor) => { + const linkLabel = DomUtils.innerText(anchor) + .replace(/[\n\s\t]+/g, ' ') + .trim(); + + if (!blocklist.has(linkLabel.toLowerCase())) return; + + context.report({ + type: GoodLabels.BadLabel, + linkHref: anchor.attribs.href, + annotationText: dedentMd`Found link label “${linkLabel}”. + Please use descriptive accessible text for labels instead + of short undescriptive labels like “here” or “read more”.`, + }); + }); + } +} diff --git a/scripts/lint-linkcheck.ts b/scripts/lint-linkcheck.ts index ec43389c93142..5226d85c9ebab 100644 --- a/scripts/lint-linkcheck.ts +++ b/scripts/lint-linkcheck.ts @@ -1,5 +1,6 @@ import { LinkCheckerOptions, LinkCheckerState } from './lib/linkcheck/base/base'; import { CanonicalUrl } from './lib/linkcheck/checks/canonical-url'; +import { GoodLabels } from './lib/linkcheck/checks/good-link-label'; import { RelativeUrl } from './lib/linkcheck/checks/relative-url'; import { SameLanguage } from './lib/linkcheck/checks/same-language'; import { TargetExists } from './lib/linkcheck/checks/target-exists'; @@ -76,6 +77,7 @@ const linkChecker = new LinkChecker({ ignoreMissingCanonicalUrl: ['/lighthouse/'], }), new RelativeUrl(), + new GoodLabels(), ], autofix: process.argv.includes('--autofix') || Boolean(process.env.npm_config_autofix), }); diff --git a/src/pages/en/guides/deploy/buddy.md b/src/pages/en/guides/deploy/buddy.md index 59c4460504b9f..a609430dcbc19 100644 --- a/src/pages/en/guides/deploy/buddy.md +++ b/src/pages/en/guides/deploy/buddy.md @@ -13,7 +13,7 @@ Buddy itself will not host your site. Instead, it helps you manage the build pro ## How to deploy -1. Create a **Buddy** account [here](https://buddy.works/sign-up). +1. [Create a **Buddy** account](https://buddy.works/sign-up). 2. Create a new project and connect it with a git repository (GitHub, GitLab, BitBucket, any private Git Repository or you can use Buddy Git Hosting). 3. Add a new pipeline. 4. In the newly created pipeline add a **[Node.js](https://buddy.works/actions/node-js)** action. @@ -24,5 +24,5 @@ Buddy itself will not host your site. Instead, it helps you manage the build pro npm run build ``` -6. Add a deployment action — there are many to choose from, you can browse them [here](https://buddy.works/actions). Although their settings can differ, remember to set the **Source path** to `dist`. +6. Add a deployment action — there are many to choose from, you can browse them in [Buddy’s actions catalog](https://buddy.works/actions). Although their settings can differ, remember to set the **Source path** to `dist`. 7. Press the **Run** button.