[Bug]: Recording dropping styles inserted by Emotion styled components
Preflight Checklist
- [X] I have searched the issue tracker for a bug report that matches the one I want to file, without success.
What package is this bug report for?
rrweb
Version
2.0.0-alpha.7
Expected Behavior
The recording displays emotion styled components with the inserted CSS.
Actual Behavior
Emotion styled components are displayed without any styling.
Steps to Reproduce
While recording a session on an app that uses components styled with the emotion library, reload the page and navigate to different pages so the inserted styles change.
Watching the session should show that the initial page displays the correct styles, but sequential page styles are dropped.
Added: We have noticed this is more relevant in users of Edge 113
Testcase Gist URL
No response
Additional Information
No response
@SpennyNDaJets do you have a minimum reproducible example of this issue? I've been trying to reproduce it but can't
I found out that this is most likely caused by https://github.com/emotion-js/emotion/blob/main/packages/sheet/README.md#speedy
Emotion uses the insertRule api to add classes to the <style data-emotion="css"></style> tag because it is much quicker than adding the classes to the DOM. This method however is not observable so I think rrweb is missing the added CSS until another full snapshot is taken.
Has there ever been a consideration to patch that API and fire an observer for the element?
Also suffering from this issue and saw emotion using insertRule, which to my surprise doesn't update the
In case you want to try and turn off speedy for emotion, there should be no need to patch the package. In a Next.js app it looks like this, in your _app.tsx:
import type { AppProps } from 'next/app'
import createCache from '@emotion/cache'
import { CacheProvider } from '@emotion/react'
const cache = createCache({ key: 'next', speedy: false })
export default function App({ Component, pageProps }: AppProps) {
return (
<CacheProvider value={cache}>
<Component {...pageProps} />
</CacheProvider>
)
}
Hoping someone has a better solution for rrweb than to make emotion slower though.
I believe the solution can be achieved by monkey patching the insertRule API:
// Keep a reference to the original insertRule
const originalInsertRule = CSSStyleSheet.prototype.insertRule;
// Patch the insertRule method
CSSStyleSheet.prototype.insertRule = function(rule, index) {
console.log(`CSS rule inserted: ${rule} at index ${index}`);
// Call the original insertRule
return originalInsertRule.call(this, rule, index);
};
console.log('insertRule observer attached.');
Then we can trigger a full snapshot (record.takeFullSnapshot()) after some timeout, or a smarter solution that doesn't involve a full snapshot.