FeaturesTemplatesShowcaseTownie
AI
BlogDocsPricing
Log inSign up
lightweight
lightweightglimpse2-runbook-view-glimpse-save-login-react
Remix of lightweight/glimpse2-runbook-view-glimpse-save-login
Public
Like
glimpse2-runbook-view-glimpse-save-login-react
Home
Code
8
_townie
13
backend
7
frontend
9
shared
3
.vtignore
README.md
deno.json
H
main.tsx
Branches
2
Pull requests
Remixes
History
Environment variables
6
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
frontend
/
README.md
Code
/
frontend
/
README.md
Search
…
Viewing readonly version of main branch: v34
View latest version
README.md

Frontend Architecture

This directory contains the frontend application with a clean, scalable architecture following React best practices and separation of concerns.

Directory Structure

frontend/
├── components/          # React components (UI rendering only)
│   ├── GlimpseView.tsx  # Main glimpse viewing component
│   ├── NotionBlock.tsx  # Notion block rendering with semantic HTML
│   └── NotionProperty.tsx # Notion property rendering with type-specific formatting
├── hooks/               # Custom React hooks (stateful logic)
│   ├── useAuth.ts       # Authentication and authorization
│   ├── useGlimpseData.ts # Glimpse data fetching and state
│   ├── useAgentData.ts  # Agent data with polling
│   └── useViewingTracking.ts # Viewing status tracking
├── services/            # API calls and external integrations
│   ├── glimpseService.ts # Glimpse data API
│   ├── agentService.ts  # Agent data API
│   ├── viewingService.ts # Viewing status API
│   └── cobrowseService.ts # Cobrowse session management
├── utils/               # Pure utility functions
│   ├── dataExtraction.ts # Notion data parsing
│   ├── validation.ts    # Authorization logic
│   └── notionFormatting.ts # Property value formatting
├── types/               # TypeScript type definitions
│   ├── notion.ts        # Notion data structures
│   ├── agent.ts         # Agent data structures
│   ├── viewing.ts       # Viewing status structures
│   └── hooks.ts         # Hook return types
├── styles/              # CSS files
│   └── notion-content.css # Notion-specific styling
├── pages/               # Page entry points
│   └── glimpse.tsx      # Glimpse page React entry point
└── *.html               # HTML templates with semantic structure

Architecture Principles

Separation of Concerns

  • Components: Pure UI rendering, minimal logic, focus on JSX
  • Hooks: Stateful logic, side effects, data management
  • Services: External API interactions, error handling
  • Utils: Pure functions, data transformations, no side effects
  • Types: TypeScript definitions, shared across all layers

Data Flow

HTML Template → React Entry Point → Components → Hooks → Services → Utils
                     ↓                ↓         ↓         ↓         ↓
                 DOM Mount      UI Rendering  State    API Calls  Pure Logic

Dependency Direction

  • Components depend on hooks, utils, types
  • Hooks depend on services, utils, types
  • Services depend on utils, types
  • Utils depend only on types
  • Types have no dependencies
  • No circular dependencies

How the Frontend Works

1. Page Loading Process

Initial Request

  1. User visits /glimpse/{id} URL
  2. Server authentication checks user access
  3. HTML template served with semantic structure (header/main/footer)
  4. Initial data injection - glimpse data embedded in window.__GLIMPSE_DATA__
  5. React entry point (glimpse.tsx) mounts to #root

React Initialization

  1. glimpse.tsx extracts initial data from window
  2. GlimpseView component renders with initial data
  3. Custom hooks initialize with data and start side effects
  4. Component renders UI based on hook states

2. Component Architecture

GlimpseView (Main Component)

  • Orchestrates all data and UI logic
  • Uses custom hooks for all stateful operations
  • Renders header content via React portals to HTML header
  • Conditionally shows agent connection UI and page content
  • Handles loading/error states with user-friendly UI

NotionBlock & NotionProperty (Rendering Components)

  • Pure rendering components for Notion content
  • Semantic HTML output with proper accessibility
  • Smart list grouping - consecutive list items become proper <ul>/<ol>
  • Type-specific formatting using utility functions
  • Recursive rendering for nested block structures

3. Custom Hooks System

useAuth

  • Extracts user email from window data (injected by server)
  • Provides authorization function for page access control
  • Memoized for performance - doesn't re-run unnecessarily

useGlimpseData

  • Manages glimpse data state (loading, error, success)
  • Handles initial data or fetches from API if needed
  • Provides refetch function for error recovery
  • Centralized error handling with consistent error structures

useAgentData

  • Polls agent data every 5 seconds when authorized
  • Manages agent state and hasAgents boolean
  • Automatic cleanup of intervals on unmount
  • Conditional polling - only runs if user is authorized

useViewingTracking

  • Tracks viewing status with periodic updates (10 seconds)
  • Monitors page visibility changes (tab switching)
  • Sends viewing analytics to server
  • Proper cleanup on component unmount

4. Service Layer

