or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdisomorphic-functions.mdmiddleware.mdrequest-response.mdrpc-system.mdserver-functions.mdserver-utilities.mdssr-components.mdvite-plugin.md

ssr-components.mddocs/

0

# SSR Components

1

2

SSR (Server-Side Rendering) components provide the foundation for rendering React applications on both server and client sides. These components handle hydration, streaming, and the coordination between server and client rendering processes.

3

4

## Capabilities

5

6

### StartClient Component

7

8

The main client-side React component that handles hydration and router initialization for client-side rendering.

9

10

```typescript { .api }

11

/**

12

* Client-side root component for hydrating the application

13

* Automatically handles router hydration and initial render

14

* @returns JSX.Element - The hydrated client application

15

*/

16

function StartClient(): JSX.Element;

17

```

18

19

**Usage Examples:**

20

21

```typescript

22

import { StrictMode, startTransition } from "react";

23

import { hydrateRoot } from "react-dom/client";

24

import { StartClient } from "@tanstack/react-start/client";

25

26

// Basic client hydration

27

startTransition(() => {

28

hydrateRoot(

29

document,

30

<StrictMode>

31

<StartClient />

32

</StrictMode>

33

);

34

});

35

36

// Custom root element hydration

37

const rootElement = document.getElementById("app");

38

if (rootElement) {

39

hydrateRoot(rootElement, <StartClient />);

40

}

41

```

42

43

### StartServer Component

44

45

The main server-side React component that provides the router for server-side rendering.

46

47

```typescript { .api }

48

/**

49

* Server-side root component for SSR

50

* @param props - Configuration object with router instance

51

* @returns JSX.Element - The server-rendered application

52

*/

53

function StartServer<TRouter extends AnyRouter>(props: {

54

router: TRouter;

55

}): JSX.Element;

56

57

interface AnyRouter {

58

// Router instance from TanStack Router

59

state: RouterState;

60

options: RouterOptions;

61

history: RouterHistory;

62

}

63

```

64

65

**Usage Examples:**

66

67

```typescript

68

import { StartServer } from "@tanstack/react-start/server";

69

import { createRouter } from "@tanstack/react-router";

70

71

// Create router instance

72

const router = createRouter({

73

routeTree: rootRoute,

74

context: {

75

// Server context

76

}

77

});

78

79

// Server-side rendering

80

function renderApp() {

81

return <StartServer router={router} />;

82

}

83

84

// In server handler

85

export default {

86

fetch: async (request) => {

87

const html = ReactDOMServer.renderToString(<StartServer router={router} />);

88

return new Response(html, {

89

headers: { "content-type": "text/html" }

90

});

91

}

92

};

93

```

94

95

### Create Start Handler

96

97

Creates a request handler for the server that processes incoming requests and renders the application.

98

99

```typescript { .api }

100

/**

101

* Creates the main request handler for server-side processing

102

* @param streamHandler - Optional custom streaming handler

103

* @returns RequestHandler for processing HTTP requests

104

*/

105

function createStartHandler(

106

streamHandler?: StreamHandler

107

): RequestHandler<Register>;

108

109

interface RequestHandler<TRegister> {

110

(request: Request): Promise<Response>;

111

router?: AnyRouter;

112

}

113

114

interface StreamHandler {

115

(renderOptions: RenderOptions): ReadableStream | Promise<ReadableStream>;

116

}

117

118

interface RenderOptions {

119

router: AnyRouter;

120

request: Request;

121

responseHeaders: Headers;

122

}

123

```

124

125

**Usage Examples:**

126

127

```typescript

128

import {

129

createStartHandler,

130

defaultStreamHandler

131

} from "@tanstack/react-start/server";

132

133

// Basic server handler

134

const handler = createStartHandler();

135

136

export default {

137

fetch: handler

138

};

139

140

// Custom streaming handler

141

const customHandler = createStartHandler((options) => {

142

// Custom streaming logic

143

return new ReadableStream({

144

start(controller) {

145

// Custom rendering logic

146

const html = renderToString(<StartServer router={options.router} />);

147

controller.enqueue(new TextEncoder().encode(html));

148

controller.close();

149

}

150

});

151

});

152

153

// Advanced server setup

154

const handler = createStartHandler(defaultStreamHandler);

155

156

export default {

157

fetch: async (request, env) => {

158

// Add custom headers or processing

159

const response = await handler(request);

160

response.headers.set("X-Powered-By", "TanStack Start");

161

return response;

162

}

163

};

164

```

165

166

### Default Stream Handler

167

168

Provides the default streaming implementation for server-side rendering with proper error handling and response streaming.

169

170

```typescript { .api }

171

/**

172

* Default streaming handler for SSR with error handling

173

* @returns StreamHandler that processes render options and returns a stream

174

*/

175

function defaultStreamHandler(): StreamHandler;

176

```

177

178

**Usage Examples:**

179

180

```typescript

181

import {

182

createStartHandler,

183

defaultStreamHandler

184

} from "@tanstack/react-start/server";

185

186

// Use default streaming

187

const handler = createStartHandler(defaultStreamHandler());

188

189

// Extend default streaming

190

const extendedHandler = createStartHandler(

191

async (options) => {

192

console.log(`Rendering ${options.request.url}`);

193

return await defaultStreamHandler()(options);

194

}

195

);

196

```

197

198

### Default Render Handler

199

200

Provides the default rendering implementation for server-side rendering without streaming.

201

202

```typescript { .api }

203

/**

204

* Default render handler for non-streaming SSR

205

* @returns RenderHandler that processes render options and returns HTML

206

*/

207

function defaultRenderHandler(): RenderHandler;

208

209

interface RenderHandler {

210

(renderOptions: RenderOptions): string | Promise<string>;

211

}

212

```

213

214

**Usage Examples:**

215

216

```typescript

217

import { defaultRenderHandler } from "@tanstack/react-start/server";

218

219

// Custom non-streaming handler

220

const renderHandler = defaultRenderHandler();

221

222

async function customRenderToString(options) {

223

const html = await renderHandler(options);

224

return `<!DOCTYPE html><html><body>${html}</body></html>`;

225

}

226

```

227

228

### Server Utilities

229

230

Additional server-side utilities for advanced SSR scenarios.

231

232

```typescript { .api }

233

/**

234

* Attach server-side SSR utilities to a router instance

235

* @param router - The router to enhance with SSR capabilities

236

* @returns Enhanced router with SSR utilities

237

*/

238

function attachRouterServerSsrUtils<T extends AnyRouter>(

239

router: T

240

): T & ServerSsrUtils;

241

242

/**

243

* Create a generic request handler with custom configuration

244

* @param options - Handler configuration options

245

* @returns Configured request handler

246

*/

247

function createRequestHandler<T>(

248

options: RequestHandlerOptions<T>

249

): RequestHandler<T>;

250

251

/**

252

* Define a handler callback for custom server processing

253

* @param callback - The handler callback function

254

* @returns Configured handler callback

255

*/

256

function defineHandlerCallback<T>(

257

callback: HandlerCallback<T>

258

): HandlerCallback<T>;

259

260

/**

261

* Transform a ReadableStream with router context

262

* @param stream - The stream to transform

263

* @param router - Router instance for context

264

* @returns Transformed stream with router utilities

265

*/

266

function transformReadableStreamWithRouter(

267

stream: ReadableStream,

268

router: AnyRouter

269

): ReadableStream;

270

271

/**

272

* Transform a pipeable stream with router context

273

* @param stream - The pipeable stream to transform

274

* @param router - Router instance for context

275

* @returns Transformed pipeable stream

276

*/

277

function transformPipeableStreamWithRouter(

278

stream: any, // React's PipeableStream type

279

router: AnyRouter

280

): any;

281

```

282

283

### Client Hydration

284

285

Functions for handling client-side hydration and startup processes.

286

287

```typescript { .api }

288

/**

289

* Perform client-side hydration of the application

290

* @returns Promise resolving to the hydrated router instance

291

*/

292

function hydrateStart(): Promise<AnyRouter>;

293

294

/**

295

* Render React Server Components on the client

296

* @param components - RSC components to render

297

* @returns Rendered RSC content

298

*/

299

function renderRsc(components: any): any;

300

```

301

302

## Advanced Usage Patterns

303

304

### Custom Server Handler with Middleware

305

306

```typescript

307

import {

308

createStartHandler,

309

defaultStreamHandler

310

} from "@tanstack/react-start/server";

311

312

const handler = createStartHandler(defaultStreamHandler());

313

314

export default {

315

fetch: async (request) => {

316

// Add CORS headers

317

if (request.method === "OPTIONS") {

318

return new Response(null, {

319

status: 204,

320

headers: {

321

"Access-Control-Allow-Origin": "*",

322

"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE",

323

"Access-Control-Allow-Headers": "Content-Type, Authorization"

324

}

325

});

326

}

327

328

const response = await handler(request);

329

330

// Add security headers

331

response.headers.set("X-Frame-Options", "DENY");

332

response.headers.set("X-Content-Type-Options", "nosniff");

333

334

return response;

335

}

336

};

337

```

338

339

### Custom Streaming Implementation

340

341

```typescript

342

import { createStartHandler } from "@tanstack/react-start/server";

343

import { renderToPipeableStream } from "react-dom/server";

344

345

const customStreamHandler = (options) => {

346

return new ReadableStream({

347

start(controller) {

348

const stream = renderToPipeableStream(

349

<StartServer router={options.router} />,

350

{

351

onShellReady() {

352

controller.enqueue(new TextEncoder().encode("<!DOCTYPE html>"));

353

stream.pipe(new WritableStream({

354

write(chunk) {

355

controller.enqueue(chunk);

356

},

357

close() {

358

controller.close();

359

}

360

}));

361

},

362

onError(error) {

363

console.error("Stream error:", error);

364

controller.error(error);

365

}

366

}

367

);

368

}

369

});

370

};

371

372

const handler = createStartHandler(customStreamHandler);

373

```

374

375

## Types

376

377

```typescript { .api }

378

// Router types from TanStack Router

379

interface AnyRouter {

380

state: RouterState;

381

options: RouterOptions;

382

history: RouterHistory;

383

navigate: (options: any) => Promise<void>;

384

resolveRedirect: (redirect: any) => any;

385

}

386

387

// Request handler types

388

interface RequestHandler<TRegister> {

389

(request: Request): Promise<Response>;

390

router?: AnyRouter;

391

}

392

393

interface RequestOptions {

394

request: Request;

395

responseHeaders?: Headers;

396

context?: any;

397

}

398

399

// Streaming types

400

interface StreamHandler {

401

(renderOptions: RenderOptions): ReadableStream | Promise<ReadableStream>;

402

}

403

404

interface RenderHandler {

405

(renderOptions: RenderOptions): string | Promise<string>;

406

}

407

408

interface RenderOptions {

409

router: AnyRouter;

410

request: Request;

411

responseHeaders: Headers;

412

context?: any;

413

}

414

415

// Server utilities types

416

interface ServerSsrUtils {

417

dehydrate: () => DehydratedRouter;

418

serialize: (data: any) => string;

419

deserialize: (data: string) => any;

420

}

421

422

interface HandlerCallback<T> {

423

(context: T): Response | Promise<Response>;

424

}

425

426

interface RequestHandlerOptions<T> {

427

createRouter: () => AnyRouter;

428

getRouterContext?: (request: Request) => T;

429

onError?: (error: Error) => Response;

430

}

431

432

// Dehydrated state for SSR

433

interface DehydratedRouter {

434

state: Record<string, any>;

435

manifest: Record<string, any>;

436

context?: any;

437

}

438

```

439

440

## Constants

441

442

```typescript { .api }

443

// HTTP headers used by the SSR system

444

const HEADERS: {

445

readonly contentType: "Content-Type";

446

readonly location: "Location";

447

readonly cacheControl: "Cache-Control";

448

};

449

```