admin管理员组文章数量:1278974
I want to add my custom class to some pages. for example
all pages must be this class fixed-header
exception this routes:
/cart/step-1
/login
this class add or remove to body element.
<body className="bg-gray fixed-header"
but I don't know how I can handle this scenario?
I want to add my custom class to some pages. for example
all pages must be this class fixed-header
exception this routes:
/cart/step-1
/login
this class add or remove to body element.
<body className="bg-gray fixed-header"
but I don't know how I can handle this scenario?
Share Improve this question asked Sep 6, 2021 at 12:01 S.M_EmamianS.M_Emamian 17.4k40 gold badges154 silver badges273 bronze badges2 Answers
Reset to default 7Create a custom _document.js
and _app.js
in your pages directory.
A small util to check if class exists on body (to avoid duplicate class, thanks to suggestion by @juliomalves):
// ./utils/hasClasses
const hasClasses = () =>
document.body.classList.contains("bg-gray") &&
document.body.classList.contains("fixed-header");
export default hasClasses;
Server Side rendering
In _document.js
, use the __NEXT_DATA__
prop to get access to the current page,
check if the page is in your allowed routes, and add the classes to body.
import Document, { Html, Head, Main, NextScript } from "next/document";
class MyDocument extends Document {
// Add more routes here if you want to use the same classes
allowedRoutes = ["/login", "/cart/step-1"];
getColor() {
const { page } = this.props?.__NEXT_DATA__;
if (this.allowedRoutes.includes(page))
return "bg-gray fixed-header";
return "";
}
render() {
return (
<Html>
<Head />
<body className={this.getColor()}>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
The above code always runs on the server. Classes doesn't get appended to the body on client-side navigation.
Client side rendering
To fix the above issue, use the same logic in _app.js
in a useEffect
, so that it adds the correct class when rendering on the client.
import { useEffect } from "react";
import { useRouter } from "next/router";
import "../styles.css";
import hasClasses from "./utils/hasClasses";
function MyApp({ Component, pageProps }) {
const { pathname: page } = useRouter();
const allowedRoutes = ["/login", "/cart/step-1"];
useEffect(() => {
if (!hasClasses() && allowedRoutes.includes(page))
document.body.className += "bg-gray fixed-header";
else if (hasClasses()) {
// Don't want the styles in other pages, remove if exists.
// Up to your implementation on how you want to handle this.
document.body.classList.remove("bg-gray");
document.body.classList.remove("fixed-header");
}
});
return <Component {...pageProps} />;
}
export default MyApp;
This solves the issue where client side navigation correctly applies the class on the allowed route. The code in _document.js
makes sure that when a page is server rendered, it is sent downstream with the correct class applied so that it doesn't cause a flash of incorrect styles on the client.
The easiest and quickest solution. Add this code into each ponent where you want different classes on the <body>
.
useEffect( () => { document.querySelector("body").classList.add("bg-gray fixed-header") } );
本文标签: javascriptHow to add custom class to body element for some routesnexjtsStack Overflow
版权声明:本文标题:javascript - How to add custom class to body element for some routes - nexjts - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741286978a2370328.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论