question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

The global style should be at the top

See original GitHub issue

Current behavior:

When there is more than one emotion cache I want the global style to always be at the top and then be overridden in order The prepend option can only be set to the top or bottom, and the insertionPoint option needs to be passed HTMLElement which does not support SSR

image image

I can adjust the order of ServerStyles here, but there’s no way to override the mantine style directly

MyDocument.getInitialProps = async (ctx: DocumentContext) => {
  const initialProps = await Document.getInitialProps(ctx)
  const server = createEmotionServer(cache)
  return {
    ...initialProps,
    styles: (
      <>
        {initialProps.styles}
        <ServerStyles html={initialProps.html} server={stylesServer} />
        <ServerStyles html={initialProps.html} server={server} />
      </>
    ),
  }
}

To reproduce:

https://github.com/u3u/emotion-issue-2803

Expected behavior:

image

Environment information:

  • react version: 18.2.0
  • @emotion/react version: 11.9.3

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
Andaristcommented, Jul 4, 2022

You can use this patch to work around your issue:

patch for the repro
diff --git a/pages/_app.tsx b/pages/_app.tsx
index f6f61f5..2da5a2e 100755
--- a/pages/_app.tsx
+++ b/pages/_app.tsx
@@ -1,18 +1,46 @@
-import { cache } from '@emotion/css'
 import { CacheProvider } from '@emotion/react'
 import { MantineProvider } from '@mantine/core'
+import createCache from '@emotion/cache'
 import type { AppProps } from 'next/app'
 import { GlobalStyles } from 'styles'
 import { mantine } from 'theme'
+import React from 'react'
 
-function MyApp({ Component, pageProps }: AppProps) {
+const createMyEmotionCache = () => {
+  const insertionPoint = typeof document !== 'undefined'
+    ? (document.querySelector('meta[name="emotion-insertion-point"]')! as HTMLElement)
+    : undefined
+
+  const cache = createCache({
+    key: 'uthreeu',
+    insertionPoint
+  })
+  cache.compat = true;
+
+  return cache;
+}
+
+const cache = createMyEmotionCache()
+
+const wrapOnClient = (children: React.ReactNode) => {
+  if (typeof document === 'undefined') {
+    return children;
+  }
   return (
     <MantineProvider {...mantine}>
       <CacheProvider value={cache}>
-        <GlobalStyles />
-        <Component {...pageProps} />
+        {children}
       </CacheProvider>
     </MantineProvider>
+  );
+};
+
+function MyApp({ Component, pageProps }: AppProps) {
+  return wrapOnClient(
+    <>
+      <GlobalStyles />
+      <Component {...pageProps} />
+    </>
   )
 }
 
diff --git a/pages/_document.tsx b/pages/_document.tsx
index 424a765..de94e2f 100644
--- a/pages/_document.tsx
+++ b/pages/_document.tsx
@@ -1,4 +1,6 @@
-import { cache } from '@emotion/css'
+import { CacheProvider } from '@emotion/react'
+import { MantineProvider } from '@mantine/core'
+import createCache from '@emotion/cache'
 import createEmotionServer from '@emotion/server/create-instance'
 import { ServerStyles, createStylesServer } from '@mantine/next'
 import Document, {
@@ -8,13 +10,15 @@ import Document, {
   NextScript,
   DocumentContext,
 } from 'next/document'
+import { mantine } from 'theme'
 
-const stylesServer = createStylesServer()
-
+const stylesServer = createStylesServer(mantine.emotionOptions)
 export function MyDocument() {
   return (
     <Html>
-      <Head />
+      <Head>
+        <meta name="emotion-insertion-point" content=""></meta>
+      </Head>
       <body>
         <Main />
         <NextScript />
@@ -23,16 +27,46 @@ export function MyDocument() {
   )
 }
 
+const createMyEmotionCache = () => {
+  const insertionPoint = typeof document !== 'undefined'
+    ? (document.querySelector('meta[name="emotion-insertion-point"]')! as HTMLElement)
+    : undefined
+
+  const cache = createCache({
+    key: 'uthreeu',
+    insertionPoint
+  })
+  cache.compat = true;
+
+  return cache;
+}
+
 MyDocument.getInitialProps = async (ctx: DocumentContext) => {
+  const cache = createMyEmotionCache()
+  const originalRenderPage = ctx.renderPage
+
+  ctx.renderPage = () =>
+    originalRenderPage({
+      // eslint-disable-next-line react/display-name
+      enhanceApp: (App) => (props) =>
+        (
+          <MantineProvider {...mantine}>
+            <CacheProvider value={cache}>
+              <App {...props} />
+            </CacheProvider>
+          </MantineProvider>
+        ),
+    });
   const initialProps = await Document.getInitialProps(ctx)
+
   const server = createEmotionServer(cache)
   return {
     ...initialProps,
     styles: (
       <>
         {initialProps.styles}
-        <ServerStyles html={initialProps.html} server={stylesServer} />
         <ServerStyles html={initialProps.html} server={server} />
+        <ServerStyles html={initialProps.html} server={stylesServer} />
       </>
     ),
   }
diff --git a/theme/mantine.ts b/theme/mantine.ts
index 1ef6ce0..79fbde4 100644
--- a/theme/mantine.ts
+++ b/theme/mantine.ts
@@ -24,3 +24,8 @@ export const styles: MantineProviderProps['styles'] = {
     filled: tw`bg-primary-500 hocus:(bg-primary-400) active:(bg-primary-600)`,
   } as Record<ButtonStylesNames, CSSObject>,
 }
+
+export const emotionOptions = {
+  key: 'mantine',
+  prepend: false,
+}

0reactions
u3ucommented, Jul 10, 2022

This is automatically set to true by createEmotionServer. It makes our APIs not to render styles “inline” during SSR - they are just put into the cache as it’s expected that they will be extracted using APIs like extractCritical etc. It also turns off the infamous “unsafe pseudo-selectors” warnings.

With your latest patch - is it already working as you want? Or do you need further assistance?

@Andarist Thank you! This problem has been solved 😁

Read more comments on GitHub >

github_iconTop Results From Across the Web

Global and local styling - Every Layout
This section will contextualize layout components in a larger system that includes global styles. What are global styles? When people talk about the...
Read more >
How to Create Global Styles with Styled Components
How to Create Global Styles with Styled Components · Step 1: Create a global styles file · Step 2: Place GlobalStyle at the...
Read more >
Standard Styling with Global CSS Files - Gatsby
The best way to add global styles is with a shared layout component. ... You should see your global styles taking effect across...
Read more >
How to manage the basic settings of Global Style | Help Center
Step 2: Click on the Global Style tab at the top of the right sidebar. Next, hit the “Create New Preset” button. You...
Read more >
Creating a Global Style Sheet - meyerweb.com
What HTML tags will I use over and over again? Are there certain colors I want to use, and if so, which ones...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Hashnode Post

No results found