Skip to content

Commit 8b3d354

Browse files
Copilothi-ogawa
andcommitted
Replace accept header with _.rsc postfix in basic, starter, and starter-cf-single examples
Co-authored-by: hi-ogawa <4232207+hi-ogawa@users.noreply.github.com>
1 parent d4282e5 commit 8b3d354

File tree

9 files changed

+83
-72
lines changed

9 files changed

+83
-72
lines changed

packages/plugin-rsc/examples/basic/src/framework/entry.browser.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
import React from 'react'
99
import { hydrateRoot } from 'react-dom/client'
1010
import { rscStream } from 'rsc-html-stream/client'
11-
import type { RscPayload } from './entry.rsc'
11+
import { RSC_POSTFIX, type RscPayload } from './shared'
1212
import { GlobalErrorBoundary } from './error-boundary'
1313

1414
async function main() {
@@ -40,16 +40,17 @@ async function main() {
4040

4141
// re-fetch RSC and trigger re-rendering
4242
async function fetchRscPayload() {
43-
const payload = await createFromFetch<RscPayload>(
44-
fetch(window.location.href),
45-
)
43+
const url = new URL(window.location.href)
44+
url.pathname = url.pathname + RSC_POSTFIX
45+
const payload = await createFromFetch<RscPayload>(fetch(url))
4646
setPayload(payload)
4747
}
4848

4949
// register a handler which will be internally called by React
5050
// on server function request after hydration.
5151
setServerCallback(async (id, args) => {
5252
const url = new URL(window.location.href)
53+
url.pathname = url.pathname + RSC_POSTFIX
5354
const temporaryReferences = createTemporaryReferenceSet()
5455
const payload = await createFromFetch<RscPayload>(
5556
fetch(url, {

packages/plugin-rsc/examples/basic/src/framework/entry.rsc.tsx

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,7 @@ import {
77
decodeFormState,
88
} from '@vitejs/plugin-rsc/rsc'
99
import type { ReactFormState } from 'react-dom/client'
10-
import type React from 'react'
11-
12-
// The schema of payload which is serialized into RSC stream on rsc environment
13-
// and deserialized on ssr/client environments.
14-
export type RscPayload = {
15-
// this demo renders/serializes/deserizlies entire root html element
16-
// but this mechanism can be changed to render/fetch different parts of components
17-
// based on your own route conventions.
18-
root: React.ReactNode
19-
// server action return value of non-progressive enhancement case
20-
returnValue?: { ok: boolean; data: unknown }
21-
// server action form state (e.g. useActionState) of progressive enhancement case
22-
formState?: ReactFormState
23-
}
10+
import { RSC_POSTFIX, type RscPayload } from './shared'
2411

2512
// the plugin by default assumes `rsc` entry having default export of request handler.
2613
// however, how server entries are executed can be customized by registering
@@ -67,19 +54,17 @@ export async function handleRequest({
6754
}
6855
}
6956

70-
const url = new URL(request.url)
57+
let url = new URL(request.url)
58+
let isRscRequest = false
59+
if (url.pathname.endsWith(RSC_POSTFIX)) {
60+
isRscRequest = true
61+
url.pathname = url.pathname.slice(0, -RSC_POSTFIX.length)
62+
}
63+
7164
const rscPayload: RscPayload = { root: getRoot(), formState, returnValue }
7265
const rscOptions = { temporaryReferences }
7366
const rscStream = renderToReadableStream<RscPayload>(rscPayload, rscOptions)
7467

75-
// respond RSC stream without HTML rendering based on framework's convention.
76-
// here we use request header `content-type`.
77-
// additionally we allow `?__rsc` and `?__html` to easily view payload directly.
78-
const isRscRequest =
79-
(!request.headers.get('accept')?.includes('text/html') &&
80-
!url.searchParams.has('__html')) ||
81-
url.searchParams.has('__rsc')
82-
8368
if (isRscRequest) {
8469
return new Response(rscStream, {
8570
status: returnValue?.ok === false ? 500 : undefined,
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type React from 'react'
2+
import type { ReactFormState } from 'react-dom/client'
3+
4+
export const RSC_POSTFIX = '_.rsc'
5+
6+
// The schema of payload which is serialized into RSC stream on rsc environment
7+
// and deserialized on ssr/client environments.
8+
export type RscPayload = {
9+
// this demo renders/serializes/deserizlies entire root html element
10+
// but this mechanism can be changed to render/fetch different parts of components
11+
// based on your own route conventions.
12+
root: React.ReactNode
13+
// server action return value of non-progressive enhancement case
14+
returnValue?: { ok: boolean; data: unknown }
15+
// server action form state (e.g. useActionState) of progressive enhancement case
16+
formState?: ReactFormState
17+
}

packages/plugin-rsc/examples/starter-cf-single/src/framework/entry.browser.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
import React from 'react'
99
import { hydrateRoot } from 'react-dom/client'
1010
import { rscStream } from 'rsc-html-stream/client'
11-
import type { RscPayload } from './entry.rsc'
11+
import { RSC_POSTFIX, type RscPayload } from './shared'
1212

1313
async function main() {
1414
// stash `setPayload` function to trigger re-rendering
@@ -39,16 +39,17 @@ async function main() {
3939

4040
// re-fetch RSC and trigger re-rendering
4141
async function fetchRscPayload() {
42-
const payload = await createFromFetch<RscPayload>(
43-
fetch(window.location.href),
44-
)
42+
const url = new URL(window.location.href)
43+
url.pathname = url.pathname + RSC_POSTFIX
44+
const payload = await createFromFetch<RscPayload>(fetch(url))
4545
setPayload(payload)
4646
}
4747

4848
// register a handler which will be internally called by React
4949
// on server function request after hydration.
5050
setServerCallback(async (id, args) => {
5151
const url = new URL(window.location.href)
52+
url.pathname = url.pathname + RSC_POSTFIX
5253
const temporaryReferences = createTemporaryReferenceSet()
5354
const payload = await createFromFetch<RscPayload>(
5455
fetch(url, {

packages/plugin-rsc/examples/starter-cf-single/src/framework/entry.rsc.tsx

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,7 @@ import {
88
} from '@vitejs/plugin-rsc/rsc'
99
import type { ReactFormState } from 'react-dom/client'
1010
import { Root } from '../root.tsx'
11-
12-
export type RscPayload = {
13-
root: React.ReactNode
14-
returnValue?: { ok: boolean; data: unknown }
15-
formState?: ReactFormState
16-
}
11+
import { RSC_POSTFIX, type RscPayload } from './shared'
1712

1813
async function handler(request: Request): Promise<Response> {
1914
// handle server function request
@@ -53,19 +48,17 @@ async function handler(request: Request): Promise<Response> {
5348
// we render RSC stream after handling server function request
5449
// so that new render reflects updated state from server function call
5550
// to achieve single round trip to mutate and fetch from server.
51+
let url = new URL(request.url)
52+
let isRscRequest = false
53+
if (url.pathname.endsWith(RSC_POSTFIX)) {
54+
isRscRequest = true
55+
url.pathname = url.pathname.slice(0, -RSC_POSTFIX.length)
56+
}
57+
5658
const rscPayload: RscPayload = { root: <Root />, formState, returnValue }
5759
const rscOptions = { temporaryReferences }
5860
const rscStream = renderToReadableStream<RscPayload>(rscPayload, rscOptions)
5961

60-
// respond RSC stream without HTML rendering based on framework's convention.
61-
// here we use request header `content-type`.
62-
// additionally we allow `?__rsc` and `?__html` to easily view payload directly.
63-
const url = new URL(request.url)
64-
const isRscRequest =
65-
(!request.headers.get('accept')?.includes('text/html') &&
66-
!url.searchParams.has('__html')) ||
67-
url.searchParams.has('__rsc')
68-
6962
if (isRscRequest) {
7063
return new Response(rscStream, {
7164
status: returnValue?.ok === false ? 500 : undefined,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import type React from 'react'
2+
import type { ReactFormState } from 'react-dom/client'
3+
4+
export const RSC_POSTFIX = '_.rsc'
5+
6+
export type RscPayload = {
7+
root: React.ReactNode
8+
returnValue?: { ok: boolean; data: unknown }
9+
formState?: ReactFormState
10+
}

packages/plugin-rsc/examples/starter/src/framework/entry.browser.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
import React from 'react'
99
import { hydrateRoot } from 'react-dom/client'
1010
import { rscStream } from 'rsc-html-stream/client'
11-
import type { RscPayload } from './entry.rsc'
11+
import { RSC_POSTFIX, type RscPayload } from './shared'
1212
import { GlobalErrorBoundary } from './error-boundary'
1313

1414
async function main() {
@@ -40,16 +40,17 @@ async function main() {
4040

4141
// re-fetch RSC and trigger re-rendering
4242
async function fetchRscPayload() {
43-
const payload = await createFromFetch<RscPayload>(
44-
fetch(window.location.href),
45-
)
43+
const url = new URL(window.location.href)
44+
url.pathname = url.pathname + RSC_POSTFIX
45+
const payload = await createFromFetch<RscPayload>(fetch(url))
4646
setPayload(payload)
4747
}
4848

4949
// register a handler which will be internally called by React
5050
// on server function request after hydration.
5151
setServerCallback(async (id, args) => {
5252
const url = new URL(window.location.href)
53+
url.pathname = url.pathname + RSC_POSTFIX
5354
const temporaryReferences = createTemporaryReferenceSet()
5455
const payload = await createFromFetch<RscPayload>(
5556
fetch(url, {

packages/plugin-rsc/examples/starter/src/framework/entry.rsc.tsx

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,7 @@ import {
88
} from '@vitejs/plugin-rsc/rsc'
99
import type { ReactFormState } from 'react-dom/client'
1010
import { Root } from '../root.tsx'
11-
12-
// The schema of payload which is serialized into RSC stream on rsc environment
13-
// and deserialized on ssr/client environments.
14-
export type RscPayload = {
15-
// this demo renders/serializes/deserizlies entire root html element
16-
// but this mechanism can be changed to render/fetch different parts of components
17-
// based on your own route conventions.
18-
root: React.ReactNode
19-
// server action return value of non-progressive enhancement case
20-
returnValue?: { ok: boolean; data: unknown }
21-
// server action form state (e.g. useActionState) of progressive enhancement case
22-
formState?: ReactFormState
23-
}
11+
import { RSC_POSTFIX, type RscPayload } from './shared'
2412

2513
// the plugin by default assumes `rsc` entry having default export of request handler.
2614
// however, how server entries are executed can be customized by registering
@@ -63,7 +51,13 @@ export default async function handler(request: Request): Promise<Response> {
6351
// we render RSC stream after handling server function request
6452
// so that new render reflects updated state from server function call
6553
// to achieve single round trip to mutate and fetch from server.
66-
const url = new URL(request.url)
54+
let url = new URL(request.url)
55+
let isRscRequest = false
56+
if (url.pathname.endsWith(RSC_POSTFIX)) {
57+
isRscRequest = true
58+
url.pathname = url.pathname.slice(0, -RSC_POSTFIX.length)
59+
}
60+
6761
const rscPayload: RscPayload = {
6862
root: <Root url={url} />,
6963
formState,
@@ -72,14 +66,6 @@ export default async function handler(request: Request): Promise<Response> {
7266
const rscOptions = { temporaryReferences }
7367
const rscStream = renderToReadableStream<RscPayload>(rscPayload, rscOptions)
7468

75-
// respond RSC stream without HTML rendering based on framework's convention.
76-
// here we use request header `content-type`.
77-
// additionally we allow `?__rsc` and `?__html` to easily view payload directly.
78-
const isRscRequest =
79-
(!request.headers.get('accept')?.includes('text/html') &&
80-
!url.searchParams.has('__html')) ||
81-
url.searchParams.has('__rsc')
82-
8369
if (isRscRequest) {
8470
return new Response(rscStream, {
8571
status: returnValue?.ok === false ? 500 : undefined,
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type React from 'react'
2+
import type { ReactFormState } from 'react-dom/client'
3+
4+
export const RSC_POSTFIX = '_.rsc'
5+
6+
// The schema of payload which is serialized into RSC stream on rsc environment
7+
// and deserialized on ssr/client environments.
8+
export type RscPayload = {
9+
// this demo renders/serializes/deserizlies entire root html element
10+
// but this mechanism can be changed to render/fetch different parts of components
11+
// based on your own route conventions.
12+
root: React.ReactNode
13+
// server action return value of non-progressive enhancement case
14+
returnValue?: { ok: boolean; data: unknown }
15+
// server action form state (e.g. useActionState) of progressive enhancement case
16+
formState?: ReactFormState
17+
}

0 commit comments

Comments
 (0)