GitHub

HTML Validator, Formatter, LSP, and Templating Language Library

SuperHTML CLI Tool

The SuperHTML CLI Tool offers validation and autoformatting features for HTML files.

The tool can be used either directly (for example by running it on save), or through a LSP client implementation.

$ superhtml
Usage: superhtml COMMAND [OPTIONS]
Commands:
  check         Check documents for errors.
  fmt           Format documents.
  lsp           Start the Language Server.
  help          Show this menu and exit.
  version       Print the version and exit.
General Options:
  --help, -h        Print command specific usage.
  --syntax-only     Disable HTML element and attribute validation.

Warning

SuperHTML only supports HTML5 (the WHATWG living spec) regardless of what you put in your doctype (a warning will be generated for unsupported doctypes).

Warning

Templated HTML (Jinja2, Angular, Mustache, ...) is not yet supported when all validation rules are enabled, use --syntax-only (or the relative Extension Setting in VSCode) to limit validation to syntax errors to use SuperHTML with templated HTML documents.

Compatibility with popular templating languages is being explored.

Diagnostics

SuperHTML validates not only syntax but also element nesting and attribute values. No other language server implements the full HTML spec in its validation code.

Autoformatting

The autoformatter has two main ways of interacting with it in order to request for horizontal / vertical alignment.

  1. Adding / removing whitespace between the start tag of an element and its content.
  2. Adding / removing whitespace between the last attribute of a start tag and the closing >.

Tip

Consider using superhtml fmt --check in your CI to enforce every change to be performed on normalized HTML files. This is a technique commonly used in Zig (and Go) for source code that can also help streamline frontend development.

Example of rule #1

Before:

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

After:

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

Reverse

Before:

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

After:

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

Example of rule #2

Before:

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

After:

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

Reverse

Before:

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

After:

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

Download

See the Releases section here on GitHub.

Editor support

VSCode

Install the Super HTML VSCode extension (doesn't require the CLI tool as it bundles a WASM build of the language server).

Neovim

  1. Download a prebuilt version of superhtml from the Releases section (or build it yourself).

  2. Put superhtml in your PATH.

  3. Configure superhtml for your chosen lsp

    • 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})

Helix

In versions later than 24.07 superhtml is supported out of the box, simply add executable to your PATH.

Flow Control

Already defaults to using SuperHTML, just add the executable to your PATH.

Vim

Vim should be able to parse the errors that superhtml check [PATH] generates. This means that you can use :make and the quickfix window to check for syntax errors.

Set the makeprg to the following in your .vimrc:

" 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

Zed

See WeetHet/superhtml-zed.

Other editors

Follow your editor specific instructions on how to define a new Language Server for a given language / file format.

(Also feel free to contribute more specific instructions to this readme / add files under the editors/ subdirectory).

FAQs

Why doesn't SuperHTML support self-closing tags?

Because self-closing tags don't exist in HTML and, while harmless when used with void elements, it just keeps misleating people into thinking that you can self-close HTML tags.

In particular, given this HTML code:

<!doctype html>
<html>
  <head></head>
  <body>
    <div/>
    <p></p>
  </body>
</html>

You might think that <div> and <p> are siblings, while in reality browsers are required by the spec to ignore the self-closing slash in <div/>, making <p> a child, not a sibling of it.

Add to that the fact that tooling like the default HTML formatter in VSCode will provide misleading autoformatting (try it yourself, disable SuperHTML in VSCode and autoformat the snippet above), to this day people are way more confused about HTML than they need to be.

Related: #100.

Why doesn't SuperHTML report duplicate values in [class] as an error?

The HTML spec defines the global class attribute as a space-separated list of tokens, as opposed to a space-separated list of unique tokens, like some other attributes are (e.g. accesskey).

Why is <style> under <body> an error? It works in all browsers!

"Permalink: Why is

Read the original on github.com ↗