
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
vite-ssr-components
Advanced tools
**_vite-ssr-components_** provides JSX components and Vite plugins for helping the development and deployment for SSR application with Vite.
vite-ssr-components provides JSX components and Vite plugins for helping the development and deployment for SSR application with Vite.
When using Cloudflare's Vite plugin for SSR applications, several challenges arise:
/@vite/client) needs to be manually embedded in server-side rendered HTMLmanifest.json handlingvite.config.ts for each Script/Link componentThis library solves these issues by providing:
manifest.jsonnpm i -D vite-ssr-components
// vite.config.ts
import { defineConfig } from 'vite'
import { cloudflare } from '@cloudflare/vite-plugin'
import ssrPlugin from 'vite-ssr-components/plugin'
export default defineConfig({
plugins: [cloudflare(), ssrPlugin()],
})
import { Script, Link, ViteClient } from 'vite-ssr-components/hono'
// import { Script, Link, ViteClient } from 'vite-ssr-components/react'
function App() {
return (
<html>
<head>
<ViteClient />
<Script src='/src/client.tsx' />
<Link href='/src/style.css' rel='stylesheet' />
</head>
<body>
<div id='root' />
</body>
</html>
)
}
That's it! The plugin automatically:
[!IMPORTANT] If you define custom components with the same names as the default
LinkandScriptcomponents, unexpected behavior may occur. In such cases, use different names for your custom components or specify custom component names in the plugin'scomponentsconfiguration.
Adds Vite client script for development mode.
import { ViteClient } from 'vite-ssr-components/hono'
// import { ViteClient } from 'vite-ssr-components/react'
function App() {
return (
<html>
<head>
<ViteClient />
</head>
</html>
)
}
// Renders: <script type="module" src="/@vite/client"></script>
Adds script tags with proper Vite handling. In production mode, automatically reads manifest.json to resolve the correct built file paths.
import { Script } from 'vite-ssr-components/hono'
// import { Script } from 'vite-ssr-components/react'
function App() {
return (
<html>
<head>
<Script src='/src/client.tsx' />
</head>
</html>
)
}
// Development: <script type="module" src="/src/client.tsx"></script>
// Production: <script type="module" src="/assets/client-abc123.js"></script>
src (required): Source path of the script filemanifest: Custom Vite manifest object (auto-loaded if not provided)prod: Force production mode (defaults to import.meta.env.PROD)baseUrl: Base URL for assets (defaults to /)<Script src='/src/client.tsx' baseUrl='/app/' defer onLoad={() => console.log('loaded')} />
Adds link tags for stylesheets and other resources. In production mode, automatically reads manifest.json to resolve the correct built file paths.
import { Link } from 'vite-ssr-components/hono'
// import { Link } from 'vite-ssr-components/react'
function App() {
return (
<html>
<head>
<Link href='/src/style.css' rel='stylesheet' />
</head>
</html>
)
}
// Development: <link href="/src/style.css" rel="stylesheet">
// Production: <link href="/assets/style-def456.css" rel="stylesheet">
href (required): Source path of the resourcemanifest: Custom Vite manifest object (auto-loaded if not provided)prod: Force production mode (defaults to import.meta.env.PROD)baseUrl: Base URL for assets (defaults to /)<Link href='/src/style.css' rel='stylesheet' baseUrl='/app/' media='screen' />
Enables React Fast Refresh in development. Requires @vitejs/plugin-react to be installed and configured.
import { ReactRefresh } from 'vite-ssr-components/react'
function App() {
return (
<html>
<head>
<ReactRefresh />
</head>
</html>
)
}
// Adds React refresh runtime in development mode
The main plugin that combines auto-entry detection and SSR hot reload functionality.
// vite.config.ts
import { defineConfig } from 'vite'
import ssrPlugin from 'vite-ssr-components/plugin'
export default defineConfig({
plugins: [ssrPlugin()],
})
interface Component {
name: string // Component name to detect
attribute: string // Attribute name to extract file path from
}
interface SSRPluginOptions {
entry?: {
target?: string | string[] // File patterns to scan (default: 'src/**/*.{tsx,ts}')
components?: Component[] // Component configurations (default: [{ name: 'Script', attribute: 'src' }, { name: 'Link', attribute: 'href' }])
}
hotReload?:
| boolean
| {
target?: string | string[] // File patterns to watch (default: ['src/**/*.ts', 'src/**/*.tsx'])
ignore?: string | string[] // File patterns to ignore
}
}
// Basic usage
export default defineConfig({
plugins: [ssrPlugin()],
})
// Custom file patterns and component configurations
export default defineConfig({
plugins: [
ssrPlugin({
entry: {
target: ['src/**/*.tsx', 'app/**/*.ts'], // Scan multiple patterns
components: [
{ name: 'Script', attribute: 'src' },
{ name: 'Link', attribute: 'href' },
{ name: 'CustomScript', attribute: 'source' },
{ name: 'CustomLink', attribute: 'url' },
{ name: 'Foo', attribute: 'bar' },
{ name: 'DataLoader', attribute: 'dataPath' },
{ name: 'AssetLoader', attribute: 'assetUrl' },
],
},
hotReload: {
target: ['src/**/*.ts', 'src/**/*.tsx'],
ignore: ['src/client/**/*'],
},
}),
],
})
// Scan only specific directories
export default defineConfig({
plugins: [
ssrPlugin({
entry: {
target: 'app/**/*.tsx', // Only scan app directory
},
}),
],
})
// Disable hot reload
export default defineConfig({
plugins: [
ssrPlugin({
hotReload: false,
}),
],
})
The plugin automatically scans your source files to detect Script/Link components and extracts file paths from their attributes. This eliminates the need to manually configure build entries.
How it works:
src/**/*.{tsx,ts})Example:
// src/pages/home.tsx
function HomePage() {
return (
<html>
<head>
<Script src='/src/client.tsx' />
<Link href='/src/style.css' rel='stylesheet' />
</head>
</html>
)
}
// src/pages/about.tsx
function AboutPage() {
return (
<html>
<head>
<Script src='/src/about-client.tsx' />
<Link href='/src/about.css' rel='stylesheet' />
</head>
</html>
)
}
The plugin will automatically detect and add these files to the build:
/src/client.tsx/src/style.css/src/about-client.tsx/src/about.cssThe plugin can detect any custom components with any attribute names:
// Custom components in your SSR code
function App() {
return (
<html>
<head>
<CustomScript source='/src/app.js' />
<CustomLink url='/src/main.css' />
<Foo bar='/src/data.json' />
<DataLoader dataPath='/src/config.json' />
<AssetLoader assetUrl='/src/assets/image.png' />
</head>
</html>
)
}
The plugin will automatically:
CustomScript components and extract paths from the source attributeCustomLink components and extract paths from the url attributeFoo components and extract paths from the bar attributeEach component type only looks for its specified attribute, ensuring accurate detection:
// Only the correct attributes are detected for each component
<Script href="/src/wrong.css" src="/src/client.tsx" /> // Only 'src' is detected
<Link src="/src/wrong.js" href="/src/style.css" /> // Only 'href' is detected
The plugin supports flexible file pattern matching using glob patterns:
// Single pattern
pattern: 'src/**/*.tsx'
// Multiple patterns
pattern: ['src/**/*.tsx', 'app/**/*.ts', 'components/**/*.jsx']
// Exclude specific directories
pattern: ['src/**/*.{tsx,ts}', '!src/test/**/*']
Pattern Examples:
src/**/*.tsx - All .tsx files in src directory and subdirectoriesapp/**/*.{ts,tsx} - All .ts and .tsx files in app directory**/*.jsx - All .jsx files in the entire project!node_modules/**/* - Exclude node_modules directorySee the examples directory for complete working examples.
examples/hono/
├── src/
│ ├── index.tsx # Server entry point
│ ├── client.tsx # Client entry point
│ └── style.css # Stylesheet
├── vite.config.ts # Vite configuration
└── package.json
import { defineConfig } from 'vite'
import { cloudflare } from '@cloudflare/vite-plugin'
import ssrPlugin from 'vite-ssr-components/plugin'
export default defineConfig({
plugins: [cloudflare(), ssrPlugin()],
})
import { Hono } from 'hono'
import { Script, Link, ViteClient } from 'vite-ssr-components/hono'
const app = new Hono()
app.get('/', (c) => {
return c.html(
<html>
<head>
<ViteClient />
<Script src='/src/client.tsx' />
<Link href='/src/style.css' rel='stylesheet' />
</head>
<body>
<div id='root' />
</body>
</html>
)
})
examples/react/
├── src/
│ ├── index.tsx # Server entry point
│ ├── style.css # Stylesheet
│ └── client/
│ ├── index.tsx # Client entry point
│ └── app.tsx # React app component
├── vite.config.ts # Vite configuration
└── package.json
import { defineConfig } from 'vite'
import { cloudflare } from '@cloudflare/vite-plugin'
import react from '@vitejs/plugin-react'
import ssrPlugin from 'vite-ssr-components/plugin'
export default defineConfig({
plugins: [
cloudflare(),
ssrPlugin({
hotReload: {
ignore: ['./src/client/**/*.tsx'],
},
}),
react(),
],
})
import { Hono } from 'hono'
import { Script, Link, ViteClient, ReactRefresh } from 'vite-ssr-components/react'
import { renderToReadableStream } from 'react-dom/server'
const app = new Hono()
app.get('/', async (c) => {
c.header('Content-Type', 'text/html')
return c.body(
await renderToReadableStream(
<html>
<head>
<ViteClient />
<ReactRefresh />
<Script src='/src/client/index.tsx' />
<Link href='/src/style.css' rel='stylesheet' />
</head>
<body>
<div id='root' />
</body>
</html>
)
)
})
Yusuke Wada https://github.com/yusukebe
MIT
FAQs
**_vite-ssr-components_** provides JSX components and Vite plugins for helping the development and deployment for SSR application with Vite.
The npm package vite-ssr-components receives a total of 3,540 weekly downloads. As such, vite-ssr-components popularity was classified as popular.
We found that vite-ssr-components demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.