Skip to content

feat: configure application to run on a relative path#1990

Open
junaid18183 wants to merge 6 commits intostackblitz-labs:mainfrom
junaid18183:feat/base-path
Open

feat: configure application to run on a relative path#1990
junaid18183 wants to merge 6 commits intostackblitz-labs:mainfrom
junaid18183:feat/base-path

Conversation

@junaid18183
Copy link

@junaid18183 junaid18183 commented Sep 11, 2025

Added Support for BASE_PATH so that application can be run on a relative path.
Fixes issue #443

Tested

VITE_BASE_PATH=/bolt pnpm run dev
VITE_BASE_PATH=/ pnpm run dev
pnpm run dev

@junaid18183 junaid18183 changed the title Configure application to run on a relative path fix: Configure application to run on a relative path Sep 11, 2025
@junaid18183 junaid18183 changed the title fix: Configure application to run on a relative path feat: configure application to run on a relative path Sep 11, 2025
@Stijnus Stijnus self-assigned this Sep 17, 2025
@Stijnus Stijnus self-requested a review September 17, 2025 11:46
Copy link
Collaborator

@Stijnus Stijnus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review — PR #1990

The feature itself (running at a sub-path) is a real need, and the vite.config.ts changes are correct. However, the implementation has a major DRY issue that needs addressing before merge.


1. Massive code duplication — needs a utility function

The same base path computation is copy-pasted ~25 times across 33 files with at least 3 inconsistent normalization patterns:

Pattern A (full normalization — used in ~10 places):

const envBasePath = import.meta.env.VITE_BASE_PATH;
const basePath = envBasePath ? (envBasePath.startsWith('/') ? envBasePath : '/' + envBasePath) : '';
const apiUrl = `${basePath}/api/...`.replace(/\/+/g, '/');

Pattern B (partial normalization — used in ~8 places):

const envBasePath = import.meta.env.VITE_BASE_PATH;
const basePath = envBasePath && envBasePath !== '/' ? envBasePath.replace(/\/$/, '') : '';

Pattern C (no normalization — used in ~7 places):

fetch(`${import.meta.env.VITE_BASE_PATH || ''}/api/...`);

Pattern C can produce double slashes (//api/...) or missing leading slashes depending on what the user sets. This inconsistency will cause bugs.

Fix: Create a single utility:

// app/utils/basePath.ts
export function getApiUrl(path: string): string {
  const base = (import.meta.env.VITE_BASE_PATH || '').replace(/\/$/, '');
  return `${base}${path.startsWith('/') ? path : '/' + path}`;
}

Then every fetch('/api/...') becomes fetch(getApiUrl('/api/...')). One place to maintain, one normalization strategy.


2. Static assets likely don't need manual prefixing

Vite's base config (which this PR correctly sets) already handles static asset URL prefixing. The manual changes in Header.tsx (logo images) and root.tsx (favicon) may double-prefix the path. Worth testing with VITE_BASE_PATH=/bolt to verify.


3. BranchSelector.tsx inconsistency (same file, different patterns)

GitHub branches use Pattern A (full normalization):

const envBasePath = import.meta.env.VITE_BASE_PATH;
const basePath = envBasePath ? (envBasePath.startsWith('/') ? envBasePath : '/' + envBasePath) : '';
const apiUrl = `${basePath}/api/github-branches`.replace(/\/+/g, '/');

But GitLab branches a few lines later use Pattern C (inline, no normalization):

response = await fetch(`${import.meta.env.VITE_BASE_PATH || ''}/api/gitlab-branches`, {

4. root.tsx favicon IIFE is fragile

href: (() => {
  const envBasePath = typeof window !== 'undefined' ? import.meta.env.VITE_BASE_PATH : process.env.VITE_BASE_PATH;
  ...
})(),

Since links() runs on the server during SSR, typeof window will always be 'undefined', so the client branch is dead code. This should just use import.meta.env.VITE_BASE_PATH (Vite replaces it at build time for both client and server).


5. Linked issue #443 is closed

The referenced issue is already closed — worth confirming this feature is still desired.


What's done well

  • vite.config.ts changes are correct (base + basename)
  • Comprehensive coverage — almost all fetch calls and navigation are updated
  • README documentation added
  • Tested with multiple configurations (/bolt, /, unset)

Suggested path forward

  1. Extract a getApiUrl() (and getAppUrl() for navigation) utility — use it everywhere
  2. Verify whether Vite's base already handles static assets (logos, favicon) — remove manual prefixing if so
  3. Add basic tests for the utility with edge cases (/bolt, /, '', /bolt/)
  4. Confirm the feature is still wanted given the closed issue

Happy to re-review after the refactor!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants