Guidelines for escaping strings and handling user-controlled data in DevTools to prevent layout bleed-through, XSS, and security issues.
66
78%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./.agents/skills/devtools-unicode-escaping/SKILL.mdWhen displaying inspected data, user-controlled strings, or untrusted input in the DevTools UI (e.g., console messages, object properties, DOM tree nodes, or UI titles/descriptions), you must ensure they are properly escaped to prevent layout bleed-through (such as Right-to-Left leaks) or security vulnerabilities.
DevTools provides two primary Unicode escaping functions in Platform.StringUtilities:
escapeUnicodeAsText)Use Platform.StringUtilities.escapeUnicodeAsText(content) when rendering values that developers need to inspect (e.g. string values inside the Console or the Object properties view) where hidden, invisible, or formatting characters should be made explicitly visible.
\u202E, \u200B).const text = Platform.StringUtilities.escapeUnicodeAsText(JSON.stringify(description));safeEscapeUnicode)Use Platform.StringUtilities.safeEscapeUnicode(content) when rendering content inside templates or HTML markup where you want safe layout-critical zero-width formatting characters to function normally for word wrapping or rendering layout, but want to escape dangerous layout-disrupting characters (like bidi overrides).
\u202E), but leaves safe formatting characters untouched:
\u200B)\u200C)\u200D)DevTools wraps Lit's default html function inside front_end/ui/lit/strip-whitespace.ts (re-exported via ui/lit/lit.js). This wrapper automatically intercepts and escapes standard string values using Platform.StringUtilities.safeEscapeUnicode(val) at runtime.
html${myString}``).ifDefined, live, repeat, classMap, etc.) are automatically traversed, and any string arguments inside their values array are escaped recursively.Because the wrapper automatically processes directive arguments, you do not need to manually escape strings passed to standard Lit directives. They will be handled safely at runtime.
title=${ifDefined(tooLong ? undefined : description)} // Automatically escaped!Any manual assignments that bypass Lit entirely (e.g., setting element.textContent, element.title, or constructing DOM elements imperatively) will also bypass the Lit wrapper.
escapeUnicodeAsText if you want hidden characters to display as text (e.g., showing \\u202E).safeEscapeUnicode if you want zero-width spaces to function but other dangerous characters to be escaped.nameElement.textContent = Platform.StringUtilities.escapeUnicodeAsText(name);184a74d
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.