I add header component to layout but i don't want to send props from layout to header for every page I want use getInitialProps
layout.js
import Header from './header'
export default ({title}) => (
<div>
<Head>
<title>{ title }</title>
<meta charSet='utf-8' />
</Head>
<Header />
{children}
</div>
)
header.js
export default class Header extends Component {
static async getInitialProps () {
const headerResponse = await fetch(someapi)
return headerResponse;
}
render() {
console.log({props: this.props})
return (
<div></div>
);
}
}
console: props: {}
App.js
import Layout from './layout'
import Page from './page'
import axios from 'axios'
const app = (props) => (
<Layout >
<Page {...props}/>
</Layout>
)
app.getInitialProps = async function(){
try {
const response = await axios.get(someUrl)
return response.data;
} catch(e) {
throw new Error(e);
}
}
export default app
I want to use get initial props in Header component but it not firing
getInitialProps is used to asynchronously fetch some data, which then populates props . Data returned from getInitialProps is serialized when server rendering, similar to what JSON. stringify does. Make sure the returned object from getInitialProps is a plain Object and not using Date , Map or Set .
Solution #1: getInitialProps() To do a quick recap, getInitialProps() is a function/method that lets you write server code before the page component in Next. JS gets rendered. In that function/method you can redirect a user to an internal or external URL via the server side.
Addition of getServerSideProp and getServerSideProp is greatly desirable, since getInitialProps will be deprecated and most likely deleted from next.
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. Since we're returning a function, we can have complex nested layouts if desired.
EDIT: 2021 way of doing this :
// with typescript remove type if you need a pure javascript solution
// _app.tsx or _app.jsx
import type { AppProps } from 'next/app';
import Layout from '../components/Layout';
export default function App({ Component, pageProps }: AppProps) {
return (
<Layout {...pageProps}>
<Component {...pageProps} />
</Layout>
);
}
// In order to pass props from your component you may need either `getStaticProps` or `getServerSideProps`.
// You should definitely not do that inside your `_app.tsx` to avoid rendering your whole app in SSR;
// Example for SSR
export async function getServerSideProps() {
// Fetch data from external API
const res = await fetch(`https://.../data`)
const data = await res.json()
// Pass data to the page via props
return { props: { data } }
}
Next.js uses the App component to initialize pages. You can override it and control the page initialization.
What you could do is, put your logic inside the _app
override and pass it to your children components, example with a Layout
component.
Create a page/_app.js
import React from 'react'
import App, { Container } from 'next/app'
import Layout from '../components/Layout'
export default class MyApp extends App {
static async getInitialProps({ Component, router, ctx }) {
let pageProps = {}
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
/* your own logic */
return { pageProps }
}
render () {
const { Component, pageProps } = this.props
return (
<Container>
<Layout {...pageProps}>
<Component {...pageProps} />
</Layout>
</Container>
)
}
}
There is a good example from zeit at github
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