Skip to content

Commit 55cea0a

Browse files
authored
Handle getStaticPaths with prerendered pages (#5734)
* fix(#5661): ensure getStaticPaths is correctly handled for prerendered pages * test: add prerender getStaticPaths cases * chore: add changeset * test: add props to test suite * chore: update lockfile Co-authored-by: Nate Moore <[email protected]>
1 parent cc4606d commit 55cea0a

18 files changed

Lines changed: 408 additions & 5 deletions

File tree

.changeset/lemon-eagles-worry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
Fix `prerender` when used with `getStaticPaths`

packages/astro/src/@types/astro.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,7 @@ export type AsyncRendererComponentFn<U> = (
10041004
export interface ComponentInstance {
10051005
default: AstroComponentFactory;
10061006
css?: string[];
1007+
prerender?: boolean;
10071008
getStaticPaths?: (options: GetStaticPathsOptions) => GetStaticPathsResult;
10081009
}
10091010

packages/astro/src/core/build/generate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ async function getPathsForRoute(
181181
route: pageData.route,
182182
isValidate: false,
183183
logging: opts.logging,
184-
ssr: false,
184+
ssr: opts.settings.config.output === 'server',
185185
})
186186
.then((_result) => {
187187
const label = _result.staticPaths.length === 1 ? 'page' : 'pages';

packages/astro/src/core/build/vite-plugin-ssr.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ function buildManifest(
139139
const joinBase = (pth: string) => (bareBase ? bareBase + '/' + pth : pth);
140140

141141
for (const pageData of eachPrerenderedPageData(internals)) {
142+
if (!pageData.route.pathname) continue;
143+
142144
const outFolder = getOutFolder(
143145
opts.settings.config,
144146
pageData.route.pathname!,

packages/astro/src/core/errors/errors-data.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ but ${plural ? 'none were.' : 'it was not.'} able to server-side render \`${comp
353353
'`getStaticPaths()` function is required for dynamic routes. Make sure that you `export` a `getStaticPaths` function from your dynamic route.',
354354
hint: `See https://docs.astro.build/en/core-concepts/routing/#dynamic-routes for more information on dynamic routes.
355355
356-
Alternatively, set \`output: "server"\` in your Astro config file to switch to a non-static server build.
356+
Alternatively, set \`output: "server"\` in your Astro config file to switch to a non-static server build. This error can also occur if using \`export const prerender = true;\`.
357357
See https://docs.astro.build/en/guides/server-side-rendering/ for more information on non-static rendering.`,
358358
},
359359
/**

packages/astro/src/core/render/route-cache.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export async function callGetStaticPaths({
3131
}: CallGetStaticPathsOptions): Promise<RouteCacheEntry> {
3232
validateDynamicRouteModule(mod, { ssr, logging, route });
3333
// No static paths in SSR mode. Return an empty RouteCacheEntry.
34-
if (ssr) {
34+
if (ssr && !mod.prerender) {
3535
return { staticPaths: Object.assign([], { keyed: new Map() }) };
3636
}
3737
// Add a check here to make TypeScript happy.

packages/astro/src/core/routing/validation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ export function validateDynamicRouteModule(
3131
route: RouteData;
3232
}
3333
) {
34-
if (ssr && mod.getStaticPaths) {
34+
if (ssr && mod.getStaticPaths && !mod.prerender) {
3535
warn(logging, 'getStaticPaths', 'getStaticPaths() is ignored when "output: server" is set.');
3636
}
37-
if (!ssr && !mod.getStaticPaths) {
37+
if ((!ssr || mod.prerender) && !mod.getStaticPaths) {
3838
throw new AstroError({
3939
...AstroErrorData.GetStaticPathsRequired,
4040
location: { file: route.component },
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "@test/ssr-prerender-get-static-paths",
3+
"version": "0.0.0",
4+
"private": true,
5+
"dependencies": {
6+
"astro": "workspace:*"
7+
}
8+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
export function getStaticPaths({ paginate }) {
3+
if (globalThis.isCalledOnce) {
4+
throw new Error("Can only be called once!");
5+
}
6+
globalThis.isCalledOnce = true;
7+
return [
8+
{params: {calledTwiceTest: 'a'}},
9+
{params: {calledTwiceTest: 'b'}},
10+
{params: {calledTwiceTest: 'c'}},
11+
];
12+
}
13+
export const prerender = true;
14+
const { params } = Astro;
15+
---
16+
17+
<html>
18+
<head>
19+
<title>Page {params.calledTwiceTest}</title>
20+
</head>
21+
<body></body>
22+
</html>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
export async function getStaticPaths() {
3+
return [
4+
{ params: { year: '2022', slug: 'post-1' } },
5+
{ params: { year: 2022, slug: 'post-2' } },
6+
{ params: { slug: 'post-2', year: '2022' } },
7+
]
8+
}
9+
10+
export const prerender = true;
11+
const { year, slug } = Astro.params
12+
---
13+
14+
<html>
15+
<head>
16+
<title>{year} | {slug}</title>
17+
</head>
18+
<body></body>
19+
</html>

0 commit comments

Comments
 (0)