Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add error messages for dynamic SSG page without getStaticPaths #10620

Merged
merged 7 commits into from
Feb 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions packages/next/build/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -543,10 +543,19 @@ export async function isPageStatic(
throw new Error(SERVER_PROPS_SSG_CONFLICT)
}

const pageIsDynamic = isDynamicRoute(page)
// A page cannot have static parameters if it is not a dynamic page.
if (hasStaticProps && hasStaticPaths && !isDynamicRoute(page)) {
if (hasStaticProps && hasStaticPaths && !pageIsDynamic) {
throw new Error(
`unstable_getStaticPaths can only be used with dynamic pages. https://nextjs.org/docs#dynamic-routing`
`unstable_getStaticPaths can only be used with dynamic pages, not '${page}'.` +
`\nLearn more: https://nextjs.org/docs#dynamic-routing`
)
}

if (hasStaticProps && pageIsDynamic && !hasStaticPaths) {
throw new Error(
`unstable_getStaticPaths is required for dynamic SSG pages and is missing for '${page}'.` +
`\nRead more: https://err.sh/next.js/invalid-getstaticpaths-value`
)
}

Expand Down
13 changes: 11 additions & 2 deletions packages/next/next-server/server/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ export async function renderToHTML(

const hasPageGetInitialProps = !!(Component as any).getInitialProps

const pageIsDynamic = isDynamicRoute(pathname)

const isAutoExport =
!hasPageGetInitialProps &&
defaultAppGetInitialProps &&
Expand All @@ -326,7 +328,7 @@ export async function renderToHTML(
if (
process.env.NODE_ENV !== 'production' &&
(isAutoExport || isFallback) &&
isDynamicRoute(pathname) &&
pageIsDynamic &&
didRewrite
) {
// TODO: add err.sh when rewrites go stable
Expand Down Expand Up @@ -361,6 +363,13 @@ export async function renderToHTML(
)
}

if (isSpr && pageIsDynamic && !unstable_getStaticPaths) {
throw new Error(
`unstable_getStaticPaths is required for dynamic SSG pages and is missing for '${pathname}'.` +
`\nRead more: https://err.sh/next.js/invalid-getstaticpaths-value`
)
}

if (dev) {
const { isValidElementType } = require('react-is')
if (!isValidElementType(Component)) {
Expand Down Expand Up @@ -459,7 +468,7 @@ export async function renderToHTML(
// invoke, where we'd have to consider server & serverless.
const previewData = tryGetPreviewData(req, res, previewProps)
const data = await unstable_getStaticProps!({
...(isDynamicRoute(pathname)
...(pageIsDynamic
? {
params: query as ParsedUrlQuery,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,10 @@ export function unstable_getStaticProps({ params }) {
return { props: { params } }
}

export function unstable_getStaticPaths() {
return {
paths: [],
}
}

export default All
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,10 @@ export function unstable_getStaticProps({ params }) {
return { props: { params } }
}

export function unstable_getStaticPaths() {
return {
paths: [],
}
}

export default All
29 changes: 28 additions & 1 deletion test/integration/prerender/test/index.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-env jest */
/* global jasmine */
import fs from 'fs-extra'
import { join } from 'path'
import { join, dirname } from 'path'
import cheerio from 'cheerio'
import webdriver from 'next-webdriver'
import escapeRegex from 'escape-string-regexp'
Expand Down Expand Up @@ -448,6 +448,33 @@ const runTests = (dev = false) => {
}
})

it('should error on dynamic page without getStaticPaths', async () => {
const curPage = join(__dirname, '../pages/temp/[slug].js')
await fs.mkdirp(dirname(curPage))
await fs.writeFile(
curPage,
`
export async function unstable_getStaticProps() {
return {
props: {
hello: 'world'
}
}
}
export default () => 'oops'
`
)
await waitFor(1000)
try {
const html = await renderViaHTTP(appPort, '/temp/hello')
expect(html).toMatch(
/unstable_getStaticPaths is required for dynamic SSG pages and is missing for/
)
} finally {
await fs.remove(curPage)
}
})

it('should not re-call getStaticProps when updating query', async () => {
const browser = await webdriver(appPort, '/something?hello=world')
await waitFor(2000)
Expand Down