API Communication

  • Centralized API calls with consistent error handling
  • Type-safe responses using TypeScript interfaces
  • Silent failures where appropriate (viewing tracking)
  • User feedback for critical errors (glimpse loading)

Service Functions

  • fetchGlimpseData - Gets page content from Notion
  • fetchAgentData - Gets agent information for support
  • updateViewingStatus - Sends analytics data
  • startCobrowseSession - Initializes screen sharing

5. Utility Functions

Data Extraction (dataExtraction.ts)

  • extractUserEmail - Parses email from Notion properties
  • extractUserName - Parses name/title from properties
  • formatPageTitle - Creates "Name for Email" format

Validation (validation.ts)

  • checkAuthorization - Email-based access control
  • getUserEmailFromWindow - Extracts injected user data

Notion Formatting (notionFormatting.ts)

  • formatNotionDate - Consistent date formatting
  • extractPlainText - Text from rich text arrays
  • formatMultiSelect - Comma-separated values
  • formatBoolean - Emoji-enhanced boolean display

6. Type System

Comprehensive TypeScript Coverage

  • Notion types - Page data, properties, blocks
  • Agent types - Agent information and collections
  • Hook types - Return types for custom hooks
  • Viewing types - Analytics payload structures

Type Safety Benefits

  • Compile-time error checking
  • IDE autocomplete and IntelliSense
  • Self-documenting code
  • Refactoring safety

Key Features

Glimpse Viewing Experience

  • Rich Notion content with semantic HTML rendering
  • Real-time agent integration with cobrowse functionality
  • Automatic viewing analytics for usage tracking
  • Email-based access control for security
  • Responsive design with mobile-friendly layout

Technical Features

  • Server-side data injection - eliminates loading states
  • React portals - dynamic header content population
  • Automatic polling - real-time agent data updates
  • Smart error handling - graceful degradation
  • Semantic HTML structure - accessibility and SEO friendly

Performance Optimizations

  • Initial data injection - faster first render
  • Memoized hooks - prevents unnecessary re-renders
  • Conditional polling - only when authorized
  • Proper cleanup - prevents memory leaks

Usage Examples

Component with Hooks

export function MyComponent({ glimpseId }: Props) { const { userEmail, isAuthorized } = useAuth(); const { data, loading, error } = useGlimpseData(glimpseId); const { agentData, hasAgents } = useAgentData(glimpseId, isAuthorized(data?.properties)); if (loading) return <Loading />; if (error) return <Error error={error} />; return <div>{/* Pure rendering logic */}</div>; }

Service Usage

import { fetchGlimpseData } from "../services/glimpseService.ts"; const data = await fetchGlimpseData(glimpseId); if (data.success) { // Handle success } else { // Handle error with data.error and data.details }

Utility Usage

import { extractUserEmail, formatPageTitle } from "../utils/dataExtraction.ts"; import { formatNotionDate, formatBoolean } from "../utils/notionFormatting.ts"; const email = extractUserEmail(properties); const title = formatPageTitle(properties); const date = formatNotionDate(dateString); const status = formatBoolean(isActive);

Development Guidelines

Component Development

  1. Keep components pure - focus on rendering, minimal logic
  2. Use custom hooks - extract all stateful logic
  3. Leverage utilities - don't duplicate formatting logic
  4. Type everything - use proper TypeScript interfaces
  5. Handle loading/error states - provide good UX

Hook Development

  1. Single responsibility - each hook has one clear purpose
  2. Proper cleanup - clear intervals, remove listeners
  3. Memoization - use useMemo/useCallback for performance
  4. Error handling - consistent error structures
  5. Type return values - use interfaces from types/

Service Development

  1. Centralize API calls - don't use fetch directly in components
  2. Consistent error handling - return structured error objects
  3. Type safety - use proper request/response types
  4. Silent failures - where appropriate for UX
  5. User feedback - for critical operations

Utility Development

  1. Pure functions only - no side effects
  2. Single responsibility - each function does one thing
  3. Error handling - graceful degradation
  4. Type safety - proper input/output types
  5. Testability - easy to unit test

Scaling and Extension

Adding New Pages

  1. Create HTML template with same header/footer structure
  2. Create React entry point following glimpse.tsx pattern
  3. Reuse existing hooks for common functionality
  4. Add page-specific components as needed

Adding New Features

  1. Types first - define data structures in types/
  2. Services - add API integration functions
  3. Hooks - create stateful logic hooks
  4. Components - build UI components
  5. Utils - extract reusable logic

Testing Strategy

  1. Utils - Unit test pure functions
  2. Services - Mock API responses
  3. Hooks - Test with React Testing Library
  4. Components - Test rendering with mocked dependencies

This architecture provides a solid foundation for building scalable, maintainable React applications with clear separation of concerns and excellent developer experience.

Go to top
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Product
FeaturesPricing
Developers
DocsStatusAPI ExamplesNPM Package Examples
Explore
ShowcaseTemplatesNewest ValsTrending ValsNewsletter
Company
AboutBlogCareersBrandhi@val.town
Terms of usePrivacy policyAbuse contact
© 2025 Val Town, Inc.