Skip to content

Commit ddc63e4

Browse files
committed
fix: SSR compatibility — guard HTMLAnchorElement instanceof check for Node.js
The DOMPurify afterSanitizeAttributes hook used instanceof HTMLAnchorElement which is undefined in Node.js/SSR environments. Replaced with nodeName string comparison ('A') as primary check, falling back to instanceof when the browser DOM constructor is available.
1 parent e89e1a4 commit ddc63e4

1 file changed

Lines changed: 11 additions & 3 deletions

File tree

src/utils/sanitizer.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,18 @@ const ALLOWED_ATTR = ['href', 'rel'];
2828
/**
2929
* Ensure anchor tags always carry `rel="nofollow noopener noreferrer"`
3030
* to prevent tab-napping and link-juice leakage.
31+
*
32+
* Uses nodeName string comparison instead of instanceof HTMLAnchorElement
33+
* to remain compatible with SSR environments (Node.js lacks browser DOM
34+
* constructors).
3135
*/
3236
DOMPurify.addHook('afterSanitizeAttributes', (node) => {
33-
if (node instanceof HTMLAnchorElement) {
34-
const rel = node.getAttribute('rel') ?? '';
37+
if (
38+
(node as Element).nodeName === 'A' ||
39+
(typeof HTMLAnchorElement !== 'undefined' &&
40+
node instanceof HTMLAnchorElement)
41+
) {
42+
const rel = (node as Element).getAttribute('rel') ?? '';
3543
const parts = new Set(
3644
rel
3745
.split(/\s+/)
@@ -41,7 +49,7 @@ DOMPurify.addHook('afterSanitizeAttributes', (node) => {
4149
parts.add('nofollow');
4250
parts.add('noopener');
4351
parts.add('noreferrer');
44-
node.setAttribute('rel', [...parts].join(' '));
52+
(node as Element).setAttribute('rel', [...parts].join(' '));
4553
}
4654
});
4755

0 commit comments

Comments
 (0)