-
-
Notifications
You must be signed in to change notification settings - Fork 764
Description
Fider Cloud or Self Hosted
Self Hosted: 0.21.1
Describe the bug
Fider cannot be hosted under a URL sub-path (e.g., https://example.com/feedback/) behind a reverse proxy. While BASE_URL accepts a path component, the path is not used consistently across the backend or frontend, causing broken redirects, broken API calls, and broken navigation links. This goes beyond the Context.BaseURL() bug reported in #1452 — even after fixing that, there are ~120 locations across the codebase with hardcoded root-relative paths.
To Reproduce
- Set
BASE_URL=https://example.com/feedbackandHOST_MODE=single - Configure a reverse proxy to forward
/feedback/to Fider, stripping the prefix - Open Fider at
https://example.com/feedback/ - Delete a post — the DELETE API call goes to
/api/v1/posts/6(missing/feedbackprefix), andnavigator.goHome()redirects tohttps://example.com/instead ofhttps://example.com/feedback/ - Click any navigation link (Settings, Admin, etc.) — the browser navigates to
https://example.com/settingsinstead ofhttps://example.com/feedback/settings - Sign in via OAuth — the callback redirects to
/instead of/feedback/
Expected behavior
When BASE_URL includes a path component, all redirects, API calls, navigation links, and URL construction should respect that path prefix. Fider should be fully functional when hosted under a sub-path.
Additional context
I'm using 0.21.1 of Fider. Self hosted.
Here is a full audit of all affected areas:
1. Core Bug — Context.BaseURL() strips path (see #1452)
The Context.BaseURL() method ignores the path in BASE_URL, which is the root cause for redirects and frontend navigation.
2. Backend — Hardcoded root-relative redirects
9 locations use c.Redirect("/") or c.Redirect("/path") instead of c.Redirect(c.BaseURL() + "/path"):
| File | Line | Current Code |
|---|---|---|
app/handlers/oauth.go |
34 | c.Redirect("/") |
app/handlers/oauth.go |
40 | c.Redirect("/") |
app/handlers/oauth.go |
109 | c.Redirect("/not-invited") |
app/handlers/signin.go |
383 | c.Redirect("/") |
app/handlers/signup.go |
144 | c.Redirect("/") |
app/handlers/post.go |
101 | c.Redirect(fmt.Sprintf("/posts/%d/%s", ...)) |
app/middlewares/tenant.go |
83 | c.Redirect("/signup") |
app/middlewares/tenant.go |
130 | c.Redirect("/signin?redirect=...") |
app/middlewares/tenant.go |
132 | c.Redirect("/signin") |
3. Frontend — API calls don't include base path
The http service in public/services/http.ts passes root-relative URLs (e.g., /api/v1/posts/6) directly to fetch(). When hosted at /feedback/, these requests miss the path prefix. All ~70 API call sites in public/services/actions/*.ts are affected.
4. Frontend — Hardcoded location.href assignments
Several files bypass the navigator service (which was partially fixed in 95f7b91) and assign root-relative paths directly:
| File | Line | Current Code |
|---|---|---|
public/pages/SignIn/CompleteSignInProfile.page.tsx |
26 | location.href = "/?c=" + props.c |
public/pages/SignIn/CompleteSignInProfile.page.tsx |
28 | location.href = "/" |
public/pages/Administration/pages/GeneralSettings.page.tsx |
25 | location.href = "/" |
public/pages/Home/components/ShareFeedback.tsx |
199 | location.href = `/posts/${...}` |
5. Frontend — Hardcoded href attributes in React components
23+ components use hardcoded root-relative href values in <a> tags. Key examples:
public/components/Header.tsx—href="/"public/components/UserMenu.tsx—href="/settings",href="/admin",href="/signout"public/pages/Administration/components/SideMenu.tsx— 12 admin linkspublic/pages/Administration/pages/Export.page.tsx— export download linkspublic/components/common/Legal.tsx—href="/terms",href="/privacy"public/components/ReadOnlyNotice.tsx—href="/admin/billing"
6. Frontend — window.history.pushState with hardcoded paths
| File | Line | Current Code |
|---|---|---|
public/pages/Home/Home.page.tsx |
74 | pushState({...}, "", `/posts/${postNumber}/${slug}`) |
public/pages/Home/Home.page.tsx |
80 | pushState({}, "", "/") |
7. HTML Templates — Hardcoded feed paths
| File | Line | Current Code |
|---|---|---|
views/index.html |
3 | href="/feed/global.atom" |
views/index.html |
5 | href="/feed/posts/{{ $.public.props.post.ID }}.atom" |
Proposed Solution
- Fix
Context.BaseURL()to return the fullBASE_URLin single-host mode (see [BUG]Context.BaseURL()strips path fromBASE_URL, breaking subfolder/sub-path hosting #1452) - Add a
basePathhelper to the frontend that extracts the path portion ofbaseURLfor URL construction - Prepend base path in
http.tsso all API calls include the prefix automatically - Replace all hardcoded redirects in Go handlers with
c.BaseURL()+ path - Replace all hardcoded
location.hrefassignments withnavigator.goTo()/navigator.goHome() - Update all
hrefattributes to use the base path utility - Update HTML templates to use the template-provided baseURL for feed links
Workaround
Hosting via a dedicated subdomain (e.g., feedback.example.com) works correctly and avoids all these issues. Sub-path hosting currently requires a reverse proxy configuration that routes both /feedback/* AND /api/v1/*, /assets/*, /_api/*, /static/*, /feed/* to Fider, which is fragile.