diff --git a/packages/next/lib/constants.ts b/packages/next/lib/constants.ts index 7c9d3bf60d4f8..b4efb3466f6d0 100644 --- a/packages/next/lib/constants.ts +++ b/packages/next/lib/constants.ts @@ -33,3 +33,9 @@ export const SERVER_PROPS_SSG_CONFLICT = `You can not use getStaticProps with ge export const PAGES_404_GET_INITIAL_PROPS_ERROR = `\`pages/404\` can not have getInitialProps/getServerSideProps, https://err.sh/next.js/404-get-initial-props` export const SERVER_PROPS_EXPORT_ERROR = `pages with \`getServerSideProps\` can not be exported. See more info here: https://err.sh/next.js/gss-export` + +export const UNSTABLE_REVALIDATE_RENAME_ERROR = + 'The `revalidate` property is not yet available for general use.\n' + + 'To try the experimental implementation, please use `unstable_revalidate` instead.\n' + + "We're excited for you to try this feature—please share all feedback on the RFC:\n" + + 'https://nextjs.link/issg' diff --git a/packages/next/next-server/server/render.tsx b/packages/next/next-server/server/render.tsx index 9919c5ef4e7d8..ec4178b5987bb 100644 --- a/packages/next/next-server/server/render.tsx +++ b/packages/next/next-server/server/render.tsx @@ -7,6 +7,7 @@ import { SERVER_PROPS_GET_INIT_PROPS_CONFLICT, SERVER_PROPS_SSG_CONFLICT, SSG_GET_INITIAL_PROPS_CONFLICT, + UNSTABLE_REVALIDATE_RENAME_ERROR, } from '../../lib/constants' import { isSerializableProps } from '../../lib/is-serializable-props' import { isInAmpMode } from '../lib/amp' @@ -518,9 +519,13 @@ export async function renderToHTML( } const invalidKeys = Object.keys(data).filter( - key => key !== 'revalidate' && key !== 'props' + key => key !== 'unstable_revalidate' && key !== 'props' ) + if (invalidKeys.includes('revalidate')) { + throw new Error(UNSTABLE_REVALIDATE_RENAME_ERROR) + } + if (invalidKeys.length) { throw new Error(invalidKeysMsg('getStaticProps', invalidKeys)) } @@ -535,41 +540,41 @@ export async function renderToHTML( ) } - if (typeof data.revalidate === 'number') { - if (!Number.isInteger(data.revalidate)) { + if (typeof data.unstable_revalidate === 'number') { + if (!Number.isInteger(data.unstable_revalidate)) { throw new Error( - `A page's revalidate option must be seconds expressed as a natural number. Mixed numbers, such as '${data.revalidate}', cannot be used.` + + `A page's revalidate option must be seconds expressed as a natural number. Mixed numbers, such as '${data.unstable_revalidate}', cannot be used.` + `\nTry changing the value to '${Math.ceil( - data.revalidate + data.unstable_revalidate )}' or using \`Math.ceil()\` if you're computing the value.` ) - } else if (data.revalidate <= 0) { + } else if (data.unstable_revalidate <= 0) { throw new Error( `A page's revalidate option can not be less than or equal to zero. A revalidate option of zero means to revalidate after _every_ request, and implies stale data cannot be tolerated.` + `\n\nTo never revalidate, you can set revalidate to \`false\` (only ran once at build-time).` + `\nTo revalidate as soon as possible, you can set the value to \`1\`.` ) - } else if (data.revalidate > 31536000) { + } else if (data.unstable_revalidate > 31536000) { // if it's greater than a year for some reason error console.warn( `Warning: A page's revalidate option was set to more than a year. This may have been done in error.` + `\nTo only run getStaticProps at build-time and not revalidate at runtime, you can set \`revalidate\` to \`false\`!` ) } - } else if (data.revalidate === true) { + } else if (data.unstable_revalidate === true) { // When enabled, revalidate after 1 second. This value is optimal for // the most up-to-date page possible, but without a 1-to-1 // request-refresh ratio. - data.revalidate = 1 + data.unstable_revalidate = 1 } else { // By default, we never revalidate. - data.revalidate = false + data.unstable_revalidate = false } props.pageProps = data.props // pass up revalidate and props for export // TODO: change this to a different passing mechanism - ;(renderOpts as any).revalidate = data.revalidate + ;(renderOpts as any).revalidate = data.unstable_revalidate ;(renderOpts as any).pageData = props } diff --git a/packages/next/types/index.d.ts b/packages/next/types/index.d.ts index bb6b2a6bff6d5..c468a324447c4 100644 --- a/packages/next/types/index.d.ts +++ b/packages/next/types/index.d.ts @@ -74,7 +74,7 @@ export type GetStaticProps< previewData?: any }) => Promise<{ props: P - revalidate?: number | boolean + unstable_revalidate?: number | boolean }> export type GetStaticPaths< diff --git a/test/integration/env-config/app/pages/index.js b/test/integration/env-config/app/pages/index.js index e02e79b019b8c..137c507e90755 100644 --- a/test/integration/env-config/app/pages/index.js +++ b/test/integration/env-config/app/pages/index.js @@ -30,7 +30,7 @@ export async function getStaticProps() { // Do not pass any sensitive values here as they will // be made PUBLICLY available in `pageProps` props: { env: items }, - revalidate: 1, + unstable_revalidate: 1, } } diff --git a/test/integration/env-config/app/pages/some-ssg.js b/test/integration/env-config/app/pages/some-ssg.js index e02e79b019b8c..137c507e90755 100644 --- a/test/integration/env-config/app/pages/some-ssg.js +++ b/test/integration/env-config/app/pages/some-ssg.js @@ -30,7 +30,7 @@ export async function getStaticProps() { // Do not pass any sensitive values here as they will // be made PUBLICLY available in `pageProps` props: { env: items }, - revalidate: 1, + unstable_revalidate: 1, } } diff --git a/test/integration/prerender/pages/another/index.js b/test/integration/prerender/pages/another/index.js index 1e2d91783b766..42cd8b44fb7d0 100644 --- a/test/integration/prerender/pages/another/index.js +++ b/test/integration/prerender/pages/another/index.js @@ -18,7 +18,7 @@ export async function getStaticProps() { world: text, time: new Date().getTime(), }, - revalidate: true, + unstable_revalidate: true, } } diff --git a/test/integration/prerender/pages/blog/[post]/[comment].js b/test/integration/prerender/pages/blog/[post]/[comment].js index 39ee2d9afce5b..3ddcfc1949cd0 100644 --- a/test/integration/prerender/pages/blog/[post]/[comment].js +++ b/test/integration/prerender/pages/blog/[post]/[comment].js @@ -18,7 +18,7 @@ export async function getStaticProps({ params }) { comment: params.comment, time: new Date().getTime(), }, - revalidate: 2, + unstable_revalidate: 2, } } diff --git a/test/integration/prerender/pages/blog/[post]/index.js b/test/integration/prerender/pages/blog/[post]/index.js index ee32341ab1f3f..d14a03d8afca9 100644 --- a/test/integration/prerender/pages/blog/[post]/index.js +++ b/test/integration/prerender/pages/blog/[post]/index.js @@ -42,7 +42,7 @@ export async function getStaticProps({ params }) { post: params.post, time: (await import('perf_hooks')).performance.now(), }, - revalidate: 10, + unstable_revalidate: 10, } } diff --git a/test/integration/prerender/pages/blog/index.js b/test/integration/prerender/pages/blog/index.js index 71ba9e9b1cca0..1a9e782fadd6c 100644 --- a/test/integration/prerender/pages/blog/index.js +++ b/test/integration/prerender/pages/blog/index.js @@ -7,7 +7,7 @@ export async function getStaticProps() { slugs: ['post-1', 'post-2'], time: (await import('perf_hooks')).performance.now(), }, - revalidate: 10, + unstable_revalidate: 10, } } diff --git a/test/integration/prerender/pages/catchall-explicit/[...slug].js b/test/integration/prerender/pages/catchall-explicit/[...slug].js index 6b3bfbccacff3..419cd89c33d48 100644 --- a/test/integration/prerender/pages/catchall-explicit/[...slug].js +++ b/test/integration/prerender/pages/catchall-explicit/[...slug].js @@ -7,7 +7,7 @@ export async function getStaticProps({ params: { slug } }) { props: { slug, }, - revalidate: 1, + unstable_revalidate: 1, } } diff --git a/test/integration/prerender/pages/catchall/[...slug].js b/test/integration/prerender/pages/catchall/[...slug].js index 0ce61b73d3a5e..57bf14e3b39bc 100644 --- a/test/integration/prerender/pages/catchall/[...slug].js +++ b/test/integration/prerender/pages/catchall/[...slug].js @@ -9,7 +9,7 @@ export async function getStaticProps({ params: { slug } }) { props: { slug, }, - revalidate: 1, + unstable_revalidate: 1, } } diff --git a/test/integration/prerender/pages/index.js b/test/integration/prerender/pages/index.js index 59b333fddfe53..4398d653cc93d 100644 --- a/test/integration/prerender/pages/index.js +++ b/test/integration/prerender/pages/index.js @@ -5,7 +5,7 @@ export async function getStaticProps() { return { props: { world: 'world', time: new Date().getTime() }, // bad-prop - revalidate: 1, + unstable_revalidate: 1, } } diff --git a/test/integration/prerender/pages/something.js b/test/integration/prerender/pages/something.js index 180818998c8d8..009ef6a9d56d9 100644 --- a/test/integration/prerender/pages/something.js +++ b/test/integration/prerender/pages/something.js @@ -10,7 +10,7 @@ export async function getStaticProps({ params }) { time: new Date().getTime(), random: Math.random(), }, - revalidate: false, + unstable_revalidate: false, } } diff --git a/test/integration/prerender/pages/user/[user]/profile.js b/test/integration/prerender/pages/user/[user]/profile.js index 95bf6e7ad7b0d..7ab61dc494de4 100644 --- a/test/integration/prerender/pages/user/[user]/profile.js +++ b/test/integration/prerender/pages/user/[user]/profile.js @@ -11,7 +11,7 @@ export async function getStaticProps({ params }) { user: params.user, time: (await import('perf_hooks')).performance.now(), }, - revalidate: 10, + unstable_revalidate: 10, } } diff --git a/test/integration/typescript/pages/ssg/[slug].tsx b/test/integration/typescript/pages/ssg/[slug].tsx index 5d6af8cfcc780..e41f6dc3d7e25 100644 --- a/test/integration/typescript/pages/ssg/[slug].tsx +++ b/test/integration/typescript/pages/ssg/[slug].tsx @@ -20,7 +20,7 @@ export const getStaticProps: GetStaticProps = async ({ }) => { return { props: { data: params!.slug }, - revalidate: false, + unstable_revalidate: false, } }