Validating Markup: Write Your Own Snippet

Mads Stoumann - Oct 10 '21 - - Dev Community

I always validate my markup. Why? There are several reasons, the main ones being:

  • If the markup is invalid, the browser will have to spend more time guessing and interpreting what the markup should most likely be like. This will take longer to process, and thus = slower rendering.

  • Screen-readers can/will fail for the same reasons.

  • Search-engines will index your site faster, if the crawler does not have to interpret invalid markup.


To validate your markup, just go to https://validator.w3.org/ and paste a url, upload a file, or input HTML directly.

While this works, it's not ideal for local development. That's why, I've been using Validity for a number of years to check my markup for errors.

Unfortunately, it's recently been removed from the Chrome Web Store ☹️

Luckily, W3 has a Validation API we can use instead.

Let's look into how we can create our own validation-snippet!


Creating a snippet

In Chrome Dev Tools, go to “Sources > Snippets” and click on “+ New snippet”.

Paste the following code:

async function valid(url = 'https://validator.nu/?out=json') {
  const response = await fetch(url, {
    method: 'POST',
    mode: 'cors',
    cache: 'no-cache',
    credentials: 'same-origin',
    headers: { 'Content-Type': 'text/html;charset=UTF-8' },
    redirect: 'follow',
    referrerPolicy: 'no-referrer',
    body: new XMLSerializer().serializeToString(document)
  });
  return response.json();
}

valid()
  .then(data => {
    console.clear();
    console.log(data);
  })
Enter fullscreen mode Exit fullscreen mode

Save the snippet, rename it to “valid”:

Snippet

This snippet will POST the markup of the current page to W3's validator, and return json with validation-information.

To run the snippet, press ⌘/CTRL+ENTER after the last line of code.

Does it run? Good! In the future, to run the snippet, just press ⌘+O (MAC) or CTRL+O (PC) – then type !valid.


Formatting the output

Now, by using all the wonderful methods of console, let's format the output.

Replace console.log(data) with:

const error = data.messages.filter(msg => msg.type === 'error');
const warning = data.messages.filter(msg => msg.type === 'info' && msg?.subType === 'warning');

if (warning.length) {
  console.group(`%c${warning.length} validation warnings`, "background-color:#FFFBE5;padding:1px 4px");
  warning.forEach(msg => {
    console.groupCollapsed(`%c${msg.message} (line: ${msg.lastLine})`, "background-color:#FFFBE5");
    console.table(msg)
    console.groupEnd();
  })
  console.groupEnd();
}
if (error.length) {
  console.group(`%c${error.length} validation errors`, "background-color:#D93025;color:#FFF;padding:1px 4px");
  error.forEach(msg => {
    console.groupCollapsed(`%c${msg.message} (line: ${msg.lastLine})`, "color:#D93025");
    console.table(msg)
    console.groupEnd();
  })
  console.groupEnd();
}
Enter fullscreen mode Exit fullscreen mode

Save the snippet (⌘/CTRL+S), and check it out:

Console

We can then expand each warning- or error-line:

Expanded error

The latter is using console.table(), but could also be console.dir – or whatever way you want to present the error.


Conclusion

I now have a fast way to validate local markup again! If you're using the snippet on external sites or with sites that have a “Content Security Policy”, you might run into issues and have to update the snippet.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .