Skip to content

Commit bfe7442

Browse files
committed
Keep non-ServerComponent exports as client components
1 parent 368e0cb commit bfe7442

File tree

5 files changed

+80
-248
lines changed

5 files changed

+80
-248
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@react-router/dev": patch
3+
"react-router": patch
4+
---
5+
6+
In (unstable) RSC Framework Mode, always keep the `ErrorBoundary`, `HydrateFallback` and `Layout` Route Module exports as client components, even when a `ServerComponent` export is present

docs/how-to/react-server-components.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ The quickest way to get started is with one of our templates.
3232

3333
These templates come with React Router RSC APIs already configured, offering you out of the box features such as:
3434

35-
- Server Component Routes
3635
- Server Side Rendering (SSR)
36+
- Server Components
3737
- Client Components (via [`"use client"`][use-client-docs] directive)
3838
- Server Functions (via [`"use server"`][use-server-docs] directive)
3939

@@ -177,9 +177,9 @@ export default function Route({
177177
}
178178
```
179179

180-
### Server Component Routes
180+
### Route Server Components
181181

182-
If a route exports a `ServerComponent` instead of the typical `default` component export, this component along with other route components (`ErrorBoundary`, `HydrateFallback`, `Layout`) will be server components rather than the usual client components.
182+
If a route exports a `ServerComponent` instead of the typical `default` component export, this will be a server component rather than the usual client component.
183183

184184
```tsx
185185
import type { Route } from "./+types/route";

integration/typegen-test.ts

Lines changed: 1 addition & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ test.describe("typegen", () => {
658658
});
659659
});
660660

661-
test.describe("server-first route component detection", () => {
661+
test.describe("route server component detection", () => {
662662
test.describe("ServerComponent export", () => {
663663
test("when RSC Framework Mode plugin is present", async ({ edit, $ }) => {
664664
await edit({
@@ -706,38 +706,6 @@ test.describe("typegen", () => {
706706
</>
707707
)
708708
}
709-
710-
export function ErrorBoundary({
711-
loaderData,
712-
actionData
713-
}: Route.ErrorBoundaryProps) {
714-
type TestLoaderData = Expect<Equal<typeof loaderData, { server: string } | undefined>>
715-
type TestActionData = Expect<Equal<typeof actionData, { server: string } | undefined>>
716-
717-
return (
718-
<>
719-
<h1>ErrorBoundary</h1>
720-
<p>Loader data: {loaderData?.server}</p>
721-
<p>Action data: {actionData?.server}</p>
722-
</>
723-
)
724-
}
725-
726-
export function HydrateFallback({
727-
loaderData,
728-
actionData
729-
}: Route.HydrateFallbackProps) {
730-
type TestLoaderData = Expect<Equal<typeof loaderData, { server: string } | undefined>>
731-
type TestActionData = Expect<Equal<typeof actionData, { server: string } | undefined>>
732-
733-
return (
734-
<>
735-
<h1>HydrateFallback</h1>
736-
<p>Loader data: {loaderData?.server}</p>
737-
<p>Action data: {actionData?.server}</p>
738-
</>
739-
)
740-
}
741709
`,
742710
});
743711
await $("pnpm typecheck");
@@ -795,38 +763,6 @@ test.describe("typegen", () => {
795763
</>
796764
)
797765
}
798-
799-
export function ErrorBoundary({
800-
loaderData,
801-
actionData
802-
}: Route.ErrorBoundaryProps) {
803-
type TestLoaderData = Expect<Equal<typeof loaderData, { server: string } | { client: string } | undefined>>
804-
type TestActionData = Expect<Equal<typeof actionData, { server: string } | { client: string } | undefined>>
805-
806-
return (
807-
<>
808-
<h1>ErrorBoundary</h1>
809-
{loaderData && <p>Loader data: {"server" in loaderData ? loaderData.server : loaderData.client}</p>}
810-
{actionData && <p>Action data: {"server" in actionData ? actionData.server : actionData.client}</p>}
811-
</>
812-
)
813-
}
814-
815-
export function HydrateFallback({
816-
loaderData,
817-
actionData
818-
}: Route.HydrateFallbackProps) {
819-
type TestLoaderData = Expect<Equal<typeof loaderData, { server: string } | { client: string } | undefined>>
820-
type TestActionData = Expect<Equal<typeof actionData, { server: string } | { client: string } | undefined>>
821-
822-
return (
823-
<>
824-
<h1>HydrateFallback</h1>
825-
{loaderData && <p>Loader data: {"server" in loaderData ? loaderData.server : loaderData.client}</p>}
826-
{actionData && <p>Action data: {"server" in actionData ? actionData.server : actionData.client}</p>}
827-
</>
828-
)
829-
}
830766
`,
831767
});
832768
await $("pnpm typecheck");
@@ -878,38 +814,6 @@ test.describe("typegen", () => {
878814
</>
879815
)
880816
}
881-
882-
export function ErrorBoundary({
883-
loaderData,
884-
actionData
885-
}: Route.ErrorBoundaryProps) {
886-
type TestLoaderData = Expect<Equal<typeof loaderData, { server: string } | { client: string } | undefined>>
887-
type TestActionData = Expect<Equal<typeof actionData, { server: string } | { client: string } | undefined>>
888-
889-
return (
890-
<>
891-
<h1>ErrorBoundary</h1>
892-
{loaderData && <p>Loader data: {"server" in loaderData ? loaderData.server : loaderData.client}</p>}
893-
{actionData && <p>Action data: {"server" in actionData ? actionData.server : actionData.client}</p>}
894-
</>
895-
)
896-
}
897-
898-
export function HydrateFallback({
899-
loaderData,
900-
actionData
901-
}: Route.HydrateFallbackProps) {
902-
type TestLoaderData = Expect<Equal<typeof loaderData, { server: string } | { client: string } | undefined>>
903-
type TestActionData = Expect<Equal<typeof actionData, { server: string } | { client: string } | undefined>>
904-
905-
return (
906-
<>
907-
<h1>HydrateFallback</h1>
908-
{loaderData && <p>Loader data: {"server" in loaderData ? loaderData.server : loaderData.client}</p>}
909-
{actionData && <p>Action data: {"server" in actionData ? actionData.server : actionData.client}</p>}
910-
</>
911-
)
912-
}
913817
`,
914818
};
915819

0 commit comments

Comments
 (0)