Skip to content

feat: sub-path (basePath) deployment support + oversized message guard - #370

Open
windli2018 wants to merge 4 commits into
agegr:mainfrom
windli2018:feat/basepath-deployment
Open

feat: sub-path (basePath) deployment support + oversized message guard#370
windli2018 wants to merge 4 commits into
agegr:mainfrom
windli2018:feat/basepath-deployment

Conversation

@windli2018

Copy link
Copy Markdown

Summary

Two independent improvements for the pi-web web UI:

1. Sub-path (basePath) deployment support

Allow pi-web to be served under a URL prefix (e.g. https://host/dev/) via PI_WEB_BASE_PATH, on top of Next.js basePath.

  • next.config.ts: read PI_WEB_BASE_PATH env → basePath + expose NEXT_PUBLIC_BASE_PATH; production builds ignore it unless PI_WEB_BUILD_BASEPATH=1 so a build spawned from the dev-server env can never bake a /dev asset prefix into .next
  • lib/base-path.ts: withBasePath() / apiUrl() helpers
  • All client fetch() / EventSource() API calls are prefixed through apiUrl() (AppShell, ChatInput, DirectoryPicker, ExportDialog, FileExplorer, FileViewer, MarkdownBody, MessageView, ModelsConfig, PluginsConfig, QuoteReplyPopover, SessionSidebar, SkillsConfig, useAgentSession, agent-client)
  • app/layout.tsx + app/manifest.ts: icons / start_url / scope basePath-aware
  • components/PwaRegistration.tsx + public/sw.js: service worker scope-aware
  • allowedDevOrigins extended (dev HMR through a reverse proxy)

Backwards compatible: with PI_WEB_BASE_PATH unset, all helpers return the original paths — root deployment is unchanged.

2. Guard oversized message rendering against browser freeze

Messages > 100 KB (e.g. pasted HAR/log dumps — one session had a 610 KB message) froze the browser because react-markdown + KaTeX + syntax highlighting processed the whole payload.

  • components/MessageView.tsx: new SafeMarkdownBody — oversized messages render as a click-to-reveal plain-text <pre> (max-height scroll), markdown pipeline skipped
  • Applies to both user messages and assistant text blocks
  • i18n: i18n.largeMessageReveal (en / zh-CN)

Testing

  • TypeScript: tsc --noEmit clean; eslint clean on changed files
  • Dev server with PI_WEB_BASE_PATH=/dev: page, /dev/api/*, manifest (start_url=/dev/, scope=/dev/), /dev/_next/* asset prefix — all verified via curl + real Firefox session (0 console errors)
  • The 610 KB-message session loads instantly; guard button shown and plain-text reveal works, page stays responsive
  • Production build: PI_WEB_BASE_PATH=/dev + NODE_ENV=production prints the ignore warning and produces a clean root deployment (no /dev asset prefix)
  • Root deployment (no basePath) verified unaffected

- next.config.ts: basePath from PI_WEB_BASE_PATH env; expose
  NEXT_PUBLIC_BASE_PATH; allow public hostnames in allowedDevOrigins for
  dev HMR through a reverse proxy
- lib/base-path.ts: withBasePath/apiUrl helpers
- client fetch/EventSource call sites prefixed via apiUrl() so all API
  traffic follows the base path
- layout.tsx manifest/icons, PwaRegistration scope, public/sw.js made
  base-path aware (scope-derived URLs)
- no behavior change when PI_WEB_BASE_PATH is unset (root deployment)
Multi-hundred-KB messages (pasted HAR/log dumps) freeze the browser
because react-markdown + KaTeX + syntax highlighting run on the entire
payload. SafeMarkdownBody renders such messages as a click-to-reveal
plain-text <pre> instead; applies to user messages and assistant text
blocks. i18n: en/zh-CN.
…th-aware

- next.config: ignore PI_WEB_BASE_PATH during production builds unless
  PI_WEB_BUILD_BASEPATH=1 (builds spawned from the dev-server env otherwise
  bake a /dev asset prefix into .next and break the root deployment)
- app/manifest.ts: start_url/scope/icons via withBasePath for sub-path PWA
- .gitignore: ignore .playwright-mcp test artifacts
The models list endpoint was still hardcoded, so with a sub-path deployment
(/dev) GET /api/models 404'd and the model selector failed to load.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant