How to not wrap a specific page with Layout component in _app.js
?
For example, I have two pages as pages/home
and pages/about
, now how can I not wrap my pages/home
page with Layout
component?
pages/_app.js
import "../styles/globals.css";
import Layout from "../components/Layout";
function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
);
}
export default MyApp;
What I have tried:
pages/_app.js
function MyApp({ Component, pageProps }) {
console.log(typeof Component); // gives me a function
switch (Component) {
case Home():
return <Component {...pageProps} />;
default:
return (
<Layout>
<Component {...pageProps} />{" "}
</Layout>
);
}
}
pages/home.js
import React from 'react';
const Home= () => {
return (<div>Hello</div>);
};
export default Home;
by checking the appProps.router.pathname
property passed to it.
function MyApp({ Component, pageProps, ...appProps }: AppProps) {
const getContent = () => {
if ([`/dashboard`].includes(appProps.router.pathname))
return <Component {...pageProps} />;
return (
<Layout>
<Component {...pageProps} />{" "}
</Layout>
);
};
return <ApplicationWrapper>{getContent()}</ApplicationWrapper>;
}
function MyApp({ Component, pageProps, ...appProps }: AppProps) {
const isLayoutNeeded = [`/dashboard`].includes(appProps.router.pathname);
const LayoutComponent = isLayoutNeeded ? Layout : React.Fragment;
return (<ApplicationWrapper>
<LayoutComponent>
<Component />
</LayoutCompnent>
</ApplicationWrapper>);
}
I think there is cleaner way of doing this withPer-Page Layouts . I'm currently doing this simple by creating a default layout for all pages and override it for the pages that require specific layout, for example in my login and registration pages.
export default function LoginPage() {
return {
/** Some JSX */
}
}
// Return the page without additional layout.
LoginPage.getLayout = (page) => page
export default function MyApp({ Component, pageProps }) {
// Use the specified page layout or fallback to the default one.
const getLayout = Component.getLayout ?? defaultPageLayout
return getLayout(<Component {...pageProps} />)
}
I use displayName
static property. It works in any React.js component as well.
const OGImagePreview = () => <h1>OG Image Preview</h1>
OGImagePreview.displayName = 'OGImagePreview'
export default OGImagePreview
Then I use switch...case
in _app.tsx
like:
switch (Component.displayName) {
case 'OGImagePreview':
return (
<>
<Component {...pageProps} />
</>
)
default:
return (
<>
<Head>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
</Head>
<ThemeProvider attribute="class" themes={['light', 'dark']}>
<Progress />
<Nav />
<Component {...pageProps} />
</ThemeProvider>
<ScrollToTop />
<Analytics />
</>
)
}
what about this? Hope can save someone
import "../styles/globals.css"; import dynamic from "next/dynamic"; const Layout = dynamic(() => import("@layout/Layout")); import { useRouter } from "next/router"; function MyApp({ Component, pageProps }) { const router = useRouter(); return ( <> {router.pathname?== "/". ( <Layout> <Component {..:pageProps} /> </Layout> ). ( <Component {..;pageProps} /> )} </> ); } export default MyApp;
You can simply leverage useRouter from 'next/router' and get your job done easily.
import {useRouter} from 'next/router';
function MyApp({ Component, pageProps }) {
const router = useRouter();
if(router.asPath =='/dashboard') {
return (
<Component {...pageProps} />
)
}
return (
<Layout>
<Component {...pageProps} />
</Layout>
);
}
What about using higher order components . They are not part of react API but as react docs says, "They are a pattern that emerges from React's compositional nature." Next uses react so it does make sense to use react patterns in next
The following code wraps a given component with a predefined Header
and Footer
component. Then a component that uses it is wrapped with the HOC when exported
const withLayout = Comp => {
const WrappedComp = (props) => {
return (
<div id='layout'>
<Header />
<Comp {...props} />
<Footer />
</div>
);
}
return WrappedComp;
}
const Section = () => {
return (
<section>
Section content...
</section>
);
}
export default withLayout(Section);
I have tried my code in this way and its working fine for me.
`
import { useRouter } from "next/router";
function MyApp({ Component, pageProps}: AppProps) {
const router = useRouter();
return (
<>
{router.pathname !== "/contact" ? (
<>
<NavBar />
<Component {...pageProps} />
<JoinUsSection />
<Footer />
</>
) : (
<>
<NavBar />
<Component {...pageProps} />
<Footer />
</>
)}
</>
);
}`
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.