feat: configure application to run on a relative path#1990
feat: configure application to run on a relative path#1990junaid18183 wants to merge 6 commits intostackblitz-labs:mainfrom
Conversation
Stijnus
left a comment
There was a problem hiding this comment.
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.tschanges 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
- Extract a
getApiUrl()(andgetAppUrl()for navigation) utility — use it everywhere - Verify whether Vite's
basealready handles static assets (logos, favicon) — remove manual prefixing if so - Add basic tests for the utility with edge cases (
/bolt,/,'',/bolt/) - Confirm the feature is still wanted given the closed issue
Happy to re-review after the refactor!
Added Support for BASE_PATH so that application can be run on a relative path.
Fixes issue #443
Tested