Reputation: 1144
in my project I want to separate section like menu in header tag, content in main tag and contact in footer tag _document.js
file, for this I created a new portal but I get an error document is not defined
in my Header.js
file.
I trying to create new portal in nextjs like this:
import React, { Fragment } from "react";
import ReactDOM from "react-dom";
import NavigationBar from "./NavigationBar";
import classes from "./header.module.css";
const Header = (props) => {
return (
<Fragment>
{ReactDOM.createPortal(
<NavigationBar>{props.children}</NavigationBar>,
document.getElementById("header")
)}
</Fragment>
);
};
export default Header;
I created _document.js:
import Document, { Html, Head, Main, NextScript } from "next/document";
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html lang="en" dir="ltr">
<Head />
<body>
<header id="header"></header>
<Main />
<footer id="_footer"></footer>
<div id="_modal"></div>
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
Upvotes: 12
Views: 7197
Reputation: 166
Another answer:
Make sure the page/document has been mounted/loaded like this:
const Header = (props) => {
// to detect document has been mounted
const [documentMouned, setDocumentMounted] = useState(false);
// run after document mounted
useEffect(() => {
setDocumentMounted(true)
}, []);
return (
<Fragment>
{ReactDOM.createPortal(
<NavigationBar>{props.children}</NavigationBar>,
document.getElementById("header")
)}
</Fragment>
);
};
Upvotes: 1
Reputation: 1144
Use React portal maker:
import React from "react";
import reactDom from "react-dom";
const Header = (props) => {
const content = <NavigationBar>{props.children}</NavigationBar>;
if (typeof window === "object") {
return reactDom.createPortal(content, document.getElementById("__header"));
}
return null;
};
export default Header ;
Upvotes: 11
Reputation: 117
The error is thrown because document
is only available inside the browser and not on the server. Next js executes this code on the server side and that's why the error is thrown.
You can wrap our code inside an if statement. If you check on the console the type of window it returns object. The following code illustrates this:
if (typeof window === 'object') {
// Check if document is finally loaded
}
Upvotes: 5