我试图理解为什么Next.js将我的一些页面构建为SSG,而有些则是静态的,而这些页面都在使用getStaticProps。
让我们以我的404页为例,它使用getStaticProps使用graphql从棱镜中获取数据。在我看来,它是作为一个静态网站呈现为SSG (因为它使用getStaticProps)。
我在我的500页中做了完全相同的事情,但是使用了不同的graphql查询,并且它被呈现为SSG (在我看来是正确的)。
为什么会这样呢?
404页:
const NotFound = ({ data: { page } }) => {
return (
<div className={'not-found'}>
<p className={'not-found__description'}>{RichText.asText(page.description)}</p>
</div>
);
};
export const getStaticProps = async (context) => {
const currentLanguage = getCurrentLocale(context);
const response = await apolloClient.query({
query: gql`
query {
}
`
};
return {
props: {
data: {
page: response
}
}
}
});
export default NotFound;500页:
const InternalServerError = ({ data: { page } }) => {
return (
<div className={'internal-server-error'}>
<p className={'internal-server-error__description'}>{RichText.asText(page.description)}</p>
</div>
);
};
export const getStaticProps = async (context) => {
const currentLanguage = getCurrentLocale(context);
const response = await apolloClient.query({
query: gql`
query {
}
`
});
return {
props: {
data: {
page: response
}
}
}
};

发布于 2021-05-07 04:11:49

Next.js中的404.tsx或404.js页面是唯一的,因为它不依赖服务器,并且始终是静态的--在构建时完全依赖静态html (没有json) --即使在文件中使用GetStaticProps时也是如此。
404页只是一个捕获所有funnel路由,当用户导航到站点作为基本URL时不存在的路径时,用户将被重定向到该路由。因此,它不依赖于初始构建的服务器。这是不存在的路径的退路,而不是其他的。另一方面,500页处理应用程序中的内部错误,因此它确实依赖于.html和.json文件类型来确定错误的性质。
有趣的是,如果您在本地检查.next目录的内容,您将注意到使用GetStaticProps的所有页面都具有静态生成的.json和.html文件。使用GetStaticProps和revalidate的页面返回=== Incremental Static Regeneration或ISR。ISR是SSG和SSR的理想混合体,具有扫描生产中传入的更改/更新的后台函数(您指定的数字是在可能的更新之间以秒为单位的时间量)。因此,使用GetStaticProps + ISR的页面在.next目录中生成三种文件类型-- .html、.json和.js。也就是说,使用GetServerSideProps或GetInitialProps的页面只在.next目录中生成.js文件。最后,没有使用上述任何方法的纯Static页面只生成.html文件。
404页及其静态特性的思想是通过加快自定义oops! that path doesn't exist页面的呈现(或更准确地说是预录制)来增强UX,以便用户能够尽快返回到实际应用程序。
例如,我的404.tsx页面中有以下内容,但在构建时它仍然呈现为静态html。
import { Container } from '@/components/UI';
import { initializeApollo, addApolloState } from '@/lib/apollo';
import { NotFound } from '@/components/NotFound';
import { AppLayout } from '@/components/Layout';
import {
GetStaticPropsContext,
GetStaticPropsResult,
InferGetStaticPropsType
} from 'next';
import {
NotFoundQuery,
NotFoundDocument,
NotFoundQueryVariables,
DynamicNavQuery,
DynamicNavDocument,
DynamicNavQueryVariables,
WordpressMenuNodeIdTypeEnum,
WordpressMediaItemSizeEnum,
WordpressPageIdType
} from '@/graphql/generated/graphql';
export function SOS({
notFound,
Header,
Footer
}: InferGetStaticPropsType<typeof getStaticProps>) {
return (
<>
<AppLayout title={'✂ 404 ✂'} Header={Header} Footer={Footer}>
<Container clean className='fit'>
<NotFound notFound={notFound} />
</Container>
</AppLayout>
</>
);
}
export async function getStaticProps(
ctx: GetStaticPropsContext
): Promise<
GetStaticPropsResult<{
notFound: NotFoundQuery['NotFound'];
Header: DynamicNavQuery['Header'];
Footer: DynamicNavQuery['Footer'];
}>
> {
const params = ctx.params!;
console.log(params ?? '');
const apolloClient = initializeApollo();
await apolloClient.query<
DynamicNavQuery,
DynamicNavQueryVariables
>({
query: DynamicNavDocument,
variables: {
idHead: 'Header',
idTypeHead: WordpressMenuNodeIdTypeEnum.NAME,
idTypeFoot: WordpressMenuNodeIdTypeEnum.NAME,
idFoot: 'Footer'
}
});
await apolloClient.query<NotFoundQuery, NotFoundQueryVariables>(
{
query: NotFoundDocument,
variables: {
id: '/404-not-found/' as '/404/',
idType: WordpressPageIdType.URI,
size: WordpressMediaItemSizeEnum.LARGE
}
}
);
return addApolloState(apolloClient, {
props: {},
revalidate: 60
});
}
export default SOS;有趣的是,由于在我的GetStaticProps页面中使用了ISR和revalidate,所以.next目录的内容反映了这一点,因为404 (.js, .json, .html)提供了所有三种文件类型。如果您在自定义的getInitialProps或_app.js文件中使用_app.js,那么整个应用程序都将禁用自动静态优化(静态页面预录制)。尝试一下,如果您好奇的话,它应该会导致404页面在构建日志中的旁边有一个lambda。但是,由于您已经拥有了GetStaticProps,它应该覆盖您的根app页面使用GetInitialProps导致的应用程序范围的静态去优化。
例如,在创建自定义的GetInitialProps页面之前,我在_app.tsx中使用了404.tsx。我决定拉建日志,并采取了一个伴随的屏幕快照。
Warning: You have opted-out of Automatic Static Optimization due to `getInitialProps` in `pages/_app`. This does not opt-out pages with `getStaticProps`.

发布于 2021-05-06 21:41:23
您的代码中的404页缺少括号吗?
const response = await apolloClient.query({
query: gql`
query {
}
`
};应该是
const response = await apolloClient.query({
query: gql`
query {
}
`
});https://stackoverflow.com/questions/67315057
复制相似问题