File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1- export const API_BASE_URL = import . meta. env . VITE_BACKEND_URL ?? "http://localhost:3000" ;
1+ const DEFAULT_API_BASE_URL = "http://localhost:3000" ;
2+
3+ const normalizeApiBaseUrl = ( rawBaseUrl : string ) : string => {
4+ const baseWithoutTrailingSlash = rawBaseUrl . replace ( / \/ + $ / , "" ) ;
5+
6+ try {
7+ const parsed = new URL ( baseWithoutTrailingSlash ) ;
8+ const duplicatedHostPrefix = `/${ parsed . hostname } ` ;
9+
10+ // Handle accidental base URLs like http://host/host/api
11+ if (
12+ parsed . pathname === duplicatedHostPrefix ||
13+ parsed . pathname . startsWith ( `${ duplicatedHostPrefix } /` )
14+ ) {
15+ parsed . pathname = parsed . pathname . slice ( duplicatedHostPrefix . length ) || "/" ;
16+ }
17+
18+ parsed . pathname = parsed . pathname . replace ( / \/ + $ / , "" ) || "/" ;
19+ return `${ parsed . origin } ${ parsed . pathname === "/" ? "" : parsed . pathname } ` ;
20+ } catch {
21+ return baseWithoutTrailingSlash ;
22+ }
23+ } ;
24+
25+ export const API_BASE_URL = normalizeApiBaseUrl (
26+ import . meta. env . VITE_BACKEND_URL ?? DEFAULT_API_BASE_URL
27+ ) ;
28+
29+ export const buildApiUrl = ( endpoint : string ) : string => {
30+ if ( / ^ h t t p s ? : \/ \/ / i. test ( endpoint ) ) {
31+ return endpoint ;
32+ }
33+
34+ const normalizedEndpoint = endpoint . replace ( / ^ \/ + / , "" ) ;
35+ return new URL ( normalizedEndpoint , `${ API_BASE_URL } /` ) . toString ( ) ;
36+ } ;
Original file line number Diff line number Diff line change 11// src/lib/fetcher.ts
22
33import { useAuth } from "@clerk/react" ;
4- import { API_BASE_URL } from "./api" ;
4+ import { buildApiUrl } from "./api" ;
55
66export const useApi = ( ) => {
77 const { getToken } = useAuth ( ) ;
@@ -12,7 +12,7 @@ export const useApi = () => {
1212 ) => {
1313 const token = await getToken ( ) ;
1414
15- const res = await fetch ( ` ${ API_BASE_URL } ${ endpoint } ` , {
15+ const res = await fetch ( buildApiUrl ( endpoint ) , {
1616 ...options ,
1717 headers : {
1818 ...( options . headers || { } ) ,
Original file line number Diff line number Diff line change 11import { useUser , useClerk , useAuth } from '@clerk/react'
22import { useState } from 'react'
3+ import { buildApiUrl } from '../lib/api'
34
45export function DashboardPage ( ) {
56 const { user } = useUser ( )
@@ -15,8 +16,7 @@ export function DashboardPage() {
1516 try {
1617 const authToken = await getToken ( )
1718
18- const backendUrl = import . meta. env . VITE_BACKEND_URL || "http://localhost:3000"
19- const res = await fetch ( `${ backendUrl } /preferences` , {
19+ const res = await fetch ( buildApiUrl ( '/preferences' ) , {
2020 headers : {
2121 'Authorization' : `Bearer ${ authToken } ` ,
2222 'Content-Type' : 'application/json'
You can’t perform that action at this time.
0 commit comments