Frontend assets fail to load when served behind a sub-path reverse proxy (e.g. Home Assistant ingress) #119

Closed
opened 2026-10-05 01:58:00 +02:00 by adam · 14 comments
Owner

When RemoteTerm is run behind a reverse proxy that serves it under a sub-path rather than at the root, the frontend fails to load and the browser shows a blank screen. The backend connects and operates correctly — this is purely a frontend asset path issue.

Context

I've packaged RemoteTerm as a Home Assistant app. Home Assistant's ingress system proxies app UIs through a path like /api/hassio_ingress/{token}/, stripping the prefix before forwarding requests to the app. The backend receives them at / as expected, and in testing I can confirm the radio connection and data flow work correctly via the logs.

However, the browser receives the HTML response and then tries to load the bundled JS/CSS using the absolute paths Vite outputs by default — e.g. <script src="/assets/index-abc123.js">. The browser resolves these against the domain root rather than the ingress sub-path, the requests never reach the app, and the page is blank.

This affects any sub-path reverse proxy setup, not just Home Assistant.

Root cause

frontend/vite.config.ts has no base set, so Vite defaults to "/" and emits absolute asset paths in the built HTML.

Proposed fix

Add base: "./" to vite.config.ts:

export default defineConfig({
  base: "./",   // ← add this
  plugins: [react()],
  // ...
})

This causes Vite to emit relative asset paths (./assets/index-abc123.js) instead of absolute ones. Relative paths resolve correctly regardless of what sub-path the app is served under, so this fixes sub-path proxies with no impact on the default root-served deployment.

Happy to open a PR for this if it's something you'd accept.

I'm primarily running this for personal use, but I've made the repository public in case others find it useful. If there's interest in officially supporting a Home Assistant app and you'd like to take over or absorb the repository, I'm happy to hand it off.

When RemoteTerm is run behind a reverse proxy that serves it under a sub-path rather than at the root, the frontend fails to load and the browser shows a blank screen. The backend connects and operates correctly — this is purely a frontend asset path issue. ## Context I've packaged RemoteTerm as a [Home Assistant app](https://github.com/bhaggs/ha-remoteterm-app). Home Assistant's ingress system proxies app UIs through a path like `/api/hassio_ingress/{token}/`, stripping the prefix before forwarding requests to the app. The backend receives them at `/` as expected, and in testing I can confirm the radio connection and data flow work correctly via the logs. However, the browser receives the HTML response and then tries to load the bundled JS/CSS using the absolute paths Vite outputs by default — e.g. `<script src="/assets/index-abc123.js">`. The browser resolves these against the domain root rather than the ingress sub-path, the requests never reach the app, and the page is blank. This affects any sub-path reverse proxy setup, not just Home Assistant. ## Root cause `frontend/vite.config.ts` has no `base` set, so Vite defaults to `"/"` and emits absolute asset paths in the built HTML. ## Proposed fix Add `base: "./"` to `vite.config.ts`: ```ts export default defineConfig({ base: "./", // ← add this plugins: [react()], // ... }) ``` This causes Vite to emit relative asset paths (`./assets/index-abc123.js`) instead of absolute ones. Relative paths resolve correctly regardless of what sub-path the app is served under, so this fixes sub-path proxies with no impact on the default root-served deployment. Happy to open a PR for this if it's something you'd accept. I'm primarily running this for personal use, but I've made the repository public in case others find it useful. If there's interest in officially supporting a Home Assistant app and you'd like to take over or absorb the repository, I'm happy to hand it off. <!-- github-sync-id:4209339498 -->
adam closed this issue 2026-10-05 01:58:00 +02:00
Author
Owner

Eyy good spotting. I'm fixing that now and have made an issue to implement a full HA integration that exposes web socket events, sensors for stuff, etc.

Eyy good spotting. I'm fixing that now and have made an issue to implement a full HA integration that exposes web socket events, sensors for stuff, etc. <!-- github-comment-id:4190427925 -->
Author
Owner

This autoclosed with the commit, but feel free to reopen if you run into any issues. Sometime this week I'll make a repo with sensor integration, messaging, etc. As someone who doesn't use HA, I'll obviously test it but if you're willing to beta test that'd be awesome please! 🙂

This autoclosed with the commit, but feel free to reopen if you run into any issues. Sometime this week I'll make a repo with sensor integration, messaging, etc. As someone who doesn't use HA, I'll obviously test it but if you're willing to beta test that'd be awesome please! 🙂 <!-- github-comment-id:4190474805 -->
Author
Owner

