Preflight Checklist
What package is this bug report for?
rrweb-snapshot
Version
2.0.1 and 2.1.4. Also on main.
Expected Behavior
An inlined <img> with srcset keeps alt, class, style, id and sizes after rebuild(). Only srcset moves to rrweb-original-srcset.
Actual Behavior
rebuild() removes every attribute except src. The image renders at natural size with no style.
Cause: packages/rrweb-snapshot/src/rebuild.ts, buildNode(), the branch that backs up srcset. It does not check name. For an img with srcset and rr_dataURL, every attribute in the loop goes into that branch.
} else if (
tagName === 'img' &&
n.attributes.srcset &&
n.attributes.rr_dataURL
) {
node.setAttribute('rrweb-original-srcset', n.attributes.srcset as string);
} else {
node.setAttribute(name, value.toString());
Fix:
} else if (
+ name === 'srcset' &&
tagName === 'img' &&
- n.attributes.srcset &&
n.attributes.rr_dataURL
) {
Steps to Reproduce
- Record a page with
inlineImages: true and one <img> that has srcset and an inline style.
- Replay it.
- The image has no style, class, alt or id.
Or, without a recording:
import { rebuild, createCache } from "rrweb-snapshot";
const PNG = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==";
const node = { type: 2, tagName: "img", id: 5, childNodes: [], attributes:
{ id: "x", alt: "hello", class: "c1", style: "width:40px", src: PNG, srcset: `${PNG} 1x`, rr_dataURL: PNG } };
const img = rebuild(node, { doc: document, cache: createCache(), UNSAFE_allowUnprotectedRebuild: true });
console.log(img.hasAttribute("style")); // false. Remove srcset from the node: true.
Testcase Gist URL
https://rrwebdebug.com/play/index.html?url=https%3A%2F%2Fgist.github.com%2FSaintPepsi%2F1aa63b3b23d690b987258fca4a21c632&version=2.0.1&virtual-dom=on&play=on
Recording: two <img> nodes, same style (200x200, red border), same rr_dataURL. The first also has srcset. Correct: two red boxes. Bug: one.
Standalone repro (browser-only fiddle.html, plus a node script that runs 3 cases against 2.0.1 and 2.1.4): https://gist.github.com/SaintPepsi/6a3d3b1d699e0a68e6a6e52aeec0feb7
Additional Information
Introduced in #822. Real-world trigger: Next.js <Image fill>, which emits srcset plus style="position:absolute;inset:0;...". The image replays at natural size over the page.
Fix PR follows.
Preflight Checklist
What package is this bug report for?
rrweb-snapshot
Version
2.0.1 and 2.1.4. Also on
main.Expected Behavior
An inlined
<img>withsrcsetkeepsalt,class,style,idandsizesafterrebuild(). Onlysrcsetmoves torrweb-original-srcset.Actual Behavior
rebuild()removes every attribute exceptsrc. The image renders at natural size with no style.Cause:
packages/rrweb-snapshot/src/rebuild.ts,buildNode(), the branch that backs upsrcset. It does not checkname. For an img withsrcsetandrr_dataURL, every attribute in the loop goes into that branch.Fix:
Steps to Reproduce
inlineImages: trueand one<img>that hassrcsetand an inline style.Or, without a recording:
Testcase Gist URL
https://rrwebdebug.com/play/index.html?url=https%3A%2F%2Fgist.github.com%2FSaintPepsi%2F1aa63b3b23d690b987258fca4a21c632&version=2.0.1&virtual-dom=on&play=on
Recording: two
<img>nodes, same style (200x200, red border), samerr_dataURL. The first also hassrcset. Correct: two red boxes. Bug: one.Standalone repro (browser-only
fiddle.html, plus a node script that runs 3 cases against 2.0.1 and 2.1.4): https://gist.github.com/SaintPepsi/6a3d3b1d699e0a68e6a6e52aeec0feb7Additional Information
Introduced in #822. Real-world trigger: Next.js
<Image fill>, which emitssrcsetplusstyle="position:absolute;inset:0;...". The image replays at natural size over the page.Fix PR follows.