PrevelteKit Documentation

(Server Pre-Rendered)

Getting Started

git clone https://github.com/tbocek/preveltekit.git
cd preveltekit
pnpm install
pnpm dev    # Development mode
pnpm build  # Production build

Core Features

📦 Server-Side Pre-Rendering (SSPR)

Unlike traditional SSR or SSG, SSPR pre-renders your app at build time while maintaining full interactivity through hydration. This gives you the best of both worlds: fast initial loads and dynamic functionality.

⚡ Build System

Built on Rsbuild for lightning-fast builds. The system automatically handles:

  • TypeScript compilation and type checking
  • Asset optimization and bundling
  • CSS processing and minification
  • Production optimizations like code splitting

🔄 Development Workflow

Three modes available to suit your needs:

  • Development (pnpm dev): Express server with fast rebuilds and hot module replacement
  • Staging (pnpm stage): Production build with local preview server
  • Production (pnpm build): Optimized build with pre-compression (Brotli, Gzip, Zstandard)

SSPR Development

🔍 Detecting Server Pre-Rendering

PrevelteKit uses window.JSDOM to indicate when code is running during server pre-rendering. This is crucial for handling client-side-only code like API calls and intervals.

// Basic detection
let renderInfo = "Client Rendered";
if (window?.JSDOM) {
    renderInfo = "Server Pre-Rendered";
}

🔄 Handling Client-Side Operations

When working with APIs, timers, or browser-specific features, wrap them in a JSDOM check to prevent execution during pre-rendering:

$effect(() => {
    if (!window?.JSDOM) {
        fetchBitcoinPrice();
        // Set up refresh interval
        const interval = setInterval(fetchBitcoinPrice, 60000);
        return () => clearInterval(interval);
    }
});

Common use cases for JSDOM checks:

  • API calls and data fetching
  • Browser APIs (localStorage, sessionStorage)
  • Timers and intervals
  • DOM manipulation
  • Browser-specific features (geolocation, notifications)

Static Site Configuration

To add static routes to your application, configure them in rsbuild.config.ts. Each route needs an entry in the configuration. For example, to add routes for /doc and /example:

export default defineConfig({
    environments: {
        web: {
            plugins: [
                pluginSvelte(),
                pluginCssMinimizer()
            ],
            source: {
                entry: {
                    // Each entry corresponds to a static route
                    index: './src/index.ts',    // https://example.com/
                    doc: './src/index.ts',      // https://example.com/doc
                    example: './src/index.ts',  // https://example.com/example
                }
            },
            output: {
                target: 'web',
                minify: process.env.NODE_ENV === 'production',
            }
        }
    }
});

Important Notes:

  • Each entry key becomes a URL path in your application
  • Subdirectories are not currently supported
  • All entries point to the same index.ts file
  • The router in your application will handle the actual component rendering

Docker Support

Development environment:

docker build -f Dockerfile.dev . -t preveltekit-dev
docker run -p3000:3000 -v./src:/app/src -v./public:/app/public preveltekit-dev

Production build:

docker build . -t preveltekit
docker run -p3000:3000 preveltekit

Project Structure

  • /src: Application source code
  • /public: Static assets
  • /dist: Production build output
  • rsbuild.config.ts: Build configuration
  • ssr.mjs: SSPR implementation

Deployment

The production build generates static files with pre-compressed variants:

  • Standard files (.js, .css, .html)
  • Brotli compressed (.br)
  • Gzip compressed (.gz)
  • Zstandard compressed (.zst)

Deploy to any static hosting or web server that supports serving compressed assets.