Definitely down to beta test and feel free to leverage anything from my repo in building out an official HA app.

Definitely down to beta test and feel free to leverage anything from my repo in building out an official HA app. <!-- github-comment-id:4190495878 -->
Author
Owner

I've pushed up the ha branch, which enables an MQTT fanout module that publishes to HA.

https://github.com/jkingsman/Remote-Terminal-for-MeshCore/tree/ha

I started on, then opted to stay with the simpler route rather than, a full installable integration -- more weight than I wanted to take on for something I don't personally use. The doc link in the setup will be wrong until it's merged but https://github.com/jkingsman/Remote-Terminal-for-MeshCore/blob/ha/README_HA.md is some LLM generated examples that I've done a bit of testing with. I'm still gonna go through and polish that up and probably make some tweaks, but that's the general shape.

Would love to hear your thoughts and, if willing, your feedback on functionality if you try it -- thanks!!

I've pushed up the `ha` branch, which enables an MQTT fanout module that publishes to HA. https://github.com/jkingsman/Remote-Terminal-for-MeshCore/tree/ha I started on, then opted to stay with the simpler route rather than, a full installable integration -- more weight than I wanted to take on for something I don't personally use. The doc link in the setup will be wrong until it's merged but https://github.com/jkingsman/Remote-Terminal-for-MeshCore/blob/ha/README_HA.md is some LLM generated examples that I've done a bit of testing with. I'm still gonna go through and polish that up and probably make some tweaks, but that's the general shape. Would love to hear your thoughts and, if willing, your feedback on functionality if you try it -- thanks!! <!-- github-comment-id:4226052450 -->
Author
Owner

Nice. I’ll give this a try this weekend to test and provide any feedback.

Nice. I’ll give this a try this weekend to test and provide any feedback. <!-- github-comment-id:4229561096 -->
Author
Owner

Awesome. I've just merged to main; feel free to open a new issue if you have any problems.

Awesome. I've just merged to main; feel free to open a new issue if you have any problems. <!-- github-comment-id:4232848462 -->
Author
Owner

Cool. I’ve been playing around with it today and so far it’s working well. Only thing I noticed is that for example, repeaters, aren’t exposing the full breadth of potential telemetry sensors (e.g., temperature, packet duplicate count, error count). I can open a new issue to account for that. Just wasn’t sure if there was a specific or technical reason they weren’t included.

Cool. I’ve been playing around with it today and so far it’s working well. Only thing I noticed is that for example, repeaters, aren’t exposing the full breadth of potential telemetry sensors (e.g., temperature, packet duplicate count, error count). I can open a new issue to account for that. Just wasn’t sure if there was a specific or technical reason they weren’t included. <!-- github-comment-id:4232928411 -->
Author
Owner

Oooh good thought! I hadn't done telemetry/LPP fetch but I can add that

Oooh good thought! I hadn't done telemetry/LPP fetch but I can add that <!-- github-comment-id:4232949932 -->
Author
Owner

Added LPP sensors.

Added LPP sensors. <!-- github-comment-id:4233289315 -->
Author
Owner

Awesome! Thanks for making this happen.

I dropped a comment on the commit about setting default display precision which would be great to include. https://github.com/jkingsman/Remote-Terminal-for-MeshCore/commit/b9414e84ee56aff3c7923b7d1cddd892262c8996#commitcomment-182220632

Awesome! Thanks for making this happen. I dropped a comment on the commit about setting default display precision which would be great to include. https://github.com/jkingsman/Remote-Terminal-for-MeshCore/commit/b9414e84ee56aff3c7923b7d1cddd892262c8996#commitcomment-182220632 <!-- github-comment-id:4233311665 -->
Author
Owner

Thanks! Fixed in e1ee7fcd24

Thanks! Fixed in e1ee7fcd2407ddc795a7a33c54c31acc966d9ef3 <!-- github-comment-id:4233319040 -->
Author
Owner

Thanks! Fixed in Awesome; I'm gonna close this again but lemme know if you have any other issues.

Thanks! Fixed in Awesome; I'm gonna close this again but lemme know if you have any other issues. <!-- github-comment-id:4233453066 -->
Author
Owner

Sounds good. I’ll keep testing

Sounds good. I’ll keep testing <!-- github-comment-id:4233705628 -->
Author
Owner

Thank you 🥰🥰🥰

Thank you 🥰🥰🥰 <!-- github-comment-id:4233713490 -->
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adam/Remote-Terminal-for-MeshCore#119