Blog
`ultrahtml` library in Nitro codebase.

`ultrahtml` library in Nitro codebase.

In this article, we review how Nitro uses ultrahtml package. We will look at:

  1. What is ultrahtml library?

  2. How is ultrahtml used in Nitro codebase?

I study patterns used in an open source project found on Github Trending. For this week, I reviewed some parts of Nitro codebase and wrote this article.

Press enter or click to view image in full size

What is ultrahtml library?

A 1.75kB library for enhancing html. ultrahtml has zero dependencies and is compatible with any JavaScript runtime.

Features

  • Tiny, fault-tolerant and friendly HTML-like parser. Works with HTML, Astro, Vue, Svelte, and any other HTML-like syntax.

  • Built-in AST walk utility

  • Built-in transform utility for easy output manipulation

  • Automatic but configurable sanitization, see Sanitization

  • Handy html template utility

  • querySelector and querySelectorAll support using ultrahtml/selector

Learn more about ultrahtml.

How is ultrahtml used in Nitro codebase?

I found the below import in nitro/src/prerender/utils.ts.

import { parse as parseHTML, walk } from "ultrahtml";

And these functions are used in extractLinks function defined at L25.

export async function extractLinks(
  html: string,
  from: string,
  res: Response,
  crawlLinks: boolean
) {
  const links: string[] = [];
  const _links: string[] = [];

  // Extract from any <TAG href=""> to crawl
  if (crawlLinks) {
    await walk(parseHTML(html), (node) => {
      if (!node.attributes?.href) {
        return;
      }

      const link = escapeHtml(node.attributes.href);
      if (
        !decodeURIComponent(link).startsWith("#") &&
        allowedExtensions.has(getExtension(link))
      ) {
        _links.push(link);
      }
    });
  }

but what does walk function do? I picked the following information from the ultrahtml README.

walk

The walk function provides full control over the AST. It can be used to scan for text, elements, components, or any other validation you might want to do.

Note: walk is async and must be awaited. Use walkSync if it is guaranteed there are no async components in the tree.

import { parse, walk, ELEMENT_NODE } from "ultrahtml";
const ast = parse(`<h1>Hello world!</h1>`);
await walk(ast, async (node) => {
  if (node.type === ELEMENT_NODE && node.name === "script") {
    throw new Error("Found a script!");
  }
});

About me:

Hey, my name is Ramu Narasinga. I study codebase architecture in large open-source projects.

Email: ramu.narasinga@gmail.com

Study the patterns used in large OSS projects at Think Throo.

References:

  1. https://github.com/nitrojs/nitro/blob/main/src/prerender/utils.ts#L4

  2. https://github.com/nitrojs/nitro/blob/main/src/prerender/utils.ts#L36

  3. https://www.npmjs.com/package/ultrahtml