one icon indicating copy to clipboard operation
one copied to clipboard

feat: middlewares can return new Response, and web.rewrites option for rewriting paths

Open natew opened this issue 4 months ago • 1 comments

...

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

natew avatar Aug 27 '25 20:08 natew

🚅 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

railway-app[bot] avatar Aug 27 '25 20:08 railway-app[bot]