SuperHTML Documentation

repository·main·Indexed 23 days ago

https://github.com/kristoff-it/superhtml

A high-fidelity HTML validator, formatter, and Language Server Protocol (LSP) implementation focusing on strict adherence to the WHATWG HTML5 living spec. It provides deep validation for element nesting and attribute correctness. The toolset includes a CLI for checking and formatting, a Tree-Sitter grammar (tree-sitter-superhtml), and integrations for VSCode, BBEdit, Emacs, Neovim, and Vim.

Tokens
4.3K
Snippets
10
Records
26
Agent score
70%

What's inside SuperHTML

  1. Why SuperHTML requires closed `<li>` elements

    main
    Although the HTML spec allows some tags like <li> to be left unclosed (implicitly closing when a sibling is encountered), SuperHTML requires explicit closing tags. This is done to prevent ambiguity caused by typos; an unclosed tag might be a legitimate implicit closure or simply a developer error. SuperHTML prioritizes strictness to catch these errors.
  2. Understand SuperHTML Autoformatting Rules

    main

    The autoformatter manages horizontal and vertical alignment using two main rules:

    1. Whitespace between start tag and content: Controls whitespace between the element's start tag and its inner content.
    2. Whitespace between last attribute and closing >: Controls whitespace between the final attribute of a start tag and the closing bracket.

    Example Rule 1 (Content Alignment): Before:

    <div> <p>Foo</p></div>

    After:

    <div>
      <p>Foo</p>
    </div>

    Example Rule 2 (Attribute Alignment): Before:

    <div foo="bar" style="verylongstring" hidden >Foo</div>

    After:

    <div foo="bar"
         style="verylongstring"
         hidden
    >Foo</div>
  3. Why SuperHTML does not support self-closing tags

    main
    SuperHTML does not support self-closing tags (e.g., <div />) because they do not exist in the HTML spec. While browsers ignore the slash in void elements, using them on non-void elements (like <div>) can lead to incorrect DOM structures where subsequent elements are treated as children rather than siblings. SuperHTML enforces correct HTML behavior to prevent these common misconceptions.
  4. Add SuperHTML to Emacs via Eglot

    main

    You can integrate SuperHTML into Emacs using the built-in eglot client (available in Emacs 29+). To use this integration, ensure the superhtml binary is present in your $PATH.

    If you use a mode other than web-mode, substitute it in the configuration. The :language-id "html" property is required to ensure eglot correctly identifies the content type as HTML when communicating with the server.

    ;; Using use-package
    (use-package eglot
      :defer t
      :hook ((web-mode . eglot-ensure)
             )
      :config
      (add-to-list 'eglot-server-programs '((web-mode :language-id "html") . ("superhtml" "lsp"))))
  5. Configure SuperHTML LSP in BBEdit

    main

    To use SuperHTML as the Language Server Protocol (LSP) provider in BBEdit, you must override the default HTML language settings. This replaces the default vscode-html-languageserver with superhtml.

    1. Open BBEdit Settings (via BBEdit > Settings or ⌘+,).
    2. Navigate to the Languages tab.
    3. Select the Custom Settings sub-tab.
    4. If HTML is not already listed, click the + dropdown and select HTML.
    5. In the new sheet window, select the Server tab.
    6. Clear the existing html-languageserver and —stdio values.
    7. Enter superhtml in the Command text box.
    8. Enter lsp in the Arguments box.
    9. Verify a green checkmark appears indicating the server is ready.
    10. Click OK to apply settings.

    Once configured, SuperHTML will provide error and warning diagnostics for HTML documents opened in BBEdit.

  6. Configure SuperHTML for Neovim

    main

    To use SuperHTML in Neovim, download a prebuilt version of superhtml and ensure it is in your PATH. You can configure it using the built-in LSP client or LspZero.

    # Neovim Built-In
    vim.api.nvim_create_autocmd("Filetype", {
    	pattern = { "html", "shtml", "htm" },
    	callback = function()
    		vim.lsp.start({
    			name = "superhtml",
    			cmd = { "superhtml", "lsp" },
    			root_dir = vim.fs.dirname(vim.fs.find({".git"}, { upward = true })[1])
    		})
    	end
    })
    
    # LspZero
    local lsp = require("lsp-zero")
    
    require('lspconfig.configs').superhtml = {
    		default_config = {
    			name = 'superhtml',
    			cmd = {'superhtml', 'lsp'},
    			filetypes = {'html', 'shtml', 'htm'},
    			root_dir = require('lspconfig.util').root_pattern('.git')
    		}
    }
    
    lsp.configure('superhtml', {force_setup = true})
  7. Setup SuperHTML VSCode LSP

    main

    The SuperHTML VSCode extension provides a Language Server for HTML that performs syntax validation, element nesting checks, and attribute value validation.

    IMPORTANT: Disable Built-in HTML Extension

    To avoid conflicts with end tag suggestions, you must disable the built-in VSCode HTML extension. SuperHTML cannot disable these suggestions automatically. You can find manual instructions for disabling the built-in extension here.

  8. Validate and Format HTML with SuperHTML CLI

    main

    Use the check command to validate documents for syntax, element nesting, and attribute values. Use the fmt command to autoformat documents.

    Tip: Use superhtml fmt --check in your CI/CD pipelines to enforce that all changes are performed on normalized HTML files.

  9. Configure SuperHTML for Emacs without use-package

    main

    If you do not use use-package, you can configure SuperHTML for eglot by requiring the library and using with-eval-after-load to add the server program to the eglot-server-programs list.

    (require 'eglot)
    (with-eval-after-load 'eglot
      (add-to-list 'eglot-server-programs
                   `((web-mode :language-id "html") . ("superhtml" "lsp"))))
  10. Configure SuperHTML for Vim

    main

    You can use SuperHTML in Vim by setting makeprg for error checking via :make and formatprg for formatting via gq motions.

    " for any html file, a :make<cr> action will populate the quickfix menu
    autocmd filetype html setlocal makeprg=superhtml\ check\ %
    
    " if you want to use gq{motion} to format sections or the whole buffer (with gggqG)
    autocmd filetype html setlocal formatprg=superhtml\ fmt\ --stdin