AgentStack
SKILL verified MIT Self-run

Vite Impl Ssr

skill-impertio-studio-vite-claude-skill-package-vite-impl-ssr · by Impertio-Studio

>

No reviews yet
0 installs
12 views
0.0% view→install

Install

$ agentstack add skill-impertio-studio-vite-claude-skill-package-vite-impl-ssr

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access Used
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Vite Impl Ssr? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

vite-impl-ssr

Quick Reference

SSR Architecture Overview

| Component | Purpose | Location | |-----------|---------|----------| | Entry Client | Hydrates server-rendered HTML in browser | src/entry-client.js | | Entry Server | Exports render() function for SSR | src/entry-server.js | | Custom Server | Express/Koa server with Vite middleware | server.js (project root) | | index.html | Template with ` placeholder | Project root | | SSR Manifest | Maps module IDs to chunks/assets for preloading | dist/client/.vite/ssr-manifest.json` |

SSR Dev vs Production

| Aspect | Development | Production | |--------|-------------|------------| | Module loading | vite.ssrLoadModule() | import('./dist/server/entry-server.js') | | HTML template | Read from project root index.html | Read from dist/client/index.html | | HTML transforms | vite.transformIndexHtml() applies plugins | Pre-built, no transforms needed | | Static files | Vite middleware serves files | Express static middleware from dist/client | | Error handling | vite.ssrFixStacktrace(e) maps to source | Standard Node.js stack traces |

Build Commands

{
  "scripts": {
    "dev": "node server",
    "build:client": "vite build --outDir dist/client",
    "build:server": "vite build --outDir dist/server --ssr src/entry-server.js",
    "build": "npm run build:client && npm run build:server"
  }
}

ALWAYS change "dev": "vite" to "dev": "node server" in package.json when implementing SSR -- the custom server replaces the default Vite dev server.

Critical Warnings

NEVER call vite.ssrLoadModule() in production -- it is a development-only API. ALWAYS use import('./dist/server/entry-server.js') for production.

NEVER forget to call vite.ssrFixStacktrace(e) in your catch block during development -- without it, error stack traces point to transformed code instead of original source files.

NEVER read index.html from the project root in production -- ALWAYS read from dist/client/index.html which contains the built asset references.

NEVER omit appType: 'custom' when creating the Vite server in middleware mode -- this prevents Vite from injecting its own HTML handling logic that conflicts with SSR.

NEVER set ssr.noExternal: true for Node.js targets unless you explicitly need a single-file bundle -- it forces bundling of all dependencies, which is unnecessary and slower for Node.js.


SSR Dev Server Setup

Middleware Mode with Express

ALWAYS use middleware mode (server: { middlewareMode: true }) for SSR development. This lets Express handle routing while Vite handles module transformation and HMR.

import fs from 'node:fs'
import path from 'node:path'
import express from 'express'
import { createServer as createViteServer } from 'vite'

async function createServer() {
  const app = express()

  const vite = await createViteServer({
    server: { middlewareMode: true },
    appType: 'custom',
  })

  app.use(vite.middlewares)

  app.use('*all', async (req, res, next) => {
    const url = req.originalUrl
    try {
      let template = fs.readFileSync(
        path.resolve(import.meta.dirname, 'index.html'),
        'utf-8',
      )
      template = await vite.transformIndexHtml(url, template)
      const { render } = await vite.ssrLoadModule('/src/entry-server.js')
      const appHtml = await render(url)
      const html = template.replace(``, () => appHtml)
      res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
    } catch (e) {
      vite.ssrFixStacktrace(e)
      next(e)
    }
  })

  app.listen(5173)
}

createServer()

index.html Template


  
    
    SSR App
  
  
    
    
  

ALWAYS place `` inside the mount element. The server replaces this comment with rendered HTML. The client entry script handles hydration.


Decision Tree: SSR Configuration

When to use ssr.noExternal

Does the dependency use browser-specific code that Vite must transform?
├─ YES → Add to ssr.noExternal: ['dependency-name']
├─ Is it a linked/monorepo package?
│  └─ YES → Linked packages are NOT externalized by default; add to ssr.noExternal if they need Vite transforms
└─ Do you need a single-file SSR bundle (e.g., for webworker)?
   └─ YES → Set ssr.noExternal: true (bundles everything)

When to use ssr.external

Is a linked dependency causing issues when processed by Vite?
├─ YES → Add to ssr.external: ['dependency-name']
└─ NO → Leave default (node_modules are externalized automatically)

SSR Target Selection

Where does the SSR code run?
├─ Node.js server → ssr.target: 'node' (default, NEVER set explicitly)
└─ Cloudflare Workers / Deno Deploy / edge runtime
   └─ ssr.target: 'webworker'
      └─ ALWAYS also set ssr.noExternal: true for webworker targets

SSR Config Options

Externals

// vite.config.ts
import { defineConfig } from 'vite'

export default defineConfig({
  ssr: {
    // Force these through Vite's transform pipeline
    noExternal: ['@my-org/ui-components', 'some-esm-only-lib'],

    // Externalize despite being linked
    external: ['legacy-linked-package'],

    // SSR runtime target
    target: 'node', // default; or 'webworker'
  },
})

Resolve Conditions

export default defineConfig({
  ssr: {
    resolve: {
      // Override resolve.conditions for SSR builds
      conditions: ['node', 'import'],
      // Additional conditions for externalized deps
      externalConditions: ['node', 'import'],
    },
  },
})

SSR Conditional Logic

if (import.meta.env.SSR) {
  // Server-only code -- tree-shaken from client bundle
}

This boolean is statically replaced during build, so dead code elimination removes the unused branch entirely. ALWAYS use this for code that must run only on the server or only on the client.


Plugin SSR Detection

Plugins detect SSR context through the options parameter in hooks:

export function mySSRPlugin() {
  return {
    name: 'my-ssr-plugin',
    transform(code, id, options) {
      if (options?.ssr) {
        // SSR-specific transform
      }
    },
  }
}

ALWAYS use options?.ssr (optional chaining) -- the options parameter may be undefined in some contexts.


SSR Manifest for Preload Directives

Generate the manifest during client build:

vite build --outDir dist/client --ssrManifest

This produces dist/client/.vite/ssr-manifest.json mapping module IDs to their output chunks and assets. Use this in the server to inject ` and ` tags for optimal loading.


Reference Links

  • [references/api-reference.md](references/api-reference.md) -- ssrLoadModule, ssrFixStacktrace, SSR config options with full signatures
  • [references/examples.md](references/examples.md) -- Complete Express SSR dev server, build commands, production server setup
  • [references/anti-patterns.md](references/anti-patterns.md) -- Common SSR mistakes and how to avoid them

Official Sources

  • https://vite.dev/guide/ssr
  • https://vite.dev/config/ssr-options
  • https://vite.dev/guide/api-javascript

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.