windows is undefined while using react-sweet-state with nextjs - reactjs

I am getting a windows is undefined error while using react-sweet-state with nextjs.
I have seen similar nextjs issues and the recommended solution was to use a rendering condition typeof window === undefined. I cannot use that rendering condition because I need the app to load even when the window is undefined.
Is there any other way to resolve the issue ?
Edit: I have added some code here which may help
pages/article/[id].js
const Article = () => {
// here is where i get the 'windows is undefined' error
const [{ article }, { fetchArticleData }] = useArticleStore();
return (
<>
<Head>
<meta property="og:title" name="og:title" content={article.title} />
<meta property="og:description" name="og:description" content={article.desc} />
</Head>
<article>
<h1>{ article.title }</h1>
<p
dangerouslySetInnerHTML={{ __html: article.content }}
></p>
</>
)
}
pages/_app.js
import "antd/dist/antd.css";
import "../styles/globals.scss";
import Layout from "../layout";
const App = ({ Component, pageProps }) => {
return (
<Layout>
<div suppressHydrationWarning>
{typeof window === "undefined" ? null : <Component {...pageProps} />}
</div>
</Layout>
);
};
export default App;

Related

Could not detect external Js file in Helmet

I have started learning React and I was creating the navigation bar.
I have leftNavigationBar defined like this
const LeftNavigationBar = (props) => {
return (
<header className={share.mypage_header} id="leftcolumn">
<Helmet>
<script type="text/babel" src="../../common/js/share.js" />
</Helmet>
</header>
);
};
export default LeftNavigationBar;
but share.js did not detected.
I put require('../../common/js/share.js'); on the top and it started working and code becomes like this
require('../../common/js/share.js');
const LeftNavigationBar = (props) => {
return (
<header className={share.mypage_header} id="leftcolumn">
<Helmet>
<script type="text/babel" src="../../common/js/share.js" />
</Helmet>
</header>
);
};
export default LeftNavigationBar;
I want to know why share.js did not worked when added inside Helmet but worked when added as require on top.
Please help.

Using react context not working as expected in remix react?

Despite having seen working examples of this in non remix projects, it doesn't seem to work in the way I'm implementing it?
I have the following in root.tsx:
export const MyContext = createContext("default");
function Document({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<Meta />
<Links />
</head>
<body className="root-body">
<MyContext.Provider value="bonjour!">
<Header />
</MyContext.Provider>
{children}
<ScrollRestoration />
<Scripts />
<LiveReload />
<Footer />
</body>
</html>
);
}
export default function App() {
return (
<Document>
<Outlet />
</Document>
);
}
In my <Header/> component I have:
import { useContext } from "react";
import { MyContext } from "~/root";
export const Header = () => {
const result = useContext(MyContext);
console.log(result);
return(null)
}
The result is then that "default" is printed to the console, but surely from my understanding it should be "bonjour"?
Where am I going wrong?
The output on the server console is from Remix SSR. It does appear that the context is not being applied during server rendering. However, it does show up correctly after hydration. Unfortunately it also results in hydration errors (see browser console).
Anyway, that does seem odd. My understanding is that you can use most hooks server side (except for useEffect and useLayoutEffect).
https://codesandbox.io/s/remix-react-context-mzexmt

react storefront TypeError: Cannot read property '_includeAppData' of undefined

I have been using react storefront for a couple of weeks now. Though I understood high level concepts, I am really stuck for API implementation using fulfillAPIRequest, fetchFromAPI, appData and pageData etc.
My current code is as follows:
File: _app.js:
export default function MyApp({ Component, pageProps }) {
useJssStyles()
const classes = useStyles()
const [appData] = useAppStore(pageProps || {})
return (
<PWA errorReporter={reportError}>
<Head>
{/* <meta
key="viewport"
name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no"
/> */}
</Head>
<SessionProvider url="/api/session">
<MuiThemeProvider theme={theme}>
<CssBaseline/>
<Header className={classes.header} />
<HeaderBanner />
<Delivery />
<Search />
<main className={classes.main}>
<Component {...pageProps} />
</main>
<Footer />
</MuiThemeProvider>
</SessionProvider>
</PWA>
)
}
MyApp.getInitialProps = async function({ Component, ctx }) {
let pageProps = {}
if (Component.getInitialProps) {
console.info("Executing _app.js: Invoking Component.getInitialProps...")
pageProps = await Component.getInitialProps(ctx)
}
return { pageProps }
}
file: pages/index.js => entry point page
import React from 'react'
import { fetchFromAPI, createLazyProps } from 'react-storefront/props'
import NearbyShops from '../components/shops/nearby-shops.js'
export default function Index(lazyProps) {
return (
<NearbyShops />
)
}
Index.getInitialProps = createLazyProps(fetchFromAPI, { timeout: 50 })
I implemented api for the page index.js, in the foder /pages/api/index.js, as follows...
import fulfillApiRequest from 'react-storefront/props/fulfillAPIRequest'
function getPageData () {
console.info("Executing 'getPageData' in /api/index.js...")
return Promise.resolve({})
}
export default async function Index (params, req, res) {
console.info("Executing '/pages/api/index.js' ...")
const result = await fulfillApiRequest(req, {
appData: () => getAppData(),
pageData: () => getPageData()
})
return result
}
When I run this app, I get the following error in the GUI:
In the console, I get the error stack trace as follows...
If I don't use the fulfillAPIRequest and its related api methods, I am able to show the rendered page, normally. But now I want to integrate the API. The official documentation is not that helpful in this regard.
Please help.

