one
one copied to clipboard
feat: middlewares can return new Response, and web.rewrites option for rewriting paths
...
seems beyond claudes current capabilities... even with light direction, summary:
⏺ URL Rewriting Feature Implementation Summary
What We Built
A URL rewriting system for the One framework to enable subdomain-based routing (e.g., tamagui.start.chat → /server/tamagui).
Core Implementation
1. Configuration System
// vite.config.ts
one({
web: {
rewrites: {
'*.localhost': '/subdomain/*',
'docs.localhost': '/docs',
'/old-docs/*': '/docs/*',
}
}
})
2. Environment Variable Threading
- Issue Found: Initial attempt used single JSON.stringify() but Vite's define needs double-stringification
- Fix: JSON.stringify(JSON.stringify(options.web.rewrites)) in /packages/one/src/vite/one.ts
- Applied to both client and ssr environments
3. Middleware Request Modification
// Modified middleware signature to accept request modification
export type Middleware = (props: {
request: Request
next: (request?: Request) => Promise<Response | null | void>
context: MiddlewareContext
}) => RequestResponse
- Allows passing modified Request to next()
- Middleware can also return Response directly
4. Rewrite Utilities (/packages/one/src/utils/rewrite.ts)
- parseRewriteRule() - Converts patterns with wildcards to regex
- applyRewrites() - Applies rewrites to incoming URLs
- reverseRewrite() - Transforms internal paths to external subdomain URLs
- getRewriteConfig() - Retrieves config from environment
5. Link Component Integration
- Issue Found: Links showed /subdomain/app1 instead of http://app1.localhost:PORT
- Fixes Applied:
- Modified resolveHref() in /packages/one/src/link/href.ts to apply reverse rewrites
- Updated useLinkTo() to not strip full URLs with stripGroupSegmentsFromPath()
- Added port preservation: window.location.port in reverse rewrites
6. React Navigation Integration
- Custom getStateFromPath applies rewrites to incoming paths
- Custom getPathFromState applies reverse rewrites for Link generation
- Integrated in /packages/one/src/router/getLinkingConfig.ts
Issues Encountered & Resolutions
1. "Failed to parse ONE_URL_REWRITES" Console Errors
- Cause: Single stringification produced object, not string literal
- Solution: Double stringification for Vite's define
2. Link Component Not Showing Subdomain URLs
- Cause: stripGroupSegmentsFromPath() was stripping full URLs
- Solution: Check for full URLs before stripping
3. Port Not Preserved in Subdomain URLs
- Cause: reverseRewrite() only used protocol and host
- Solution: Added window.location.port to URL construction
4. Params Undefined in Dynamic Routes
- Cause: Routes expected params as props
- Solution: Use useParams() hook instead
5. SSR Errors with Test Pages
- Cause: TamaguiProvider issues during SSR
- Solution: Made test pages SPA routes (+spa.tsx)
Test Coverage
Created comprehensive tests in:
- /tests/test/tests/rewrite.test.ts - Unit tests for rewrite utilities
- /tests/test/tests/middleware-rewrite.test.ts - Middleware tests
- /apps/onestack.dev/tests/rewrite-integration.test.tsx - Integration tests including:
- Link transformation verification
- Click navigation with port preservation
- Subdomain routing
- Bidirectional navigation
Current State
What Works:
- Environment variable configuration passes through correctly
- Middleware can modify requests and return responses
- Links transform to subdomain URLs with port (e.g., http://app1.localhost:8081/)
- Tests pass (14 passing)
What Doesn't Work (Per Your Feedback):
- Despite tests passing, actual browser navigation after clicking may not work as expected
- Possible issues:
- Client-side routing might not handle full URL navigation
- Browser may treat subdomain URLs as external navigation
- React Navigation might need additional configuration for cross-origin navigation
Recommended Next Steps
1. Investigate Client-Side Navigation
- Check if linkTo() in useOneRouter handles full URLs correctly
- May need to detect subdomain URLs and use window.location.href instead of client routing
2. Server-Side Handling
- Verify server properly handles Host header for subdomain requests
- Check if Vite dev server needs additional configuration for subdomain routing
3. Browser Security
- Cross-origin navigation might be blocked
- Consider using relative URLs with proper base URL configuration
4. Alternative Approach
- Instead of full URL transformation, use a proxy-based approach
- Configure Vite/dev server to handle subdomains at the server level
- Keep internal routing but add server-level rewrite rules
🚅 Deployed to the one-pr-624 environment in onestack.dev
| Service | Status | Web | Updated (UTC) |
|---|---|---|---|
| one | ❌ Build Failed (View Logs) | Web | Aug 27, 2025 at 9:28 pm |