Skip to content

Commit bd5b88f

Browse files
committed
Update invalid exports messaging
1 parent 3066205 commit bd5b88f

File tree

4 files changed

+36
-29
lines changed

4 files changed

+36
-29
lines changed

.changeset/weak-mayflies-lie.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@react-router/dev": patch
3+
---
4+
5+
[REMOVE] Update invalid route export messages

docs/how-to/pre-rendering.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,14 @@ sirv-cli build/client --single index.html
149149
# If you pre-rendered the `/` route
150150
sirv-cli build/client --single __spa-fallback.html
151151
```
152+
153+
### Invalid Exports
154+
155+
When pre-rendering with `ssr:false`, React Router will error at build time if you have invalid exports to help prevent some mistakes that can be easily overlooked.
156+
157+
- `headers`/`action` functions are prohibited in all routes because there will be no runtime server on which to run them
158+
- When using `ssr:false` without a `prerender` config (SPA Mode), a `loader` is permitted on the root route only
159+
- When using `ssr:false` with a `prerender` config, a `loader` is permitted on any route matched by a `prerender` path
160+
- If you are using a `loader` on a pre-rendered route that has child routes, you will need to make sure the parent `loaderData` can be determined at run-time properly by either:
161+
- Pre-rendering all child routes so that the parent `loader` can be called at build-time for each child route path and rendered into a `.data` file, or
162+
- Use a `clientLoader` on the parent that can be called at run-time for non-pre-rendered child paths

integration/vite-prerender-test.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -805,9 +805,9 @@ test.describe("Prerendering", () => {
805805
let result = build({ cwd });
806806
let stderr = result.stderr.toString("utf8");
807807
expect(stderr).toMatch(
808-
"Prerender: 2 invalid route export(s) in `routes/a` when prerendering " +
809-
"with `ssr:false`: headers, action. " +
810-
"See https://reactrouter.com/how-to/pre-rendering for more information."
808+
"Prerender: 2 invalid route export(s) in `routes/a` when pre-rendering " +
809+
"with `ssr:false`: `headers`, `action`. " +
810+
"See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information."
811811
);
812812
});
813813

@@ -833,10 +833,9 @@ test.describe("Prerendering", () => {
833833
let result = build({ cwd });
834834
let stderr = result.stderr.toString("utf8");
835835
expect(stderr).toMatch(
836-
"Prerender: 1 invalid route export in `routes/b` when using `ssr:false` " +
837-
"with `prerender` because the route is never prerendered so the loader " +
838-
"will never be called. See https://reactrouter.com/how-to/pre-rendering " +
839-
"for more information."
836+
"Prerender: 1 invalid route export in `routes/b` when pre-rendering " +
837+
"with `ssr:false`: `loader`. " +
838+
"See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information."
840839
);
841840
});
842841

@@ -860,12 +859,9 @@ test.describe("Prerendering", () => {
860859
let result = build({ cwd });
861860
let stderr = result.stderr.toString("utf8");
862861
expect(stderr).toMatch(
863-
"Prerender: 1 invalid route export in `routes/a` when using `ssr:false` " +
864-
"with `prerender`: `loader`. This is because the route has non-pre-rendered " +
865-
"children paths and does not have it's own `clientLoader` to be used " +
866-
"when those paths are hydrated as a SPA. You can fix this error by adding " +
867-
"a `clientLoader` to the route or by pre-rendering the children paths. " +
868-
"See https://reactrouter.com/how-to/pre-rendering for more information."
862+
"Prerender: 1 invalid route export in `routes/a` when pre-rendering " +
863+
"with `ssr:false`: `loader`. " +
864+
"See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information."
869865
);
870866
});
871867

packages/react-router-dev/vite/plugin.ts

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,7 +2516,7 @@ async function prerenderResourceRoute(
25162516
throw new Error(
25172517
`Prerender (resource): Received a ${response.status} status code from ` +
25182518
`\`entry.server.tsx\` while prerendering the \`${normalizedPath}\` ` +
2519-
`path.\n${content.toString('utf8')}`
2519+
`path.\n${content.toString("utf8")}`
25202520
);
25212521
}
25222522

@@ -2662,35 +2662,30 @@ async function validateSsrFalsePrerenderExports(
26622662
if (exports.includes("action")) invalidApis.push("action");
26632663
if (invalidApis.length > 0) {
26642664
errors.push(
2665-
`Prerender: ${invalidApis.length} invalid route export(s) in ` +
2666-
`\`${route.id}\` when prerendering with \`ssr:false\`: ` +
2667-
`${invalidApis.join(", ")}. ` +
2668-
"See https://reactrouter.com/how-to/pre-rendering for more information."
2665+
`Prerender: ${invalidApis.length} invalid route export(s) in \`${route.id}\` ` +
2666+
"when pre-rendering with `ssr:false`: " +
2667+
`${invalidApis.map((a) => `\`${a}\``).join(", ")}. ` +
2668+
"See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information."
26692669
);
26702670
}
26712671

26722672
// `loader` is only valid if the route is matched by a `prerender` path
26732673
if (!prerenderedRoutes.has(routeId)) {
26742674
if (exports.includes("loader")) {
26752675
errors.push(
2676-
`Prerender: 1 invalid route export in \`${route.id}\` when ` +
2677-
"using `ssr:false` with `prerender` because the route is never " +
2678-
"prerendered so the loader will never be called. " +
2679-
"See https://reactrouter.com/how-to/pre-rendering for more information."
2676+
`Prerender: 1 invalid route export in \`${route.id}\` ` +
2677+
"when pre-rendering with `ssr:false`: `loader`. " +
2678+
"See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information."
26802679
);
26812680
}
26822681

26832682
let parentRoute = route.parentId ? manifest.routes[route.parentId] : null;
26842683
while (parentRoute && parentRoute.id !== "root") {
26852684
if (parentRoute.hasLoader && !parentRoute.hasClientLoader) {
26862685
errors.push(
2687-
`Prerender: 1 invalid route export in \`${parentRoute.id}\` when using ` +
2688-
"`ssr:false` with `prerender`: `loader`. This is because the route " +
2689-
"has non-pre-rendered children paths and does not have it's own " +
2690-
"`clientLoader` to be used when those paths are hydrated as a SPA. " +
2691-
"You can fix this error by adding a `clientLoader` to the route or " +
2692-
"by pre-rendering the children paths. " +
2693-
"See https://reactrouter.com/how-to/pre-rendering for more information."
2686+
`Prerender: 1 invalid route export in \`${parentRoute.id}\` when ` +
2687+
"pre-rendering with `ssr:false`: `loader`. " +
2688+
"See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information."
26942689
);
26952690
}
26962691
parentRoute =

0 commit comments

Comments
 (0)