HTMLProofer

repository·main·Indexed 23 days ago

https://github.com/gjtorikian/html-proofer

A Ruby-based validation tool for generated HTML output. It checks for broken internal and external links, missing image alt tags, valid favicons, and correct OpenGraph metadata. It can be used via a Ruby API or a command-line interface and is designed for integration into CI/CD pipelines with support for caching, custom checks, and parallel requests via Typhoeus.

Tokens
7.9K
Snippets
13
Records
32
Agent score
82%

What's inside html-proofer

  1. What HTMLProofer tests

    main

    HTMLProofer validates various aspects of your HTML output, including:

    • Images (img): Presence of alt tags, validity of internal references, visibility of external images, and ensuring images use HTTP/HTTPS.
    • Links (a, link): Functionality of internal links and internal hash references (#linkToMe), validity of external links, HTTPS usage, and CORS/SRI enablement.
    • Scripts (script): Validity of internal script references, loading of external scripts, and CORS/SRI enablement.
    • Favicon: Validity of favicon files.
    • OpenGraph: Validity of images and URLs within OpenGraph metadata.
  2. Ignore specific HTML elements

    main

    To prevent HTMLProofer from checking a specific element (and its children), add the data-proofer-ignore attribute to the tag.

    <!-- This link will not be checked -->
    <a href="https://notareallink" data-proofer-ignore>Not checked.</a>
    
    <!-- All children of this div will be ignored -->
    <div data-proofer-ignore>
      <a href="https://notareallink">Not checked because of parent.</a>
    </div>
    <a href="https://notareallink" data-proofer-ignore>Not checked.</a>
  3. Install HTMLProofer

    main

    You can install HTMLProofer as a Ruby gem.

    To add it to your application's Gemfile:

    gem 'html-proofer'

    Then run:

    bundle install

    Alternatively, install it directly via gem:

    gem install html-proofer

    Performance Tip: To increase installation speed in Continuous Integration (CI) builds, set the environment variable NOKOGIRI_USE_SYSTEM_LIBRARIES to true.

    gem 'html-proofer'
    $ bundle install
  4. Enable caching in Continuous Integration

    main

    To benefit from caching in CI, you must persist the tmp/.htmlproofer directory between builds.

    GitHub Actions: Add a cache step before running HTMLProofer. Note that you may need to append || true to the HTMLProofer command to prevent a failed check from stopping the entire workflow.

    - name: Cache HTMLProofer
      id: cache-htmlproofer
      uses: actions/cache@v2
      with:
        path: tmp/.htmlproofer
        key: ${{ runner.os }}-htmlproofer

    Travis CI: Add the directory to your .travis.yml configuration:

    cache:
      directories:
        - $TRAVIS_BUILD_DIR/tmp/.htmlproofer
  5. Configure Typhoeus options for SSL, User-Agent, and Cookies

    main

    HTML-Proofer uses Typhoeus for network requests. You can pass a typhoeus configuration hash in the options to customize behavior.

    Ignore SSL certificates

    HTMLProofer.check_directory("out/", {
      typhoeus: {
        ssl_verifypeer: false,
        ssl_verifyhost: 0,
      },
    }).run

    Set a custom User-Agent

    Ruby:

    HTMLProofer.check_directory("out/", {
      typhoeus: {
        headers: { "User-Agent" => "Mozilla/5.0 (compatible; My New User-Agent)" },
      }
    }).run

    CLI:

    htmlproofer --typhoeus='{"headers":{"User-Agent":"Mozilla/5.0 (compatible; My New User-Agent)"}}'

    Use Cookies

    HTMLProofer.check_directory("out/", {
      typhoeus: {
        cookiefile: ".cookies",
        cookiejar: ".cookies",
      },
    }).run

    CLI:

    htmlproofer --typhoeus='{"cookiefile":".cookies","cookiejar":".cookies"}'
  6. Enable and configure caching for link checks

    main

    To speed up tests and avoid rate limits, you can enable caching for external and internal links using the :cache option.

    Configuration:

    • :timeframe: A hash with :external and :internal keys. Values use suffixes: M (months), w (weeks), d (days), h (hours).
    • :cache_file: Filename for the cache (e.g., stay_cachey.json).
    • :storage_dir: Directory where the cache is kept.

    Note: Caching only applies to external links. Failed links are always rechecked.

    CLI Usage:

    htmlproofer --cache '{ "timeframe": { "external": "2w", "internal": "1w" } }'
  7. Configure HTMLProofer options

    main

    The HTMLProofer constructor accepts an optional hash of configuration options to customize how files are checked. Common options include:

    • checks: An array of Strings specifying which checks to run (e.g., ['Links', 'Images', 'Scripts']).
    • extensions: An array of file extensions to check (e.g., ['.html']).
    • ignore_files: An array of Strings or RegExps of file paths to skip.
    • ignore_urls: An array of Strings or RegExps of URLs to skip.
    • root_dir: The absolute path to the directory serving your HTML files.
    • enforce_https: If true, fails a link if it is not marked as https (default: true).
    • allow_hash_href: If true, assumes href="#" anchors are valid (default: true).
  8. Exclude URLs using regular expressions

    main

    To prevent certain URLs from being checked, provide an array of regular expressions to the ignore_urls option. Ensure the regexes are not quoted in the Ruby code.

    HTMLProofer.check_directories(["out/"], {
      ignore_urls: [/example.com/],
    }).run
  9. Use a custom reporter by inheriting from HTMLProofer::Reporter

    main

    By default, HTML-Proofer prints errors to the console at the end of a run. To implement custom reporting behavior (e.g., sending results to an external service or a different file format), create a subclass of HTMLProofer::Reporter and implement the report method.

    You can assign your reporter to the proofer instance before calling .run.

    proofer = HTMLProofer.check_directory(item, opts)
    proofer.reporter = MyCustomReporter.new(logger: proofer.logger)
    proofer.run
  10. Map URLs and Attributes with swap_urls and swap_attributes

    main

    If your HTML content uses different URLs or attribute names than what is actually served by your server, you can use swapping mechanisms.

    URL Swapping

    Use swap_urls to map a pattern (RegEx) to a replacement string. This is useful for placeholder URLs or handling baseurl in Jekyll.

    # Example: mapping a placeholder domain to the real domain
    run_proofer(file, :file, swap_urls: { %r{^https//placeholder.com} => "https://website.com" })

    Attribute Swapping

    Use swap_attributes to tell HTMLProofer to treat one attribute as another. This is useful for lazy-loading implementations where data-src is used instead of src.

    # Example: treating 'data-src' as 'src' for img tags
    run_proofer(file, :file, swap_attributes: { "img"  => [["data-src", "src"]] })
    run_proofer(file, :file, swap_urls: { %r{^https//placeholder.com} => "https://website.com" })
    run_proofer(file, :file, swap_attributes: { "img"  => [["data-src", "src"]] })
  11. Inspect the underlying Nokogiri node from a failure

    main

    If you need deep access to the HTML structure of a failed element, use the element method on an HTMLProofer::Failure object. This returns an HTMLProofer::Element which provides:

    • node: The raw Nokogiri node.
    • a_tag?: Returns true if the element is an <a> tag.
    • img_tag?: Returns true if the element is an <img> tag.
    • content: The text content of the element.
    • line: The line number.
    proofer.failed_checks.each do |failure|
      element = failure.element
      next if element.nil?
    
      # Access the Nokogiri node directly
      node = element.node
      puts "Tag name: #{node.name}"
      puts "Href: #{node['href']}"
      puts "All attributes: #{node.attributes.keys}"
    
      # Use helper methods
      puts "Is anchor tag: #{element.a_tag?}"
      puts "Is image tag: #{element.img_tag?}"
      puts "Link text: #{element.content}"
      puts "Line number: #{element.line}"
    end