Frontend Dashboard

React Router v8 application with server-side rendering on Cloudflare Workers. UI built with shadcn/ui components and Tailwind CSS v4.

Routes

Path File Description
/ _layout._index.tsx Dashboard home
/live _layout.live.tsx Live session control surface
/feed _layout.feed.tsx Trails from followed users
/explore _layout.explore.tsx Public trail discovery, challenge board, weekly featured challenge
/search _layout.search.tsx Search trails and users
/notifications _layout.notifications.tsx Community notifications
/collections _layout.collections.tsx Named trail collections
/trails _layout.trails.tsx R2 trail browser
/my/trails _layout.my.trails.tsx User's cloud trail library
/my/settings _layout.my.settings.tsx Account settings, passkey mgmt
/audit _layout.audit.tsx Audit log viewer
/extension-test _layout.extension-test.tsx Extension connectivity test
/about _layout.about.tsx Platform info, features, docs
/about/architecture _layout.about.architecture.tsx Architecture documentation
/about/extension _layout.about.extension.tsx Extension documentation
/about/backend-api _layout.about.backend-api.tsx Backend API documentation
/about/database-schema _layout.about.database-schema.tsx Database schema docs
/about/frontend-dashboard _layout.about.frontend-dashboard.tsx Frontend docs
/login login.tsx Email/password + passkey login
/register register.tsx Registration with email verify
/trail/:id trail.$id.tsx Single trail viewer/replay (client-rendered, internal id)
/@{username} profile.$username.tsx Public server-rendered user profile
/t/:token t.$token.tsx Public shared trail viewer (SSR, share token, OG/Twitter cards)
/t/:token/card.png t.$token.card.tsx Auto-generated 1200×630 OG preview PNG (workers-og)
/t/:token/embed t.$token.embed.tsx Compact framable embed view for <iframe> (noindex)
/s/:token s.$token.tsx Legacy share URL — 301 redirect to /t/:token

Layout

All dashboard routes are wrapped in _layout.tsx, which provides:

  • Sidebar (app-sidebar.tsx) — Navigation links with icons (lucide-react)
  • Header (dashboard-header.tsx) — Breadcrumbs, user menu
  • Built on shadcn/ui Sidebar + SidebarProvider

Auth pages (/login, /register) and the trail viewers (/trail/:id, /t/:token) render outside the sidebar layout. The public viewer /t/:token is fully server-rendered: a route loader resolves the share token against cloud_trails (only when is_public = 1), loads the trail body from R2, and emits OpenGraph + Twitter Card meta tags so pasted links preview in chat apps. Unknown or private tokens return HTTP 404. The og:image points at the sibling resource route /t/:token/card.png, a 1200×630 PNG rendered in the worker with workers-og (Satori + resvg-wasm) — wordmark, trail title, a miniature path of colored domain nodes, and summary stats. Fonts are loaded at render time via loadGoogleFont and the PNG is cached (Cache-Control). Shared D1/R2 lookup lives in app/lib/trail.server.ts; pure formatting helpers in app/lib/trail.ts. The viewer also offers a copyable <iframe> snippet (client island) pointing at /t/:token/embed — a compact, chrome-less variant that sizes to content, is marked noindex, and sets no framing headers so it can be embedded anywhere.

Public profile pages resolve user_profiles.username, show display name, bio, avatar, cover color, verified business badge, optional brand/support/ knowledge-base links, public-trail stats, follower/following counts, up to five pinned trails, and recent public trails. Signed-in viewers can follow and unfollow directly from the profile page. The feed page shows public trails from followed users with author metadata, category badges, favicons, duration, page count, and the first three page titles. The explore page surfaces public trails across the network with filters for category, duration, and domain, and adds a challenge board for posting prompts, submitting public trails, and voting on answers, plus a weekly featured challenge spotlight. Business-aware search and explore cards now surface a verified badge when available, and the settings screen can toggle business profile fields for public presentation. The shared trail viewer now renders a cover band, highlight reel, vertical timeline, page cards with interaction metrics, and domain-grouped trail sections derived from the trail summary model. Settings (/my/settings) manages the blincr-owned public profile fields, including business metadata, while security and billing continue to link out to AR. The My Trails page includes a per-trail category selector before publishing and the public profile page filters public trails by category query string. The public trail viewer now includes trail reactions and comments, and the sidebar adds community navigation for feed, explore, search, notifications, and collections. The public trail viewer also supports synchronized watch parties for shared replay rooms, with host playback controls and live emoji reactions. It also infers shopping trails, renders product cards and price comparison, and offers a shop-all action for detected commerce pages. It also infers research trails, extracts citations and annotations from visited pages, and offers markdown and BibTeX export for the resulting research report. The live page starts sessions, shows viewer counts, lists participants, streams chat, and lets the host pass control to another participant. It also exposes a copyable invite link and page votes for the current page, with replay showing stored vote counts. Public trail pages also support review mode with per-page 1-5 star ratings, show aggregated page ratings alongside dwell time, and lift review trails in search when the query implies comparisons. The My Trails page now shows creator analytics for public trails, including views, unique viewers, completion depth, and the most-attended page. The settings page also manages signed outbound webhook delivery for trail creation, followers, reactions, and comments. It also manages Slack incoming-webhook sharing, which posts a preview card to a channel when a trail is published. An "AI agent access (MCP)" card shows the /mcp endpoint and mints a one-time 90-day Bearer token so MCP clients (Claude, Cowork) can read trails and manage blincrs — see docs/backend-api.md § MCP. The My Trails page has a per-trail "For AI" button that downloads the agent-ready trail bundle (blincr-trail-bundle/1, see docs/trail-bundle.md), and /about/trail-bundle renders that schema reference for agent authors. Agent trails (E13.4) show a purple "🤖 agent" badge on My Trails; in the public trail viewer, agent contributors always render in a fixed purple with a robot prefix instead of the hashed palette color. The home page has an "agents" section ("Let your agent browse — keep the receipts").

All HTML responses are served as text/html; charset=utf-8 (app/entry.server.tsx); without the explicit charset, routes that export their own meta (which replaces the root <meta charset>) render UTF-8 punctuation as mojibake.

Auth Flow

  1. User registers at /register with name, email, password, terms checkbox
  2. Backend sends 6-digit verification code via Resend (or logs it in dev)
  3. User enters code on verification step
  4. On success, receives JWT-like bearer token stored in cookie/localStorage
  5. Login supports both password and passkey (WebAuthn) authentication

UI Components (shadcn/ui)

app/components/ui/: badge, breadcrumb, button, card, collapsible, input, separator, sheet, sidebar, skeleton, slot, table, tooltip.

Dependencies

Package Purpose
react / react-dom 19 UI framework
react-router 7.6 File-based routing + SSR
@simplewebauthn/browser Client-side WebAuthn
@simplewebauthn/server Server-side WebAuthn verification
isbot Bot detection for SSR
@tailwindcss/typography Prose styling for markdown docs
tailwindcss 4 Utility-first CSS
marked Markdown to HTML renderer
lucide-react Icon library
class-variance-authority Component variant styling
clsx / tailwind-merge Class name utilities

Dev Server

npm run dev          # react-router dev (wrangler.jsonc)
npm run preview      # build + wrangler dev workers/deploy-entry.ts (prebuilt dist)
npm run deploy       # build + wrangler deploy workers/deploy-entry.ts (prebuilt dist)
npm run typecheck    # wrangler types + react-router typegen + tsc