feat: serve web UI from relay + repos page redesign#479
Merged
wesbillman merged 6 commits intomainfrom May 5, 2026
Merged
Conversation
Replace 3-column card grid with two-column layout: left sidebar with "Connect to Relay" button and People section, main content area with vertical repo list, search input, and sort dropdown. - Add OrgSidebar with relay deep link button and contributor identicons - Replace RepoCard with RepoListItem (name + Public badge + description + metadata) - Add client-side search (name/description) and sort (newest/oldest/name) - Add shared badge.tsx and input.tsx UI components - Extract unique contributors from p tags into Repo interface Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merge the separate / and /repos routes into a single index route that renders the org-style repos page directly. Remove the "Repos" nav link since there's only one page now. Update smoke test to check for the Repositories section instead of the old relay URL card. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The webUrl from kind:30617 points to the relay's server-rendered page, not a client-side route. Open it in a new tab instead of navigating within the SPA. When no webUrl is set, render the name as plain text. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add ConnectButton component, show it on mobile (lg:hidden) and in the empty state so the deep link CTA is always accessible - Change "View all N people" from a no-op button to static text - Add aria-label="Sort repositories" to the sort select - Restore /repos route as a redirect to / for bookmark compat Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add optional SPROUT_WEB_DIR config that enables the relay to serve the React SPA directly. When set, browser requests get index.html while WebSocket upgrades and Nostr clients continue working as before. - Add "fs" feature to tower-http for ServeDir support - Add web_dir config field with startup validation (index.html must exist) - Add SPA fallback service with reserved-prefix protection (/api/, /media/, /git/, etc. return 404, not index.html; missing asset files also 404) - Modify nip11_or_ws_handler: Accept:text/html → SPA after WS upgrade attempt, before NIP-11 fallback - Fix relay-url.ts to derive WebSocket URL from window.location when VITE_RELAY_URL is unset (zero-config same-origin serving) - Add Node/pnpm build stage to Dockerfile, set SPROUT_WEB_DIR=/code/web - Remove web/ from .dockerignore so Node stage can access it - Document SPROUT_WEB_DIR in .env.example Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a `just relay-web` convenience command that builds the web frontend with pnpm and starts the relay with SPROUT_WEB_DIR pointed at the build output, so you can test the production-like SPA serving locally. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SPROUT_WEB_DIRis set, the relay serves the built web frontend as a fallback, with reserved-prefix guards to avoid swallowing API/media/git 404s. Content negotiation atGET /correctly prioritizes nostr+json → WebSocket → text/html → NIP-11 fallback.relayWsUrl()now derives the WS URL fromwindow.locationwhenVITE_RELAY_URLis absent, so the web app works when served directly from the relay without hardcoded URLs.SPROUT_WEB_DIRin the runtime image.just relay-webrecipe: Convenience command to build the web frontend and start the relay serving it locally.Changed files
Cargo.toml— added"fs"feature to tower-httpcrates/sprout-relay/src/config.rs—SPROUT_WEB_DIRconfig with startup validationcrates/sprout-relay/src/router.rs—ServeDirfallback + root handler content negotiationweb/src/shared/lib/relay-url.ts— same-origin WS URL derivation.dockerignore— removedweb/exclusionDockerfile— Node build stage.env.example— documentedSPROUT_WEB_DIRjustfile—relay-webrecipeweb/src/**— repos page redesign, new components, route changesTest plan
just relay-webserves web UI at localhost🤖 Generated with Claude Code