From 02be9594611a524268781f1b86291c72898ebb1f Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Sun, 1 Feb 2026 18:05:51 +0200 Subject: [PATCH] fix(webapp): normalize api path --- packages/webapp/src/hooks/useQueryRequest.tsx | 7 ++++- packages/webapp/src/hooks/useRequest.tsx | 26 +++++++++---------- packages/webapp/src/utils/index.tsx | 3 +++ 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/packages/webapp/src/hooks/useQueryRequest.tsx b/packages/webapp/src/hooks/useQueryRequest.tsx index d1cfc7466..e243cc4e1 100644 --- a/packages/webapp/src/hooks/useQueryRequest.tsx +++ b/packages/webapp/src/hooks/useQueryRequest.tsx @@ -3,6 +3,7 @@ import { useQuery } from 'react-query'; import { castArray, defaultTo } from 'lodash'; import { useAuthOrganizationId } from './state'; import useApiRequest from './useRequest'; +import { normalizeApiPath } from '../utils'; import { useRef } from 'react'; /** @@ -19,7 +20,11 @@ export function useRequestQuery(query, axios, props) { const states = useQuery( query, - () => apiRequest.http({ ...axios, url: `/api/${axios.url}` }), + () => + apiRequest.http({ + ...axios, + url: `/api/${normalizeApiPath(axios.url)}`, + }), props, ); // Momerize the default data. diff --git a/packages/webapp/src/hooks/useRequest.tsx b/packages/webapp/src/hooks/useRequest.tsx index e27bfff23..fd7f087ac 100644 --- a/packages/webapp/src/hooks/useRequest.tsx +++ b/packages/webapp/src/hooks/useRequest.tsx @@ -7,7 +7,7 @@ import { useSetGlobalErrors, useAuthToken, } from './state'; -import { getCookie } from '../utils'; +import { getCookie, normalizeApiPath } from '../utils'; export default function useApiRequest() { const setGlobalErrors = useSetGlobalErrors(); @@ -93,27 +93,27 @@ export default function useApiRequest() { http, get(resource, params) { - return http.get(`/api/${resource}`, params); + return http.get(`/api/${normalizeApiPath(resource)}`, params); }, post(resource, params, config) { - return http.post(`/api/${resource}`, params, config); + return http.post(`/api/${normalizeApiPath(resource)}`, params, config); }, update(resource, slug, params) { - return http.put(`/api/${resource}/${slug}`, params); + return http.put(`/api/${normalizeApiPath(resource)}/${slug}`, params); }, put(resource, params) { - return http.put(`/api/${resource}`, params); + return http.put(`/api/${normalizeApiPath(resource)}`, params); }, patch(resource, params, config) { - return http.patch(`/api/${resource}`, params, config); + return http.patch(`/api/${normalizeApiPath(resource)}`, params, config); }, delete(resource, params) { - return http.delete(`/api/${resource}`, params); + return http.delete(`/api/${normalizeApiPath(resource)}`, params); }, }), [http], @@ -130,22 +130,22 @@ export function useAuthApiRequest() { () => ({ http, get(resource, params) { - return http.get(`/api/${resource}`, params); + return http.get(`/api/${normalizeApiPath(resource)}`, params); }, post(resource, params, config) { - return http.post(`/api/${resource}`, params, config); + return http.post(`/api/${normalizeApiPath(resource)}`, params, config); }, update(resource, slug, params) { - return http.put(`/api/${resource}/${slug}`, params); + return http.put(`/api/${normalizeApiPath(resource)}/${slug}`, params); }, put(resource, params) { - return http.put(`/api/${resource}`, params); + return http.put(`/api/${normalizeApiPath(resource)}`, params); }, patch(resource, params, config) { - return http.patch(`/api/${resource}`, params, config); + return http.patch(`/api/${normalizeApiPath(resource)}`, params, config); }, delete(resource, params) { - return http.delete(`/api/${resource}`, params); + return http.delete(`/api/${normalizeApiPath(resource)}`, params); }, }), [http], diff --git a/packages/webapp/src/utils/index.tsx b/packages/webapp/src/utils/index.tsx index 5d5c0b35e..24d7597ac 100644 --- a/packages/webapp/src/utils/index.tsx +++ b/packages/webapp/src/utils/index.tsx @@ -13,6 +13,9 @@ import jsCookie from 'js-cookie'; import { deepMapKeys } from './map-key-deep'; export * from './deep'; +/** Strips leading slash from a path segment to avoid double slashes when joining with a base (e.g. `/api/` + path). */ +export const normalizeApiPath = (path) => (path || '').replace(/^\//, ''); + export const getCookie = (name, defaultValue) => _.defaultTo(jsCookie.get(name), defaultValue);