I have three pages that I want to share data between (these are the core of the web app) but I also have a bunch of blog pages that don't care about that data. Everywhere I've looked suggests putting the Provider in the _app.tsx
file. If I understand that correctly if I wrapp MyApp
with the provider, if someone goes straight to www.myurl.com/blog/my-blog-1 (from google), that will cause the provider to run its functions; even if that page won't call useContext
How do I only wrap three pages in the Provider and leave out the blog pages?
For example:
Here's what my _app.tsx
looks like:
import { AppProps } from 'next/app'
import '../styles/index.css'
export default function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
Per-Page Layouts If you need multiple layouts, you can add a property getLayout to your page, allowing you to return a React component for the layout. This allows you to define the layout on a per-page basis.
Wrap the entire app inside the AppContext.Provider In a Next. js app, we can see file _app. js inside the pages directory and, all the pages are rendered via this component. Here, we will import the AppContext file and languageObject we created earlier.
js. Starting from React v16. 3.0 , it is possible to use a new feature named context to pass data throughout the app.
A bit late to the party but there is actually an official way to do this:
Use a per page layout.
First slightly tweak your _app.tsx
file:
import type { ReactElement, ReactNode } from 'react';
import { AppProps } from 'next/app';
import type { NextPage } from 'next';
type NextPageWithLayout = NextPage & {
getLayout?: (page: ReactElement) => ReactNode;
};
type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
};
export const App = ({ Component, pageProps }: AppPropsWithLayout): unknown => {
// Use the custom layout defined at the page level, if available
const getLayout = Component.getLayout ?? ((page) => page);
return getLayout(<Component {...pageProps} />);
};
Then in a Page component write the following:
// DashboardPage.ts that need to have a UserProvider and CompanyProvider
import Layout from '@components/Layout'; // Default Layout that is imported for all the page
import { ReactElement } from 'react';
import { UserProvider } from '@contexts/user';
import { CompanyProvider } from '@contexts/company';
const DashboardPage = (): JSX.Element => {
return <DashboardContainer />;
};
// Custom Layout to wrap the page within the User and company providers
DashboardPage.getLayout = function getLayout(page: ReactElement) {
return (
<Layout title="Dashboard page">
<UserProvider>
<CompanyProvider>{page}</CompanyProvider>
</UserProvider>
</Layout>
);
};
export default DashboardPage;
Well, this is an interesting issue.
Challenge is in the way Next implements file-based routing. Since there is no way to create a wrapper for the group of pages only out-of-the-box thing you can do is to wrap the App in the context providers. But that doesn't really resolve your issue.
SOOO... I think there is a workaround. If you want to be able to wrap a certain group of pages in the context provider, first, you need to replace the file-based router with the react-router.
There is a very interesting article on this topic by Andrea Carraro. I think you should try this out: https://dev.to/toomuchdesign/next-js-react-router-2kl8
I will try to find another solution as well, but let me know did this worked for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With