React Server Components for Pages Routing
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 35/100
- issue の種類
- 機能追加
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- react, typescript, vite
調査の方向性
Read the Pages protocol in the React adapter and the page scanning logic in packages/void/src/pages/scan.ts, then examine how Void configures the RSC environment in packages/void/src/index.ts and the vinext-app playground's @vitejs/plugin-rsc setup. Map how loader data is transported, prefetched, cached, and prerendered before proposing an implementation. Done means an opt-in Pages flow can return React elements from loaders while preserving client routing and existing plain data behavior.
索引モデルが issue の本文から書いたものです。
説明
Parts of the text were generated using an LLM, but the core purpose and intent of the proposal were written by a human.
Summary
I'd like to propose opt-in React Server Components (RSC) support for Pages mode in the React adapter, built on @vitejs/plugin-rsc. Rather than an RSC-first architecture like the Next.js App Router, a page's loader would be able to return server-rendered elements, and the page component would receive them as props — a small extension of Void's existing loader → props model.
Motivation
Void is excellent, and it looks like it could become my first choice for full-stack React apps. When comparing it with the other React meta-frameworks, the most visible gap is RSC:
| Framework | RSC support |
|---|---|
| Next.js (App Router) | Stable, RSC-first |
| React Router (Framework Mode) | Experimental (unstable_reactRouterRSC + @vitejs/plugin-rsc) |
| TanStack Start | Experimental, opt-in (rsc: { enabled: true } + @vitejs/plugin-rsc) |
| Void (Pages mode) | Not supported |
I understand RSC isn't central to Void's design, and I'm not suggesting that change. But an unchecked box in these comparisons makes Void look less capable than it is, even for teams that would only use RSC in a few places.
Existing options don't fully cover this:
- Islands already avoid client JS for static parts, but island pages use full-page navigation without the Void Router. RSC would bring the same benefit (server-only rendering, heavy dependencies that never reach the browser) to regular pages, with client navigation, actions and deferred props intact.
- The TanStack Start / React Router integrations could provide RSC, but their RSC modes aren't covered in the integration docs, and switching gives up Pages-only features such as Void-managed auth (not yet supported in framework mode) and per-page
revalidate/prerenderexports.
Proposal
// pages/posts/[slug].server.tsx
import { defineHandler } from 'void';
import type { InferProps } from 'void';
import { getPost, type Post } from '../../lib/posts';
import { renderMarkdown } from '../../lib/markdown'; // markdown/highlighter code stays on the server
import { LikeButton } from './_LikeButton'; // a 'use client' component
async function PostContent({ post }: { post: Post }) {
const html = await renderMarkdown(post.body);
return (
<article>
<div dangerouslySetInnerHTML={{ __html: html }} />
<LikeButton postId={post.id} />
</article>
);
}
export type Props = InferProps<typeof loader>;
export const loader = defineHandler(async (c) => {
const post = await getPost(c.req.param('slug'));
return {
title: post.title, // plain data, as today
content: <PostContent post={post} />, // rendered as a Server Component
};
});
// pages/posts/[slug].tsx — a regular page component, unchanged
import type { Props } from './[slug].server';
export default function PostPage({ title, content }: Props) {
return (
<main>
<h1>{title}</h1>
{content}
</main>
);
}
How it could work:
- Opt-in through the React adapter, e.g.
voidReact({ rsc: true }). Since.server.tsxis already accepted as a companion extension, the file extension alone shouldn't change behavior. - When enabled, companion server modules run in the RSC environment from
@vitejs/plugin-rsc, and loader results are encoded with React's Flight protocol, so props can contain React elements. Plain data keeps working as before, anddefer()could map onto Flight's native promise streaming. - Page components and layouts stay client components, so routing, navigation, forms and hydration work as they do today. As usual with RSC, components imported into a server module render on the server unless marked
'use client'. - Out of scope for a first version:
'use server'Server Functions (Void actions already cover mutations) and the Vue / Svelte / Solid adapters.
Prior art
- React Router RSC Framework Mode lets loaders and actions return React elements that render only on the server and reach the route component through
loaderData— the closest match to this proposal. - TanStack Start creates server components in server functions (
renderServerComponent,createCompositeComponent), returns them from loaders, and reads them withRoute.useLoaderData(). - Void itself already configures the Worker environment as
rscwithssras a child for vinext App Router projects, and thevinext-appplayground depends on@vitejs/plugin-rsc. So this wouldn't start from zero on the build and deploy side; most of the work would be in the Pages protocol and the React adapter.
Open questions
- Opt-in granularity: app-wide adapter option, per-page export, or automatic when a loader returns React elements.
- Transport: page data is JSON today (NDJSON for deferred props); RSC props need a Flight stream, at least for the React adapter.
- Caching: how prefetch, ISR and prerendered pages store Flight payloads.
- Islands: whether island pages should also accept server-component props.
- Types:
InferPropsshould expose server-rendered values asReactNode.
I'd be happy to help test a prototype if this direction sounds reasonable.
- 主要言語
- TypeScript
- スター
- 402
- フォーク
- 32
- 平均マージ
- 11時間 52分
- マージ済み PR(30日)
- 88
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
voidzero-dev/void のほかの issue
-
bug
難易度 1/5 1〜3時間 初心者へのやさしさ 78/100
voidzero-dev/void#428 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
voidzero-dev/void#511 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
voidzero-dev/void#510 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 58/100
voidzero-dev/void#509 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 55/100
voidzero-dev/void#507 ·
メンテナーはふだん 1 日以内に返信
voidzero-dev/void の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
diegosouzapw/OmniRoute#17386 ·
メンテナーはふだん 1 日以内に返信
-
ready-for-agent
難易度 2/5 1〜3時間 初心者へのやさしさ 77/100
メンテナーはふだん 1 日以内に返信
-
area/dashboard kind/bug kind/bug-qa QA/dev-automation
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
メンテナーはふだん 2 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
vybestack/llxprt-code#3917 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
api-parity
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
IBM/carbon-components-ember#1157 ·
メンテナーはふだん 1 日以内に返信