Error on next-18next integration with latest nextjs: appWithTranslation was called without a next-i18next config

I am upgrading today app to latest nextjs version (10.0.9).
In order to move translates I used next-i18next lib and its simple example from Github.
However, in my app I always get next error:
On debugger of next-i18next lib, I found that this error thrown in case of i18n config does not provided.
In my app configurations looks like:
nextjs.config.js
next-i18next.config.js
_app.js
const HeadstartApp = (props) => {
const { Component, apollo, redux, theme } = props;
const reduxRef = useRef(initRedux(redux));
const apolloRef = useRef(
getApolloClient()
);
return (
<React.Fragment>
<Head>
<title>Example</title>
<meta
name='viewport'
content='minimum-scale=1, initial-scale=1, width=device-width'
/>
</Head>
<ApolloProvider client={apolloRef.current}>
<Provider store={reduxRef.current}>
<div dir={locale === 'he' ? 'rtl' : 'ltr'}>
<ThemeProvider theme={createMuiTheme(theme)}>
{/* <AppBar position={'static'}>
<Toolbar>
<Typography>
<h1>{locale}</h1>
</Typography>
<Link href='/projects/construction/1'>
<Button>Project 1</Button>
</Link>
<Link href='/projects/digital/2'>
<Button>Project 2</Button>
</Link>
</Toolbar>
</AppBar> */}
<Layout {...props}>
<Component {...props} />
</Layout>
</ThemeProvider>
</div>
</Provider>
</ApolloProvider>
</React.Fragment>
);
};
}
export default appWithTranslation(HeadstartApp);
index.js
const HomePage = (props) => {
...code
}
export const getStaticProps = async ({ locale, defaultLocale }) => ({
props: {
...(await serverSideTranslations(locale || defaultLocale, [
'common',
'homepage',
])),
},
});
export default HomePage;
It looks like my app has same configurations as simple example here, but throws this strange exception.
Someone got something and can help to solve it
That's the solution that works for me:
In the _app.js import import i18next.config, like this import NextI18nextConfig from '../../next-i18next.config', this will guarantee that you are loading the consigurations.
Then exported it in the appWithTranslation, like this export default appWithTranslation(App, NextI18nextConfig)
This will overrides the default config.

How can I use shared components between routes in Next.js

I'm thinking of migrating from create-react-app to Next.js
I need to share component between routes in Next.js
I tried the Layout file example below and it worked pretty well for me but I have a special case where I need the shared component to be above the router itself.
For example, if I have a video element and want the video to still playing if I changed the route
const Layout = (props) => (
<div>
{props.children}
<video width="400" controls>
<source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"/>
Your browser does not support HTML5 video.
</video>
</div>
)
const Home = () => (
<Layout>
<Link href="/about"><a>About</a></Link>
<h1 className='title'>Welcome to Home!</h1>
</Layout>
)
const About = () => (
<Layout>
<Link href="/"><a>Home</a></Link>
<h1 className='title'>Welcome to About!</h1>
</Layout>
)
Example from another project using create-react-app and reach-router
the player component is above the router
<Layout>
<Player/>
<Router className={'router'}>
<Login path={Routes.login}/>
<NotFound404 default/>
<Home path={Routes.root}/>
<Test path={Routes.test}/>
</Router>
<Layout/>
The shared element will be the video tag, the problem is on every route change the video is rendered and replayed
You might wanna check the docs on using pages/_app.js for that.
Example usage is shown below:
import Head from "next/head";
type Props = {
pageProps: any;
Component: React.FC;
};
const App = ({ Component, pageProps }: Props) => {
return (
<>
<Head>
// You can put whatever you want to put in your document head
</Head>
<YourSharedComponent />
<Component {...pageProps} />
<style>{`
// styles...
`}</style>
</>
);
};
App.getInitialProps = async ({ Component }) => {
const pageProps = Component.getInitialProps && await Component.getInitialProps(ctx, loggedUser);
return {
pageProps,
}
};
export default App;

Resources