Skip to content
Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

Linkinator Action

Find broken links in Markdown, HTML, and websites—directly in GitHub Actions.

Linkinator Action is the GitHub Actions wrapper for Linkinator. It checks local documentation and remote URLs, annotates failures in the workflow log, and writes a readable job summary.

Linkinator Action

Quick start

Add .github/workflows/links.yml to your repository:

name: Check linkson:
pull_request:
push:
branches: [main]jobs:
linkinator:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v7
- uses: JustinBeckwith/linkinator-action@v2

That is it. By default, the action checks Markdown files matching *.md in the repository root and fails the job when it finds a broken link.

To scan every Markdown file in the repository:

- uses: JustinBeckwith/linkinator-action@v2with:
paths: '**/*.md'

What you get

  • Broken-link annotations in the workflow log
  • A GitHub Actions job summary grouped by source file
  • Support for local files, remote pages, redirects, fragments, and CSS URLs
  • Configurable retries, timeouts, status-code policies, and skip patterns
  • A machine-readable results output for later workflow steps

Common recipes

Check anchors and fragments

Fragment checking is opt-in because it requires downloading and parsing page content:

- uses: JustinBeckwith/linkinator-action@v2with:
paths: '**/*.md'checkFragments: true

Skip unreliable or private URLs

linksToSkip accepts comma- or whitespace-separated regular expressions. Skip rules are matched against the complete URL, including fragments.

- uses: JustinBeckwith/linkinator-action@v2with:
paths: '**/*.md'linksToSkip: >- ^https://example\.com/private ^https://(?:www\.)?ghostbrowser\.com(?:/|$) .*#L[0-9]+(?:-L[0-9]+)?$

skip is supported as an alias for linksToSkip.

Retry transient failures

- uses: JustinBeckwith/linkinator-action@v2with:
paths: '**/*.md'timeout: 15000retry: trueretryErrors: trueretryErrorsCount: 3retryErrorsJitter: 2000

retry handles HTTP 429 responses with a retry-after header. retryErrors handles network errors and 5xx responses.

Customize status-code handling

Map an exact status or a status family to ok, warn, skip, or error:

- uses: JustinBeckwith/linkinator-action@v2with:
statusCodes: '{"403":"warn","429":"skip","5xx":"warn"}'

Enforce HTTPS and flag redirects

- uses: JustinBeckwith/linkinator-action@v2with:
requireHttps: errorredirects: warn

requireHttps accepts off, warn, or error. The boolean values true and false are aliases for error and off. redirects accepts allow, warn, or error.

Check a website recursively

- uses: JustinBeckwith/linkinator-action@v2with:
paths: https://example.comrecurse: trueconcurrency: 20

Recursive scans follow links on the same root domain. Use a reasonable concurrency value when scanning a site you do not control.

Check CSS URLs

- uses: JustinBeckwith/linkinator-action@v2with:
paths: publiccheckCss: true

This extracts URLs from CSS files, <style> blocks, and inline styles.

Support clean URLs and directory links

- uses: JustinBeckwith/linkinator-action@v2with:
paths: docscleanUrls: truedirectoryListing: true

cleanUrls lets a link such as /about resolve to about.html. directoryListing lets local links to directories resolve through an automatically generated directory index and defaults to true.

Rewrite URLs in pull requests

The action automatically rewrites matching GitHub blob and tree links from the base branch to the pull request branch. You can also define one custom rewrite:

- uses: JustinBeckwith/linkinator-action@v2with:
urlRewriteSearch: '^https://docs\.example\.com/'urlRewriteReplace: 'https://preview.example.com/'

Both rewrite inputs must be provided together.

Configuration file

For a larger configuration, add linkinator.config.json to the repository:

{
"recurse": false,
"concurrency": 20,
"skip": [
"^https://example\\.com/private",
"^mailto:"
],
"statusCodes": {
"403": "warn",
"429": "skip",
"5xx": "warn"
}
}

Then reference it from the workflow:

- uses: JustinBeckwith/linkinator-action@v2with:
paths: '**/*.md'config: linkinator.config.json

Values supplied directly to the action take precedence over the configuration file. See the Linkinator API options for the underlying configuration format.

Inputs

InputDefaultDescription
paths*.mdComma- or whitespace-separated paths, globs, directories, or URLs to scan.
configlinkinator.config.json when presentPath to a Linkinator configuration file.
concurrency100Maximum number of concurrent requests.
recursefalseFollow same-domain links recursively.
linksToSkipComma- or whitespace-separated URL regular expressions to skip.
skipAlias for linksToSkip.
timeout0Request timeout in milliseconds; 0 disables the action-level timeout.
markdowntrueParse Markdown when scanning local files.
serverRootrepository rootRoot from which local files are served.
directoryListingtrueGenerate directory listings for local directory links.
retryfalseRetry 429 responses that include retry-after.
retryErrorsfalseRetry network errors and 5xx responses.
retryErrorsCount3Maximum retries for network errors and 5xx responses.
retryErrorsJitter2000Maximum retry-delay jitter in milliseconds.
userAgentLinkinator defaultCustom HTTP User-Agent header.
verbosityWARNINGOne of DEBUG, INFO, WARNING, ERROR, or NONE.
urlRewriteSearchRegular expression used for a custom URL rewrite.
urlRewriteReplaceReplacement used with urlRewriteSearch.
allowInsecureCertsfalseAllow invalid or self-signed TLS certificates.
requireHttpsfalse (off)HTTPS policy: off, warn, or error.
cleanUrlsfalseResolve extensionless local links to .html files.
checkCssfalseExtract and check URLs found in CSS.
checkFragmentsfalseValidate fragment identifiers and anchors.
statusCodesLinkinator defaultsJSON object mapping statuses or families to ok, warn, skip, or error.
redirectsallowRedirect policy: allow, warn, or error.

Boolean inputs should be written as true or false. See action.yml for the canonical action metadata.

Outputs

The action exposes the full Linkinator result as results:

- id: linksuses: JustinBeckwith/linkinator-action@v2
- name: Inspect resultsif: always()env:
LINKINATOR_RESULTS: ${{ steps.links.outputs.results }}run: echo "$LINKINATOR_RESULTS"

The result includes the overall pass/fail state and each checked link's URL, status, state, parent, and failure details.

Troubleshooting

A valid URL reports a network failure

The action reports the underlying transport cause when available, such as ENOTFOUND, ECONNREFUSED, or a timeout. These failures can be specific to automated clients or GitHub-hosted runners.

  1. Add a reasonable timeout and enable retryErrors for transient services.
  2. Set verbosity: DEBUG to include complete error and cause details.
  3. Add persistently bot-protected or unreliable domains to linksToSkip.

Relative directory links return 404

Keep directoryListing: true when local documentation links to directories without an index file. If links are resolved from the wrong location, set serverRoot to the directory that represents the site's root.

A skip pattern does not match

Skip values are regular expressions, not shell globs. Quote patterns in YAML, escape literal dots (example\.com), and remember that inputs are split on commas and whitespace. Use a configuration file when a pattern itself must contain either delimiter.

I need more logging

Set verbosity: DEBUG. To include GitHub runner diagnostics as well, enable debug logging in GitHub Actions.

Versioning and security

Use the moving major tag for automatic compatible updates:

- uses: JustinBeckwith/linkinator-action@v2

For a fully immutable workflow, pin the action to a commit SHA and let a dependency updater manage it. The action runs on the Node.js runtime bundled by GitHub Actions; consumers do not need to install Node.js themselves.

Contributing

Issues and pull requests are welcome. For changes to the underlying checker, visit the Linkinator repository.

License

MIT

About

A GitHub Action that checks your README and other markdown for 404s.

Resources

Stars

42 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages