FFUNSTACK Static
DocsAPILearn

Getting Started

IntroductionMigrating from Vite SPA

Learn

React Server ComponentsHow It WorksOptimizing RSC PayloadsUsing lazy() in ServerPrefetching with ActivityFile-System Routing

Advanced

Multiple Entrypoints (SSG)Server-Side Rendering

API Reference

funstackStatic()defer()EntryDefinition

Help

FAQ

Server-Side Rendering

In FUNSTACK Static, Server-Side Rendering (SSR) means a build-time process that pre-renders your React components (including client components) to HTML. This can make the initial paint faster.

FUNSTACK Static supports a ssr option to enable SSR. This page explains when to enable this option and what to consider.

What is SSR?

By default, FUNSTACK Static renders only the Root shell to HTML. The App component is delivered as an RSC payload and rendered client-side. When you enable ssr: true, the App component is also rendered to HTML at build time:

funstackStatic({
  root: "./src/root.tsx",
  app: "./src/App.tsx",
  ssr: true,
});

Pros

Faster Paint on Initial Page Load

With SSR enabled, the full page content is visible in the HTML before JavaScript loads. Users see meaningful content immediately, rather than waiting for JavaScript to download, parse, and execute.

This improves perceived performance, especially on:

  • Slower network connections
  • Lower-powered devices
  • Pages with significant content above the fold

The browser can start painting content as soon as the HTML arrives, while JavaScript loads in the background. Once loaded, React hydrates the existing HTML to make it interactive.

Cons

Client Components Must Be SSR-Capable

When SSR is enabled, your client components run during the build process to generate HTML. This means they must work in a server-like environment where browser APIs are not available.

Components that directly access browser-only APIs will cause build errors:

"use client";

// This will fail during SSR build
export function BrowserOnlyComponent() {
  const width = window.innerWidth; // window is not defined during SSR
  return <div>Width: {width}</div>;
}

To make components SSR-capable, use useSyncExternalStore with a server snapshot:

"use client";

import { useSyncExternalStore } from "react";

function subscribeToWidth(callback: () => void) {
  window.addEventListener("resize", callback);
  return () => window.removeEventListener("resize", callback);
}

function getWidth() {
  return window.innerWidth;
}

function getServerWidth() {
  return 0; // Fallback value during SSR
}

export function SSRSafeComponent() {
  const width = useSyncExternalStore(
    subscribeToWidth,
    getWidth,
    getServerWidth,
  );
  return <div>Width: {width}</div>;
}

Common browser APIs to watch for:

  • window and document
  • localStorage and sessionStorage
  • location (use your router's APIs instead)

When to Use SSR

Enable SSR when:

  • You want the fastest possible initial paint
  • Your client components are already SSR-compatible
  • You're building content-heavy pages with multiple entrypoints

Keep SSR disabled when:

  • Your app relies heavily on browser-only APIs
  • You prefer simpler client component development
  • Initial paint speed is not a priority

See Also

  • How It Works - Understanding the build process
  • funstackStatic() - Configuration reference