Skip to main content

This version of GitHub Enterprise Server was discontinued on 2023-09-25. No patch releases will be made, even for critical security issues. For better performance, improved security, and new features, upgrade to the latest version of GitHub Enterprise Server. For help with the upgrade, contact GitHub Enterprise support.

Using the content linter

You can use content linter to check your contributions for errors.

Articles in the "Contributing to GitHub Docs" section refer to the documentation itself and are a resource for GitHub staff and open source contributors.

About the GitHub Docs content linter

Our content linter enforces style guide rules in our Markdown content.

The linter uses markdownlint as the framework to perform checks, report flaws, and automatically fix content, when possible. This framework flexibly runs specific rules, gives descriptive error messages, and fixes errors. The GitHub Docs content linter uses several existing markdownlint rules and additional custom rules to check the Markdown content in our content and data directories. Our custom rules implement checks that are either not yet available in the markdownlint framework or are specific to GitHub Docs content. Rules check the syntax for both Markdown and Liquid.

Running the GitHub Docs content linter

The GitHub Docs content linter will run automatically on pre-commit, but you can also run it manually.

Automatically run the linter on pre-commit

When you are writing content locally and committing files using the command line, those staged files will automatically be linted by the content linter. Both warnings and errors are reported, but only errors will prevent your commit from completing.

If any errors are reported, your commit will not complete. You will need to fix the reported errors, re-add the changed files, and commit your changes again. Any errors that are reported must be fixed to prevent introducing errors in the content that are in violation of the GitHub Docs style guide. If any warnings are reported, you can optionally choose to fix them or not.

When you are writing content locally, there are several rules that you can fix automatically using the command line. If you want to automatically fix errors that can be fixed, see "Automatically fix errors that can be fixed."

If you are editing a file in the GitHub UI, you will not be able to automatically fix errors or run the linter on a commit, but you will get a CI failure if the content violates any rules with a severity of error.

Manually run the linter

Run the linter on staged and changed files

Use the following command to run the linter locally on your staged and changed files. It will output both warning and error severity flaws.

npm run lint-content

Run the linter on staged and changed files and only report errors

Use the following command to run the linter locally on your staged and changed files, and report only error severity flaws.

npm run lint-content -- --errors

Run the linter on specific files or directories

Use the following command to run the linter locally on specific files or directories. Separate multiple paths with a space. You can include both files and directories in the same command.

npm run lint-content -- \
  --paths content/ content/DIRECTORY

Automatically fix errors that can be fixed

If an error has fixable: true in its description, you can use the following commands to automatically fix them.

Run this command to fix staged and changed files only:

npm run lint-content -- --fix

Run this command to fix specific files or directories:

npm run lint-content -- \
  --fix --paths content/ content/DIRECTORY

Run a specific set of linter rules

Use the following command to run one or more specific linter rules. These examples run the heading-increment and code-fence-line-length rules. Replace heading-increment code-fence-line-length with one or more linter aliases that you would like to run. To see the list of linter rules you can pass to this option, run npm run lint-content -- --help. You can use either the short name (for example, MD001) or long name (for example, heading-increment) of a linter rule.

Run the specified linter rules on all staged and changed files:

npm run lint-content -- \
  --rules heading-increment code-fence-line-length

Run the specified linter rules on specific files or directories:

npm run lint-content -- \
  --rules heading-increment code-fence-line-length \
  --path content/ content/DIRECTORY

Bypass the commit hook

If the linter catches errors that you did not introduce, you can bypass the git commit hook by using the --no-verify option when you commit your changes.

git commit -m 'MESSAGE' --no-verify

Display the help menu for the content linter script

npm run lint-content -- --help

Linting rules

Each rule is configured in a file in src/content-linter/style, which is where the severities of rules are defined.

Errors must be addressed before merging your changes to the main branch. Warnings should be addressed but do not prevent a change from being merged into the main branch. Most rules will eventually be promoted to errors, once the content no longer has warning violations.

