eleventy-plugin-broken-links v2.2.1
eleventy-plugin-broken-links
Table of contents
Overview
This is an 11ty plugin to check for broken external links after a build.
Currently it only checks external links, but checking internal links might be added at some point.
Features
- caching using
eleventy-fetch
- excluding URLs
- control of level of logging
- warn or error on broken, redirected or forbidden links
- exclude certain URLs or wildcards
- exclude certain input files or globs
Dependencies
Under the hood, the plugin uses:
node-html-parser
to parse build output and gather linkseleventy-fetch
to cache resultsminimatch
to handle globbing for excluded input fileskleur
for log coloring / formattingvalid-url
to check if it's a valid uri
Usage
1. Install the plugin
NPM:
npm i -D eleventy-plugin-broken-links
Yarn:
yarn add -D eleventy-plugin-broken-links
2. Add plugin to .eleventy.js
config
const brokenLinksPlugin = require("eleventy-plugin-broken-links");
module.exports = (eleventyConfig) => {
eleventyConfig.addPlugin(brokenLinksPlugin);
// ... the rest of your config
};
3. Add .cache
to .gitignore
See this privacy notice in the eleventy-fetch
docs
about why we should ignore the .cache
directory. Unless you really know
what you're doing, it's probably a good idea.
.cache/
# ... the rest of your `.gitignore`
(4. Set options)
There are currently 7 possible keys to the optional options
object passed
with eleventyConfig.addPlugin()
:
Option | Default | Accepted values | Description |
---|---|---|---|
forbidden | "warn" | "warn" , "error" | Whether to warn or throw an error |
broken | "warn" | "warn" , "error" | (same as above) |
redirect | "warn" | "warn" , "error" | (same as above) |
cacheDuration | "1d" | any value accepted by eleventy-fetch | Set the duration of the cache |
loggingLevel | 2 | Integer 0 (silent) to 3 (all) | Set the logging level |
excludeUrls | ['http://localhost*', 'https://localhost*'] | Array of URL strings | Exclude specific URLs or wildcards |
excludeInputs | [] | Array of globs, relative to eleventyConfig.dir.input value | Exclude input files / globs |
callback | null | null or a function with signature (brokenLinks, redirectLinks) => {} | Custom callback after checking links |
Here's an example using all options, with the defaults:
const brokenLinksPlugin = require("eleventy-plugin-broken-links");
module.exports = (eleventyConfig) => {
// ... the rest of your config
eleventyConfig.addPlugin(brokenLinksPlugin, {
forbidden: "warn",
redirect: "warn",
broken: "warn",
cacheDuration: "1d",
loggingLevel: 2,
excludeUrls: [],
excludeInputs: [],
callback: null,
});
};
NOTE: If the broken
, redirect
or forbidden
options are set to error
, your
build will not be successful if there are broken/redirected links!
Options
broken
, redirect
and forbidden
- Default:
"warn"
- Accepted:
"warn"
or"error"
Whether to warn
or error
if broken, redirect or forbidden links are found. If error
,
builds will not succeed if any are found.
cacheDuration
- Default:
"1d"
- Accepted: Anything accepted by
eleventy-fetch
plugin
Sets the cache duration for checking URL status codes. See the
eleventy-fetch
plugin docs
for more info.
loggingLevel
- Default:
2
- Accepted: Integer
0
to3
Level | Result |
---|---|
0 | Silent |
1 | Only log broken links |
2 | Only log broken and redirect links |
3 | All (verbose) |
excludeUrls
- Default:
['http://localhost*', 'https://localhost*']
(new in2.0.0
) - Accepted: Array of URL strings
You can exclude specific URLs by specifying their fully-qualified uri:
excludeUrls: ["https://example.com"];
But you can also use a wildcard (*
) to exclude domains or sub-paths. Examples:
"https://example.com"; // excludes only the root URL,
// but sub-paths will be include,
// e.g. 'https://example.com/about'
"https://example.com/about"; // excludes only '/about', but root and other
// pages are included
"https://example.com/about/*"; // excludes any path nested under 'about',
// but includes 'about'
"https://example.com/about*"; // excludes any sub-path that begins
// with `about`, INCLUDING all nested paths
"https://example.com/*"; // excludes all paths, but includes the root
"https://example.com*"; // excludes the root and all paths
Note that the URLs specified need to be fully-qualified, so sub-domains need to be explicitly indicated.
excludeInputs
- Default:
[]
- Accepted: Array of files or globs, relative to
dir.input
You can exclude specific input files by providing an array of files or globs.
Please note:
- All files and globs are relative to the config
dir.input
value - Leading "dot-slash" (
./
) is optional, and is stripped from the input filenames andexcludeInputs
values when normalized before processing
To illustrate these points:
// - `dir.input` not set in config (`undefined`)
["index.md"]["./index.md"][ // exclude only ./index.md // identical to above
// - `dir.input` = "src":
"index.md"
]; // exclude ./src/index.md
Globbing is handled by minimatch
under the hood. Some examples:
// Some globbing examples:
["**/index.md"]["**/*.md"]["notes/**"]["**/./*.md"]["**/+(foo|bar).md"]; // exclude all index.md files recursively // exclude all .md files recursively // exclude all files recursively in 'notes' // exclude all .md files in subdirectories only // exclude all files named "foo.md" or "bar.md"
callback
- Default:
null
- Accepted:
null
or a function with signature(brokenLinks, redirectLinks, forbiddenLinks) => {}
Custom callback for handling broken, redirect or forbidden links after checking and
logging results (and before throwing an error, if option is set). The three
arguments, brokenLinks
, redirectLinks
and forbiddenLinks
are arrays of instances of the
ExternalLink
class,
which has the following methods and properties:
url
propertygetHttpStatusCode()
, which returns the HTTP status codegetPages()
which returns an array of EleventyinputPath
filenamesgetLinkCount()
, which returns the number of times the link is used in the site's pages
This allows for integration with third-party services, webhooks, etc. Here's a basic example:
// your project's .eleventy.js:
const thirdPartyService = require("service");
const brokenLinksPlugin = require("eleventy-plugin-broken-links");
module.exports = (eleventyConfig) => {
eleventyConfig.addPlugin(brokenLinksPlugin, {
callback: (brokenLinks, redirectLinks) => {
thirdPartyService.post({
msg: `Your eleventy build had broken links! Links: ${brokenLinks.map(link => link.url).join(", ")}`,
});
},
});
};
Roadmap / Contributing
I don't have a specific roadmap or timeline for this project, but here is a general idea of what the next steps are. If you would like to contribute, please feel free to file an issue or feature request, or send a PR.
- cache results (added in
v1.1.0
) - allow control over logging (added in
v1.3.0
) - add option to exclude certain urls (added in
v1.4.0
) - add option to exclude certain input files (added in
v1.5.0
) - add debugging using
debug
to hook into theDEBUG=Eleventy*
workflow (Added inv2.0.0
) - check internal links
11 days ago
11 days ago
20 days ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago