Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation in SSR (Next.js) #5

Open
sanishkr opened this issue Feb 10, 2020 · 9 comments
Open

Implementation in SSR (Next.js) #5

sanishkr opened this issue Feb 10, 2020 · 9 comments

Comments

@sanishkr
Copy link

Where do I implement in SSR (Next.js)? Should I keep StyleSheetManager in _app.js or in _document.js? I think it should be in _document.js. But I tried wrapping my in StyleSheetManager, it doesn't work.

Here is a sample _document.js without this plugin.

import Document, { Head, Main, NextScript } from 'next/document';
import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
import stylisRTLPlugin from 'stylis-plugin-rtl';
import { parseCookies } from 'nookies';

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;
    const { html, head, errorHtml, chunks } = ctx.renderPage();
    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: App => props => sheet.collectStyles(<App {...props} />)
        });
      const initialProps = await Document.getInitialProps(ctx);
      const cookies = parseCookies(ctx);
      initialProps.language = cookies['next-i18next'] || 'en';
      initialProps.direction = initialProps.language === 'ar' ? 'rtl' : 'ltr';
      return {
        html,
        head,
        errorHtml,
        chunks,
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        )
      };
    } finally {
      sheet.seal();
    }
  }
  render() {
    const { language, direction } = this.props;
    return (
      <html dir={direction} lang={language}>
        <body>
          {this.props.customValue}
          <Main />
          <NextScript />
        </body>
      </html>
    );
  }
}

Here is what I tried

.
.
.
       <StyleSheetManager
          stylisPlugins={language === 'ar' ? [stylisRTLPlugin] : []}
        >
          <body>
            {this.props.customValue}
            <Main />
            <NextScript />
          </body>
        </StyleSheetManager>
.
.
.
@Migggz
Copy link

Migggz commented Mar 9, 2020

It should be in _app.js

<StyleSheetManager stylisPlugins={language === "ar" ? [stylisRTLPlugin] : []}>
   {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
   <CssBaseline />
   <Page {...pageProps}  />
</StyleSheetManager>

@sanishkr
Copy link
Author

Thanks, @Migggz for the suggestion.
I had tried like this in _app.js:

.
.
.
         {language ? (
            <StyleSheetManager
              stylisPlugins={language === 'ar' ? [stylisRTLPlugin] : []}
            >
              <Component {...pageProps} />
            </StyleSheetManager>
          ) : null}
.
.

Conditional to do re-rendering when I hit change language. It wasn't working otherwise.
What is CssBaseline though?

@oliviertassinari
Copy link

What is CssBaseline though?

@sanishkr https://material-ui.com/components/css-baseline/

@sanishkr
Copy link
Author

Got it. Thanks @oliviertassinari

Can anyone help me why it doesn't work when doing like this:

    <StyleSheetManager
              stylisPlugins={language === 'ar' ? [stylisRTLPlugin] : []}
            >
              <Component {...pageProps} />
    </StyleSheetManager>

I have to do like this:

         {language ? (
            <StyleSheetManager
              stylisPlugins={language === 'ar' ? [stylisRTLPlugin] : []}
            >
              <Component {...pageProps} />
            </StyleSheetManager>
          ) : null}

But this approach has its own problems. I have made an example here to look at. Check components/Theme.js. Just comment line 17 and 23.

CodeSandbox

@barghi
Copy link

barghi commented Jul 11, 2020

@sanishkr Have you found a solution?

@sanishkr
Copy link
Author

Nope. It's a really cool plugin but authors or community doesn't have much support yet.

@barghi
Copy link

barghi commented Jul 12, 2020

everything is ok in development mode,
when I run the project in production mode, RTL-plugin won't work at first render
and if I navigate to another page (in the client) styles will show without any problem

the problem is: server render in production mode:

here is _app.js file:

render() {
 const { Component, pageProps, store, lang } = this.props;
 const stylePlugins = [];

 if (APP_CONSTANTS.LANG[lang].direction === 'rtl') {
   stylePlugins.push(rtlPlugin);
 }

 return (
   <Provider store={store}>
      <ThemeProvider theme={theme}>
         <StyleSheetManager stylisPlugins={stylePlugins}>
            <Component {...pageProps} />
         </StyleSheetManager>
      </ThemeProvider>
   </Provider>
 );
}

@sanishkr
Copy link
Author

Looks fine. A repo would be useful.

Or check this sandbox

@Stewiey
Copy link

Stewiey commented Nov 1, 2020

any news on this bug ?
StyleSheetManager/stylisRTLPlugin doesn't seem to work at all with nextjs, i followed the guide in styled-components about how to implement in nextjs.

<StyleSheetManager stylisPlugins={[stylisRTLPlugin]}>

the css doesn't flip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants