Skip to content

Commit 6b12480

Browse files
authored
Better port detection in custom servers (#206)
* fix * version bump
1 parent 74af10d commit 6b12480

24 files changed

+9675
-7222
lines changed

package-lock.json

Lines changed: 9103 additions & 7219 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "react-router-devtools",
33
"description": "Devtools for React Router - debug, trace, find hydration errors, catch bugs and inspect server/client data with react-router-devtools",
44
"author": "Alem Tuzlak",
5-
"version": "5.0.3",
5+
"version": "5.0.4",
66
"license": "MIT",
77
"keywords": [
88
"react-router",
@@ -74,8 +74,10 @@
7474
"docs": "npm run dev -w docs",
7575
"prepublishOnly": "npm run build",
7676
"react-router-vite": "npm run dev -w test-apps/react-router-vite",
77+
"react-router-custom": "npm run dev -w test-apps/custom-server",
7778
"runner": "npm-run-all -s build -p watch-all",
7879
"dev": "npm run runner react-router-vite",
80+
"dev:c": "npm run runner react-router-custom",
7981
"build": "run-s tsup:* -- --clean",
8082
"watch-all": "npm-run-all -p tsup:index:watch tsup:client:watch tsup:server:watch tsup:context:watch -- --watch",
8183
"tsup:index": "tsup",
@@ -102,10 +104,10 @@
102104
},
103105
"workspaces": [".", "test-apps/*"],
104106
"peerDependencies": {
105-
"react": ">=17",
106-
"react-dom": ">=17",
107107
"@types/react": ">=17",
108108
"@types/react-dom": ">=17",
109+
"react": ">=17",
110+
"react-dom": ">=17",
109111
"react-router": ">=7.0.0",
110112
"vite": ">=5.0.0 || >=6.0.0"
111113
},

src/vite/plugin.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,13 @@ export const reactRouterDevTools: (args?: ReactRouterViteConfig) => Plugin[] = (
235235
if (server.config.appType !== "custom") {
236236
return
237237
}
238+
server.middlewares.use((req, res, next) => {
239+
if (req.socket.localPort && req.socket.localPort !== port) {
240+
port = req.socket.localPort
241+
process.rdt_port = port
242+
}
243+
next()
244+
})
238245
if (server.config.server.port) {
239246
process.rdt_port = server.config.server.port ?? 5173
240247
port = process.rdt_port
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.react-router
2+
build
3+
node_modules
4+
README.md

test-apps/custom-server/.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.DS_Store
2+
/node_modules/
3+
*.tsbuildinfo
4+
5+
# React Router
6+
/.react-router/
7+
/build/

test-apps/custom-server/Dockerfile

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
FROM node:20-alpine AS development-dependencies-env
2+
COPY . /app
3+
WORKDIR /app
4+
RUN npm ci
5+
6+
FROM node:20-alpine AS production-dependencies-env
7+
COPY ./package.json package-lock.json /app/
8+
WORKDIR /app
9+
RUN npm ci --omit=dev
10+
11+
FROM node:20-alpine AS build-env
12+
COPY . /app/
13+
COPY --from=development-dependencies-env /app/node_modules /app/node_modules
14+
WORKDIR /app
15+
RUN npm run build
16+
17+
FROM node:20-alpine
18+
COPY ./package.json package-lock.json server.js /app/
19+
COPY --from=production-dependencies-env /app/node_modules /app/node_modules
20+
COPY --from=build-env /app/build /app/build
21+
WORKDIR /app
22+
CMD ["npm", "run", "start"]

test-apps/custom-server/README.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Welcome to React Router!
2+
3+
A modern, production-ready template for building full-stack React applications using React Router.
4+
5+
## Features
6+
7+
- 🚀 Server-side rendering
8+
- ⚡️ Hot Module Replacement (HMR)
9+
- 📦 Asset bundling and optimization
10+
- 🔄 Data loading and mutations
11+
- 🔒 TypeScript by default
12+
- 🎉 TailwindCSS for styling
13+
- 📖 [React Router docs](https://reactrouter.com/)
14+
15+
## Getting Started
16+
17+
### Installation
18+
19+
Install the dependencies:
20+
21+
```bash
22+
npm install
23+
```
24+
25+
### Development
26+
27+
Start the development server with HMR:
28+
29+
```bash
30+
npm run dev
31+
```
32+
33+
Your application will be available at `http://localhost:5173`.
34+
35+
## Building for Production
36+
37+
Create a production build:
38+
39+
```bash
40+
npm run build
41+
```
42+
43+
## Deployment
44+
45+
### Docker Deployment
46+
47+
To build and run using Docker:
48+
49+
```bash
50+
docker build -t my-app .
51+
52+
# Run the container
53+
docker run -p 3000:3000 my-app
54+
```
55+
56+
The containerized application can be deployed to any platform that supports Docker, including:
57+
58+
- AWS ECS
59+
- Google Cloud Run
60+
- Azure Container Apps
61+
- Digital Ocean App Platform
62+
- Fly.io
63+
- Railway
64+
65+
### DIY Deployment
66+
67+
If you're familiar with deploying Node applications, the built-in app server is production-ready.
68+
69+
Make sure to deploy the output of `npm run build`
70+
71+
```
72+
├── package.json
73+
├── package-lock.json (or pnpm-lock.yaml, or bun.lockb)
74+
├── server.js
75+
├── build/
76+
│ ├── client/ # Static assets
77+
│ └── server/ # Server-side code
78+
```
79+
80+
## Styling
81+
82+
This template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever CSS framework you prefer.
83+
84+
---
85+
86+
Built with ❤️ using React Router.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@import "tailwindcss";
2+
3+
@theme {
4+
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif,
5+
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
6+
}
7+
8+
html,
9+
body {
10+
@apply bg-white dark:bg-gray-950;
11+
12+
@media (prefers-color-scheme: dark) {
13+
color-scheme: dark;
14+
}
15+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import {
2+
isRouteErrorResponse,
3+
Links,
4+
Meta,
5+
Outlet,
6+
Scripts,
7+
ScrollRestoration,
8+
} from "react-router";
9+
10+
import type { Route } from "./+types/root";
11+
import "./app.css";
12+
13+
export const links: Route.LinksFunction = () => [
14+
{ rel: "preconnect", href: "https://fonts.googleapis.com" },
15+
{
16+
rel: "preconnect",
17+
href: "https://fonts.gstatic.com",
18+
crossOrigin: "anonymous",
19+
},
20+
{
21+
rel: "stylesheet",
22+
href: "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap",
23+
},
24+
];
25+
26+
export function Layout({ children }: { children: React.ReactNode }) {
27+
return (
28+
<html lang="en">
29+
<head>
30+
<meta charSet="utf-8" />
31+
<meta name="viewport" content="width=device-width, initial-scale=1" />
32+
<Meta />
33+
<Links />
34+
</head>
35+
<body>
36+
{children}
37+
<ScrollRestoration />
38+
<Scripts />
39+
</body>
40+
</html>
41+
);
42+
}
43+
44+
export default function App() {
45+
return <Outlet />;
46+
}
47+
48+
export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
49+
let message = "Oops!";
50+
let details = "An unexpected error occurred.";
51+
let stack: string | undefined;
52+
53+
if (isRouteErrorResponse(error)) {
54+
message = error.status === 404 ? "404" : "Error";
55+
details =
56+
error.status === 404
57+
? "The requested page could not be found."
58+
: error.statusText || details;
59+
} else if (import.meta.env.DEV && error && error instanceof Error) {
60+
details = error.message;
61+
stack = error.stack;
62+
}
63+
64+
return (
65+
<main className="pt-16 p-4 container mx-auto">
66+
<h1>{message}</h1>
67+
<p>{details}</p>
68+
{stack && (
69+
<pre className="w-full p-4 overflow-x-auto">
70+
<code>{stack}</code>
71+
</pre>
72+
)}
73+
</main>
74+
);
75+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { type RouteConfig, index } from "@react-router/dev/routes";
2+
3+
export default [index("routes/home.tsx")] satisfies RouteConfig;

0 commit comments

Comments
 (0)