rrweb icon indicating copy to clipboard operation
rrweb copied to clipboard

[Bug]: Recording dropping styles inserted by Emotion styled components

Open SpennyNDaJets opened this issue 2 years ago • 5 comments

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 avatar May 23 '23 21:05 SpennyNDaJets

@SpennyNDaJets do you have a minimum reproducible example of this issue? I've been trying to reproduce it but can't

daibhin avatar May 23 '24 17:05 daibhin

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?

daibhin avatar Jul 02 '24 16:07 daibhin

Also suffering from this issue and saw emotion using insertRule, which to my surprise doesn't update the

danieltroger avatar Sep 09 '24 09:09 danieltroger

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.

damusnet avatar Sep 26 '24 02:09 damusnet

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.

ShayMalchi avatar Jan 08 '25 12:01 ShayMalchi