HAST Interactive Content Utility
hast-util-interactive is a focused utility within the unified ecosystem, specifically designed to determine if a given hast (Hypertext Abstract Syntax Tree) node constitutes "interactive content" according to the HTML specification. This package is particularly useful for tools that analyze or transform HTML content and need to identify elements like `<a>` with `href`, `<button>`, `<input>`, or `<video controls>` to enforce accessibility rules, validate content, or apply specific styling. The current stable version is 3.0.0. Maintained by the syntax-tree collective, it follows a release cadence tied to Node.js LTS cycles and hast ecosystem updates, providing TypeScript types for enhanced developer experience. Its primary differentiator is its precise implementation of the HTML interactive content algorithm for hast nodes, offering a reliable predicate function rather than a full parsing or transformation engine.
Common errors
-
TypeError [ERR_REQUIRE_ESM]: require() of ES module /path/to/node_modules/hast-util-interactive/index.js from /your/project/file.js not supported.
cause Attempting to use CommonJS `require()` syntax with an ESM-only package.fixChange your import statement from `const { interactive } = require('hast-util-interactive')` to `import { interactive } from 'hast-util-interactive'` and ensure your Node.js environment or build setup supports ESM. -
ReferenceError: interactive is not defined
cause Using an outdated Node.js version (prior to 16) that does not meet the minimum requirement for `hast-util-interactive@^3`, or an incorrect import.fixUpgrade your Node.js environment to version 16 or higher. Alternatively, ensure the `import` statement is correct and the module is resolving properly. -
TypeError: Cannot read properties of undefined (reading 'type') or similar error when passing non-node values.
cause Passing `null`, `undefined`, or other non-Node JavaScript values to the `interactive` function, which now strictly requires a `hast` Node.fixBefore calling `interactive(node)`, validate that `node` is indeed a `hast` Node object. For example, `if (node && typeof node === 'object' && node.type) { interactive(node) }`.
Warnings
- breaking Version 3.0.0 changes to require Node.js 16 or higher. Older Node.js versions are no longer supported.
- breaking Version 3.0.0 removes support for passing non-Node values (e.g., `null`, `undefined`) to the `interactive` function. Input must be a valid `hast` Node.
- breaking Version 3.0.0 introduces `exports` in package.json, changing internal module resolution. Avoid relying on private, non-exported APIs as they may no longer be accessible.
- breaking Version 2.0.0 converted the package to ESM (ECMAScript Modules) only. CommonJS `require()` is no longer supported.
- gotcha This utility is highly specific, checking for 'interactive content' according to HTML. It is not a general-purpose HTML parser or validator. Its definition of 'interactive' is precise (e.g., `<a>` is only interactive with an `href`).
Install
-
npm install hast-util-interactive -
yarn add hast-util-interactive -
pnpm add hast-util-interactive
Imports
- interactive
const interactive = require('hast-util-interactive')import { interactive } from 'hast-util-interactive' - Element
import type { Element } from 'hast'
Quickstart
import { interactive } from 'hast-util-interactive';
import type { Element, Text, Root } from 'hast';
// Example 1: Non-interactive anchor (no href)
const nonInteractiveLink: Element = {
type: 'element',
tagName: 'a',
properties: {},
children: [{type: 'text', value: 'Non-clickable link'}]
};
console.log('Is nonInteractiveLink interactive?', interactive(nonInteractiveLink)); // => false
// Example 2: Interactive anchor (with href)
const interactiveLink: Element = {
type: 'element',
tagName: 'a',
properties: {href: '#section'},
children: [{type: 'text', value: 'Clickable link'}]
};
console.log('Is interactiveLink interactive?', interactive(interactiveLink)); // => true
// Example 3: Interactive button
const buttonElement: Element = {
type: 'element',
tagName: 'button',
properties: {},
children: [{type: 'text', value: 'Submit'}]
};
console.log('Is buttonElement interactive?', interactive(buttonElement)); // => true
// Example 4: Video with controls
const videoElement: Element = {
type: 'element',
tagName: 'video',
properties: {controls: true, src: 'movie.mp4'},
children: []
};
console.log('Is videoElement interactive?', interactive(videoElement)); // => true
// Example 5: Input field
const inputElement: Element = {
type: 'element',
tagName: 'input',
properties: {type: 'text', value: 'Hello'},
children: []
};
console.log('Is inputElement interactive?', interactive(inputElement)); // => true