1 year ago
#235233
JonQuayle
Next JS Issue with data from getInitialProps in _app.js "TypeError: Cannot read properties of undefined"
I'm having an issue displaying data pulled in (from Prismic) with getInitialProps in the _app.js file. I have followed the Prismic slice machine tutorial, which includes defining a header and navigation in Prismic and displaying that data on the frontend - that all works fine.
I've defined a footer now, have included the call for the footer data in the same place and way I have for the header data in the _app.js file, but that data does not display on the frontend. The error message I am seeing is:
TypeError: Cannot read properties of undefined (reading 'data')
and references the call stack to my _document.js file, but I cannot understand where the issue is in that file.
_document.js:
import Document, { Html, Head, Main, NextScript } from 'next/document'
import { repoName } from '../prismicConfiguration'
import Link from 'next/link'
export default class extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}
render() {
return (
<Html lang="en">
<Head>
<script async defer src={`//static.cdn.prismic.io/prismic.js?repo=${repoName}&new=true`} />
</Head>
<body className="">
<Main />
<NextScript />
</body>
</Html>
)
}
}
_app.js:
import React from 'react'
import NextApp from 'next/app'
import { Client } from '../utils/prismicHelpers'
import '../styles/style.scss'
export default class MyApp extends NextApp {
static async getInitialProps(appCtx) {
const menu = await Client().getSingle('menu') || null
const footer = await Client().getSingle('footer') || null
console.log("FOOTER", footer)
console.log("MENU",menu)
return {
props: {
menu: menu,
footer: footer
},
}
}
render() {
const { Component, pageProps, props } = this.props
return (
<Component {...pageProps} menu={props.menu} footer={props.footer} />
)
}
}
Footer.js (where the data should be getting displayed):
import React from 'react'
import Link from 'next/link'
// Project functions
import { linkResolver } from '../prismicConfiguration'
import { RichText } from 'prismic-reactjs'
// Footer component
export default function Footer({ footer }) {
return (
<footer className="footer">
<div className="container max-width-lg">
{footer.data.eyebrow}
<RichText render={footer.data.headline} />
<RichText render={footer.data.description} />
<Link href={linkResolver(footer.data.link)}>
<a>
{footer.data.linkLabel}
</a>
</Link>
{ footer.data.copyrightText }
{ footer.data.signoffText }
</div>
</footer>
)
}
I'm so confused as to why this footer data cannot be displayed or read when it has been defined and called in the same way as the header, which works completely fine. I am console logging both sets of data in the _app.js file and both are returning fine in the terminal, so I am confident what I am adding to the footer component file is correct. For some context, the reason I am pulling this data in the _app.js file is that its data that needs to be across all pages rather than calling it on every single page.
Where am I going wrong here?
Thanks
Addition: The Footer component is being added to a layout component:
import React from 'react'
import { useEffect } from 'react'
import Head from 'next/head'
import { useRouter } from 'next/router'
import Script from 'next/Script'
// Components
import Header from './Header'
import Footer from './Footer'
// Project functions
import * as gtag from '../lib/gtag'
// Layout component
const Layout = ({ children, footer, menu }) => {
const router = useRouter()
useEffect(() => {
const handleRouteChange = (url) => {
gtag.pageview(url)
}
router.events.on('routeChangeComplete', handleRouteChange)
return () => {
router.events.off('routeChangeComplete', handleRouteChange)
}
}, [router.events])
return (
<div className="page_wrapper">
<Head>
{/* <meta charSet="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon/favicon.ico" />
<script dangerouslySetInnerHTML={{ __html: `document.getElementsByTagName("html")[0].className += " js";`}}
/> */}
{/* <Link
rel="preload"
href="/fonts/font-file.woff2"
as="font"
crossOrigin=""
/> */}
</Head>
<Script
id="codyhouse-utils-js"
src="https://unpkg.com/codyhouse-framework/main/assets/js/util.js"
strategy="beforeInteractive"
/>
<Script
strategy="afterInteractive"
src={`https://www.googletagmanager.com/gtag/js?id=${gtag.GA_TRACKING_ID}`}
/>
<Script
id="gtag-init"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${gtag.GA_TRACKING_ID}', {
page_path: window.location.pathname,
});
`,
}}
/>
{/* <Script
src="https://www.google.com/recaptcha/api.js?&render=explicit"
strategy="afterInteractive"
/> */}
<Header menu={menu} />
<main>
{children}
</main>
<Footer footer={footer} />
</div>
);
};
export default Layout
javascript
html
reactjs
next.js
prismic.io
0 Answers
Your Answer