Reputation: 318
I'm working on my first integration of Sanity with Next.Js, trying to add a blog to a personal site. Dev works fine, but when I go to deploy, or do a build, I get an error that it can't find one of the props for the blog page.
Error thrown is this:
TypeError: Cannot read property 'title' of undefined
This is what I'm using for my [slug].js file:
import { useState, useEffect } from 'react';
import { motion } from 'framer-motion';
import Head from 'next/head';
import { useRouter } from 'next/router';
import Layout from '../../components/layout';
import Scrollbar from 'react-scrollbars-custom';
import Transitions from '../../lib/transitions';
import BlockContent from '@sanity/block-content-to-react';
import { postQuery, postSlugsQuery } from '../../lib/grocQueries';
import { getClient, overlayDrafts, sanityClient } from '../../lib/sanity.server';
import { urlForImage, usePreviewSubscription } from '../../lib/sanity';
const pageVariants = Transitions.pageVariant;
const pageTransition = Transitions.pageTransition;
export const Post = ({ data = {}, preview }) => {
const router = useRouter();
const slug = data?.post?.slug;
const {
data: { post, morePosts },
} = usePreviewSubscription(postQuery, {
params: { slug },
initialData: data,
enabled: preview && slug,
});
return (
<Layout>
<motion.article className='blog-article' initial='initial' animate='in' exit='out' variants={pageVariants} transition={pageTransition}>
<Scrollbar style={{ width: '100%', height: '100%' }}>
<figure className='hero-container'>
<h1 className='blog-title'>{post.title} </h1>
{post.mainImage && <img className='blog-hero' alt='Some alt Text' src={urlForImage(post.mainImage).url()} />}
</figure>
<div className='copy-block'>
<BlockContent blocks={post.body} imageOptions={{ w: 860, fit: 'max' }} {...sanityClient.config()} />
</div>
</Scrollbar>
</motion.article>
</Layout>
);
};
export async function getStaticProps({ params, preview = false }) {
const { post, morePosts } = await getClient(preview).fetch(postQuery, {
slug: params.slug,
});
return {
props: {
preview,
data: {
post,
morePosts: overlayDrafts(morePosts),
},
},
};
}
export async function getStaticPaths() {
const paths = await sanityClient.fetch(postSlugsQuery);
return {
paths: paths.map((slug) => ({ params: { slug } })),
fallback: true,
};
}
export default Post;
Upvotes: 1
Views: 1066
Reputation: 13588
There are 2 things may want to add a in static generated page so it knows what to do if there isn't any props.
Add props checking in page, so it will not fail build.
if (!props) return null // or !data in your case.
Add notFound return props in getStaticProps so it knows how to handle 404 properly.
return {
notFound: true,
revalidate: 300,
}
Upvotes: 1
Reputation: 149
<figure className='hero-container'>
<h1 className='blog-title'>{post?.title} </h1>
{post?.mainImage && <img className='blog-hero' alt='Some alt Text' src={urlForImage(post?.mainImage).url()} />}
</figure>
During the build time next not aware of the post object and its key so it's better to make an optional chaining.
Upvotes: 1