
Product
Secure Your AI-Generated Code with Socket MCP
Socket MCP brings real-time security checks to AI-generated code, helping developers catch risky dependencies before they enter the codebase.
rsbuild-plugin-react-router
Advanced tools
A Rsbuild plugin that provides seamless integration with React Router, supporting both client-side routing and server-side rendering (SSR).
npm install rsbuild-plugin-react-router
# or
yarn add rsbuild-plugin-react-router
# or
pnpm add rsbuild-plugin-react-router
Add the plugin to your rsbuild.config.ts
:
import { defineConfig } from '@rsbuild/core';
import { pluginReactRouter } from 'rsbuild-plugin-react-router';
import { pluginReact } from '@rsbuild/plugin-react';
export default defineConfig(() => {
return {
plugins: [
pluginReactRouter({
// Optional: Enable custom server mode
customServer: false,
// Optional: Specify server output format
serverOutput: "commonjs",
//Optional: enable experimental support for module federation
federation: false
}),
pluginReact()
],
};
});
The plugin uses a two-part configuration system:
rsbuild.config.ts
):pluginReactRouter({
/**
* Whether to disable automatic middleware setup for custom server implementation.
* Enable this when you want to handle server setup manually.
* @default false
*/
customServer?: boolean,
/**
* Specify the output format for server-side code.
* Options: "commonjs" | "module"
* @default "module"
*/
serverOutput?: "commonjs" | "module"
/**
* Enable experimental support for module federation
* @default false
*/
federation?: boolean
})
react-router.config.ts
):import type { Config } from '@react-router/dev/config';
export default {
/**
* Whether to enable Server-Side Rendering (SSR) support.
* @default true
*/
ssr: true,
/**
* Build directory for output files
* @default 'build'
*/
buildDirectory: 'dist',
/**
* Application source directory
* @default 'app'
*/
appDirectory: 'app',
/**
* Base URL path
* @default '/'
*/
basename: '/my-app',
} satisfies Config;
All configuration options are optional and will use sensible defaults if not specified.
If no configuration is provided, the following defaults will be used:
// Plugin defaults (rsbuild.config.ts)
{
customServer: false
}
// Router defaults (react-router.config.ts)
{
ssr: true,
buildDirectory: 'build',
appDirectory: 'app',
basename: '/'
}
Routes can be defined in app/routes.ts
using the helper functions from @react-router/dev/routes
:
import {
type RouteConfig,
index,
layout,
prefix,
route,
} from '@react-router/dev/routes';
export default [
// Index route for the home page
index('routes/home.tsx'),
// Regular route
route('about', 'routes/about.tsx'),
// Nested routes with a layout
layout('routes/docs/layout.tsx', [
index('routes/docs/index.tsx'),
route('getting-started', 'routes/docs/getting-started.tsx'),
route('advanced', 'routes/docs/advanced.tsx'),
]),
// Routes with dynamic segments
...prefix('projects', [
index('routes/projects/index.tsx'),
layout('routes/projects/layout.tsx', [
route(':projectId', 'routes/projects/project.tsx'),
route(':projectId/edit', 'routes/projects/edit.tsx'),
]),
]),
] satisfies RouteConfig;
The plugin provides several helper functions for defining routes:
index()
- Creates an index routeroute()
- Creates a regular route with a pathlayout()
- Creates a layout route with nested childrenprefix()
- Adds a URL prefix to a group of routesRoute components support the following exports:
default
- The route componentErrorBoundary
- Error boundary componentHydrateFallback
- Loading component during hydrationLayout
- Layout componentclientLoader
- Client-side data loadingclientAction
- Client-side form actionshandle
- Route handlelinks
- Prefetch linksmeta
- Route meta datashouldRevalidate
- Revalidation controlloader
- Server-side data loadingaction
- Server-side form actionsheaders
- HTTP headersThe plugin supports two ways to handle server-side rendering:
Default Server Setup: By default, the plugin automatically sets up the necessary middleware for SSR.
Custom Server Setup: For more control, you can disable the automatic middleware setup by enabling custom server mode:
// rsbuild.config.ts
import { defineConfig } from '@rsbuild/core';
import { pluginReactRouter } from 'rsbuild-plugin-react-router';
import { pluginReact } from '@rsbuild/plugin-react';
export default defineConfig(() => {
return {
plugins: [
pluginReactRouter({
customServer: true
}),
pluginReact()
],
};
});
When using a custom server, you'll need to:
server/index.ts
):import { createRequestHandler } from '@react-router/express';
export const app = createRequestHandler({
build: () => import('virtual/react-router/server-build'),
getLoadContext() {
// Add custom context available to your loaders/actions
return {
// ... your custom context
};
},
});
server.js
):import { createRsbuild, loadConfig } from '@rsbuild/core';
import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const app = express();
const isDev = process.env.NODE_ENV !== 'production';
async function startServer() {
if (isDev) {
const config = await loadConfig();
const rsbuild = await createRsbuild({
rsbuildConfig: config.content,
});
const devServer = await rsbuild.createDevServer();
app.use(devServer.middlewares);
app.use(async (req, res, next) => {
try {
const bundle = await devServer.environments.node.loadBundle('app');
await bundle.app(req, res, next);
} catch (e) {
next(e);
}
});
const port = Number.parseInt(process.env.PORT || '3000', 10);
const server = app.listen(port, () => {
console.log(`Development server is running on http://localhost:${port}`);
devServer.afterListen();
});
devServer.connectWebSocket({ server });
} else {
// Production mode
app.use(express.static(path.join(__dirname, 'build/client'), {
index: false
}));
// Load the server bundle
const serverBundle = await import('./build/server/static/js/app.js');
// Mount the server app after static file handling
app.use(async (req, res, next) => {
try {
await serverBundle.default.app(req, res, next);
} catch (e) {
next(e);
}
});
const port = Number.parseInt(process.env.PORT || '3000', 10);
app.listen(port, () => {
console.log(`Production server is running on http://localhost:${port}`);
});
}
}
startServer().catch(console.error);
package.json
scripts:{
"scripts": {
"dev": "node server.js",
"build": "rsbuild build",
"start": "NODE_ENV=production node server.js"
}
}
The custom server setup allows you to:
To deploy your React Router app to Cloudflare Workers:
rsbuild.config.ts
):import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { pluginReactRouter } from 'rsbuild-plugin-react-router';
export default defineConfig({
environments: {
node: {
performance: {
chunkSplit: { strategy: 'all-in-one' },
},
tools: {
rspack: {
experiments: { outputModule: true },
externalsType: 'module',
output: {
chunkFormat: 'module',
chunkLoading: 'import',
workerChunkLoading: 'import',
wasmLoading: 'fetch',
library: { type: 'module' },
module: true,
},
resolve: {
conditionNames: ['workerd', 'worker', 'browser', 'import', 'require'],
},
},
},
},
},
plugins: [pluginReactRouter({customServer: true}), pluginReact()],
});
wrangler.toml
):workers_dev = true
name = "my-react-router-worker"
compatibility_date = "2024-11-18"
main = "./build/server/static/js/app.js"
assets = { directory = "./build/client/" }
[vars]
VALUE_FROM_CLOUDFLARE = "Hello from Cloudflare"
# Optional build configuration
# [build]
# command = "npm run build"
# watch_dir = "app"
server/index.ts
):import { createRequestHandler } from 'react-router';
declare global {
interface CloudflareEnvironment extends Env {}
interface ImportMeta {
env: {
MODE: string;
};
}
}
declare module 'react-router' {
export interface AppLoadContext {
cloudflare: {
env: CloudflareEnvironment;
ctx: ExecutionContext;
};
}
}
// @ts-expect-error - virtual module provided by React Router at build time
import * as serverBuild from 'virtual/react-router/server-build';
const requestHandler = createRequestHandler(serverBuild, import.meta.env.MODE);
export default {
fetch(request, env, ctx) {
return requestHandler(request, {
cloudflare: { env, ctx },
});
},
} satisfies ExportedHandler<CloudflareEnvironment>;
{
"dependencies": {
"@react-router/node": "^7.1.3",
"@react-router/serve": "^7.1.3",
"react-router": "^7.1.3"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20241112.0",
"@react-router/cloudflare": "^7.1.3",
"@react-router/dev": "^7.1.3",
"wrangler": "^3.106.0"
}
}
package.json
):{
"scripts": {
"build": "rsbuild build",
"deploy": "npm run build && wrangler deploy",
"dev": "rsbuild dev",
"start": "wrangler dev"
}
}
workers_dev = true
setting enables deployment to workers.dev subdomainmain
points to your Worker's entry point in the build outputassets
directory specifies where your static client files are located[vars]
sectioncompatibility_date
should be kept up to date@cloudflare/workers-types
wrangler dev
wrangler deploy
Local Development:
# Start local development server
npm run dev
# or
npm start
Production Deployment:
# Build and deploy
npm run deploy
The plugin automatically:
MIT
0.0.4
FAQs
React Router plugin for Rsbuild
The npm package rsbuild-plugin-react-router receives a total of 87 weekly downloads. As such, rsbuild-plugin-react-router popularity was classified as not popular.
We found that rsbuild-plugin-react-router 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.
Product
Socket MCP brings real-time security checks to AI-generated code, helping developers catch risky dependencies before they enter the codebase.
Security News
As vulnerability data bottlenecks grow, the federal government is formally investigating NIST’s handling of the National Vulnerability Database.
Research
Security News
Socket’s Threat Research Team has uncovered 60 npm packages using post-install scripts to silently exfiltrate hostnames, IP addresses, DNS servers, and user directories to a Discord-controlled endpoint.