So, here's the situation.
I'm trying to get a "language" cookie in the app initialization to change the UI accordingly. For example, if the language is "Arabic" (ar), I revert the layout to be "RTL", and vise versa.
There are two ways to achieve this, the first solution is to get the cookie inside "useEffect()", like this ...
import { parseCookies } from "nookies";
import { useEffect, useLayoutEffect, useState } from "react";
import { StyleSheetManager, ThemeProvider } from "styled-components";
import rtlPlugin from "stylis-plugin-rtl";
function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
const [appLanguage, setAppLanguage] = useState("en");
useEffect(() => {
const cookies = parseCookies();
setAppLanguage(cookies.language);
}, []);
useEffect(() => {
history.scrollRestoration = "manual";
if (appLanguage === "ar") {
document.documentElement.classList.add("rtl");
document.documentElement.dir = "rtl";
} else {
document.documentElement.classList.remove("rtl");
document.documentElement.dir = "ltr";
}
}, [appLanguage]);
console.log("Appp Language", appLanguage);
return (
<>
<ThemeProvider theme={theme}>
<StyleSheetManager stylisPlugins={[rtlPlugin]}>
<>
<GlobalStyle />
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
</>
</StyleSheetManager>
</ThemeProvider>
</>
);
}
export default wrapper.withRedux(MyApp);
And that works, but the issue as you can imagine is that the page flicker for a brief moment with the default "English" layout until the useEffect()
is executed.
The other way to avoid such flickering behavior is of course use getInitialProps
on the _app.tsx level, like this ...
MyApp.getInitialProps = async (appContext: AppContext) => {
const cookies = nookies.get(appContext)
const appLanguage = cookies.language;
const appProps = await App.getInitialProps(appContext);
return { appLanguage, ...appProps };
};
And now you have the "appLanguage" prop available to you on the root _app level to do whatever you want with it.
The only problem with this approach is that it is not recommended by the "Next.js" team to use "getInitialProps" on the _app level because according to the documentation...
"this disables the ability to perform automatic static optimization, causing every page in your app to be server-side rendered."
On the other hand, you can't seem to be able to use "getServerSideProps" on the root _app level.
So, my question is, how to have the best of both worlds? get a state to share it from the root "_app" level without using getInitialProps to not have every page server-side rendered?
Is it even possible? or is there a way to use "getServerSideProps" in the root "_app" file?
Any help is appreciated.