--- name: Apps MUST open at direct port — NEVER proxy paths description: CRITICAL — All apps in iframes must open at their direct port (http(s)://{host}:{port}), NEVER through /app/{id}/ proxy paths. This is the #1 cause of broken app loading across all nodes. type: feedback --- ## CRITICAL RULE: Apps load at DIRECT PORT, never proxy paths All Archipelago apps that open in iframes MUST use the direct port URL: ``` {protocol}://{hostname}:{port} ``` **NEVER** use path-based proxy URLs like `/app/indeedhub/` or `/app/mempool/` for iframe loading. Path proxies break apps because: 1. The main nginx SPA catch-all serves the Archipelago dashboard instead of the app 2. sub_filter URL rewrites break client-side routing in Vue/React apps 3. Different nodes have different nginx configs — path proxies are unreliable **Why:** This was broken THREE TIMES in one session (2026-03-17). Every time the iframe URL used a proxy path instead of the direct port, the app showed the Archipelago dashboard or a blank page. .228 and .198 work correctly because they use HTTP which naturally hits the direct port. Tailscale nodes use HTTPS which was falling through to the proxy path. **How to apply:** - In `AppSession.vue`, apps like IndeedHub must ALWAYS construct `{protocol}://{hostname}:{port}` — even on HTTPS - The `HTTPS_PROXY_PATHS` mapping should NOT include apps that have X-Frame-Options removed (like IndeedHub) - When adding new apps: use PORT_APPS for the port mapping, do NOT add to HTTPS_PROXY_PATHS unless absolutely necessary - The deploy script removes X-Frame-Options from IndeedHub's internal nginx, enabling direct port iframe access **Also critical for IndeedHub specifically:** - IndeedHub nginx MUST use hardcoded container IPs (not DNS names) — see feedback_indeedhub_nginx_ips.md - nostr-provider.js must be injected via sub_filter in the IndeedHub internal nginx - SearXNG must NOT use --cap-drop ALL — see feedback_searxng_no_cap_drop.md **When recreating containers:** - NEVER recreate containers without reapplying ALL patches (X-Frame-Options removal, nostr-provider injection, IP hardcoding) - After any container IP change (restart, recreation), update the hardcoded IPs in IndeedHub's nginx config - Deploy the SAME frontend build to ALL nodes — version mismatch causes different behavior