Rule IDRule Name(s)DescriptionSeverityTags
MD001heading-increment, header-incrementHeading levels should only increment by one level at a timeerrorheadings, headers
MD002first-heading-h1, first-header-h1First heading should be a top-level headingerrorheadings, headers
MD004ul-styleUnordered list styleerrorbullet, ul
MD009no-trailing-spacesTrailing spaceserrorwhitespace
MD011no-reversed-linksReversed link syntaxerrorlinks
MD012no-multiple-blanksMultiple consecutive blank lineserrorwhitespace, blank_lines
MD014commands-show-outputDollar signs used before commands without showing outputerrorcode
MD018no-missing-space-atxNo space after hash on atx style headingerrorheadings, headers, atx, spaces
MD019no-multiple-space-atxMultiple spaces after hash on atx style headingerrorheadings, headers, atx, spaces
MD022blanks-around-headings, blanks-around-headersHeadings should be surrounded by blank lineserrorheadings, headers, blank_lines
MD023heading-start-left, header-start-leftHeadings must start at the beginning of the lineerrorheadings, headers, spaces
MD027no-multiple-space-blockquoteMultiple spaces after blockquote symbolerrorblockquote, whitespace, indentation
MD029ol-prefixOrdered list item prefixerrorol
MD030list-marker-spaceSpaces after list markerserrorol, ul, whitespace
MD031blanks-around-fencesFenced code blocks should be surrounded by blank lineserrorcode, blank_lines
MD037no-space-in-emphasisSpaces inside emphasis markerserrorwhitespace, emphasis
MD039no-space-in-linksSpaces inside link texterrorwhitespace, links
MD040fenced-code-languageFenced code blocks should have a language specifiederrorcode, language
MD042no-empty-linksNo empty linkserrorlinks
MD047single-trailing-newlineFiles should end with a single newline charactererrorblank_lines
MD049emphasis-styleEmphasis style should be consistenterroremphasis
MD050strong-styleStrong style should be consistenterroremphasis
search-replacetodocs-placeholderCatch occurrences of TODOCS placeholder.error
search-replacedocs-domainCatch occurrences of domain.warning
search-replacehelp-domainCatch occurrences of domain.error
search-replacepreview-domainCatch occurrences of domain.error
search-replacedeveloper-domainCatch occurrences of domain.error
search-replacedeprecated liquid syntax: site.dataCatch occurrences of deprecated liquid data syntax.error
search-replacedeprecated liquid syntax: octicon-The octicon liquid syntax used is deprecated. Use this format instead octicon "<octicon-name>" aria-label="<Octicon aria label>"error
GH001no-default-alt-textImages should have meaningful alternative text (alt text)erroraccessibility, images
GH002no-generic-link-textAvoid using generic link text like Learn more or Click hereerroraccessibility, links
GHD030code-fence-line-lengthCode fence lines should not exceed a maximum lengthwarningcode, accessibility
GHD032image-alt-text-end-punctuationAlternate text for images should end with punctuationerroraccessibility, images
GHD004image-file-kebab-caseImage file names must use kebab-caseerrorimages
GHD033incorrect-alt-text-lengthImages alternate text should be between 40-150 characterswarningaccessibility, images
GHD002internal-links-no-langInternal links must not have a hardcoded language codeerrorlinks, url
GHD003internal-links-slashInternal links must start with a /errorlinks, url
GHD031image-alt-text-exclude-wordsAlternate text for images should not begin with words like "image" or "graphic"erroraccessibility, images
GHD034list-first-word-capitalizationFirst word of list item should be capitalizedwarningul, ol
GHD001link-punctuationInternal link titles must not contain punctuationerrorlinks, url
GHD008early-access-referencesFiles that are not early access should not reference early-access or early-access fileserrorfeature, early-access
GHD021yaml-scheduled-jobsYAML snippets that include scheduled workflows must not run on the hour and must be uniqueerrorfeature, actions
GHD006internal-links-old-versionInternal links must not have a hardcoded version using old versioning syntaxerrorlinks, url, versioning
GHD005hardcoded-data-variableStrings that contain "personal access token" should use the product variable insteaderrorsingle-source
GHD013github-owned-action-referencesGitHub-owned action references should not be hardcodederrorfeature, actions
GHD016liquid-quoted-conditional-argLiquid conditional tags should not quote the conditional argumenterrorliquid, format
GHD014liquid-data-references-definedLiquid data or indented data references were found in content that have no value or do not exist in the data directoryerrorliquid
GHD015liquid-data-tag-formatLiquid data or indented data references tags must have the correct number of arguments and spacingerrorliquid, format
GHD010frontmatter-hidden-docsArticles with frontmatter property hidden can only be located in specific productserrorfrontmatter, feature, early-access
GHD009frontmatter-early-access-referencesFiles that are not early access should not have frontmatter that references early-accesserrorfrontmatter, feature, early-access
GH011frontmatter-video-transcriptsVideo transcript must be configured correctlyerrorfrontmatter, feature, video-transcripts
GHD012frontmatter-schemaFrontmatter must conform to the schemaerrorfrontmatter, schema
GHD007code-annotationsCode annotations defined in Markdown must contain a specific layout frontmatter propertyerrorcode, feature, annotate, frontmatter
GHD017frontmatter-liquid-syntaxFrontmatter properties must use valid Liquiderrorliquid, frontmatter
GHD018liquid-syntaxMarkdown content must use valid Liquiderrorliquid
GHD019liquid-if-tagsLiquid ifversion tags should be used instead of if tags when the argument is a valid versionerrorliquid, versioning
GHD020liquid-ifversion-tagsLiquid ifversion tags should contain valid version names as argumentserrorliquid, versioning

Suppressing linter rules

Rarely, you may need to document something that violates one or more linter rules. In these cases, you can suppress rules by adding a comment to the Markdown file. You can disable all rules or specific rules. Always try to limit as few rules as possible. You can disable a rule for an entire file, for a section of a Markdown file, a specific line, or the next line.

For example, if you are writing an article that includes the regular expression (^|/)[Cc]+odespace/ that checks for reversed link syntax, it will trigger the MD011 rule that checks for reversed links. You can disable the rule MD011 on that specific line by adding the following comment.

(^|/)[Cc]+odespace/ <!-- markdownlint-disable-line MD011 -->

If the line you're trying to ignore is in a code block, you can ignore the code block by surrounding it with the following comments.

<!-- markdownlint-disable MD011 -->
<!-- markdownlint-enable MD011 -->

You can use these comments to enable or disable rules.

<!-- markdownlint-disable -->
Disable all rules
<!-- markdownlint-enable -->
Enable all rules
<!-- markdownlint-disable-line -->
Disable all rules for the current line
<!-- markdownlint-disable-next-line -->
Disable all rules for the next line
<!-- markdownlint-disable RULE-ONE RULE-TWO -->
Disable one or more rules by name
<!-- markdownlint-enable RULE-ONE RULE-TWO -->
Enable one or more rules by name
<!-- markdownlint-disable-line RULE-NAME -->
Disable one or more rules by name for the current line
<!-- markdownlint-disable-next-line RULE-NAME -->
Disable one or more rules by name for the next line