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
5
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
/
README.md
Code
/
README.md
Search
9/10/2025
Viewing readonly version of main branch: v5
View latest version
README.md

Glance Demos

A Val Town application for managing and viewing demos with authentication.

Features

  • Authentication: Google OAuth via LastLogin
  • Dashboard: User-friendly interface showing system status
  • Health Monitoring: Real-time system health checks
  • Modular Architecture: Clean separation of concerns

Authentication

This application uses LastLogin for authentication:

  • Login: Users sign in with their Google account
  • Protected Routes: All routes require authentication except public endpoints
  • Logout: Users can logout via /auth/logout (handled automatically by LastLogin)
  • Session Management: Automatic session validation and renewal

Public Routes

The following routes are accessible without authentication:

  • /api/health - System health status

Protected Routes

Routes are protected by different authentication mechanisms:

User Authentication (Google OAuth via LastLogin):

  • / - Main dashboard (shows user info and system status)
  • /api/* - API endpoints (except health)
  • /views/* - View routes including /views/glimpse/:id
  • /glimpse/* - Shortcut routes including /glimpse/:id (equivalent to /views/glimpse/:id)

Webhook Authentication (X-API-KEY header):

  • /tasks/* - Webhook endpoints for external integrations (POST requests only)
    • GET requests to /tasks/* are allowed without authentication for debug endpoints

Project Structure

├── backend/
│   ├── controllers/         # Business logic controllers
│   ├── routes/             # Route definitions and HTTP handling
│   │   ├── api/            # API endpoints
│   │   ├── glimpse/        # Glimpse routes (enhanced with React frontend)
│   │   ├── tasks/          # Task-related routes
│   │   ├── views/          # User-facing views
│   │   └── authCheck.ts    # Authentication middleware
│   └── services/           # External service integrations
├── frontend/               # React frontend assets
│   ├── glimpse.html        # HTML template for glimpse views
│   ├── glimpse.tsx         # React entry point
│   ├── components/         # React components
│   │   ├── GlimpseView.tsx # Main glimpse display component
│   │   ├── NotionBlock.tsx # Notion block renderer
│   │   └── NotionProperty.tsx # Property display component
│   └── README.md
├── shared/                 # Shared utilities and types
│   ├── types.ts           # TypeScript interfaces for Notion data
│   ├── utils.ts           # Shared utility functions
│   └── README.md
└── main.tsx               # Application entry point with static file serving

Architecture

The application follows a clean MVC architecture with proper separation of concerns:

Route Layer (HTTP Handling)

  • Handles HTTP request/response formatting
  • Extracts parameters from requests
  • Applies authentication middleware
  • Calls controller functions and formats responses
  • Manages HTTP status codes and error responses

Controller Layer (Business Logic)

  • Contains business logic and orchestrates service calls
  • Returns plain data objects (not HTTP responses)
  • Handles data validation and transformation
  • Filters sensitive data (e.g., button properties)
  • Provides consistent success/error response structure

Service Layer (External Integrations)

  • Handles external API calls (Notion, databases)
  • Manages data persistence
  • Returns structured results with success/error information

Response Format

All controller functions return a consistent structure:

{ success: boolean, data: any | null, error: string | null, details?: string // Additional error context }

Routes then format these into appropriate HTTP responses.

Glimpse Routes

The application provides multiple routes for accessing page data and user authentication:

Authentication Routes

  • GET /glimpse/login - User-specific login redirect

    • Requires user authentication (Google OAuth via LastLogin)
    • Looks up authenticated user's email in GLANCE_DEMOS_DB_ID database
    • If user found: Redirects to user's personal URL
    • If user not found: Creates new user record and redirects to /glimpse/thanks
    • Shows detailed error information for debugging database structure issues
  • GET /glimpse/thanks - New user welcome page

    • Shows confirmation that user account was created
    • Explains next steps (admin review, email with demo link)
    • Provides timeline expectations (1-2 business days)

Data Access Routes

  • GET /views/glimpse/:id - Get complete page data with blocks by Notion page ID (JSON only)
  • GET /glimpse/:id - Enhanced with React Frontend - Content negotiation based on Accept header:
    • Browser requests (Accept: text/html): Returns rich React frontend with interactive Notion content display
    • API requests (Accept: application/json): Returns raw JSON data (same as before)
    • Fallback: If HTML template fails to load, automatically serves JSON

React Frontend Features

The /glimpse/:id endpoint now includes a rich React frontend when accessed via browser:

Content Rendering

  • Rich Notion Blocks: Supports headings, paragraphs, lists, code blocks, callouts, images, videos, tables, and more
  • Property Display: Shows all page properties with type-specific formatting and icons
  • Responsive Design: Mobile-friendly layout using TailwindCSS
  • Server-Side Data Injection: Initial data injected to eliminate loading states

User Experience

  • Error Handling: Graceful error states with retry functionality
  • Loading States: Smooth loading indicators
  • Navigation: Easy return to dashboard
  • Debug Mode: Raw data view in development environments

Technical Implementation

  • Content Negotiation: Single endpoint serves both HTML and JSON
  • Static File Serving: Frontend assets served via /frontend/* route
  • React 18.2.0: Pinned version for consistency
  • TypeScript Support: Shared types for Notion data structures

Note: The glimpse endpoints now provide both programmatic access (JSON) and user-friendly viewing (React frontend) from the same URL, maintaining backward compatibility while adding rich content display capabilities.

Demo API Endpoints

API endpoints for accessing Notion page data with different levels of detail:

  • GET /api/demo/:id/properties - Returns page properties only
  • GET /api/demo/:id - Returns page properties + all blocks recursively

Architecture:

  • Routes: Handle HTTP concerns (parameter extraction, response formatting, status codes)
  • Controllers: Contain business logic (getDemoProperties, getDemoFull)
  • Services: Handle Notion API integration

Authentication Behavior:

  • Browser requests: Require user authentication (Google OAuth via LastLogin)
  • Internal requests: Bypass authentication when called from within the Val (identified by Deno user agent)

Response Format: Routes return the data directly from controllers on success:

{ // Notion page object with properties // For full endpoint: also includes "blocks" array with recursive block data }

On error, routes return:

{ "error": "Error message", "details": "Additional error context" }

Usage Examples:

// Internal call from within Val (no authentication needed) const response = await fetch('/api/demo/page-id/properties'); const data = await response.json(); // External browser request (requires authentication) // User must be logged in via Google OAuth

All glimpse routes:

  • Require user authentication
  • Return complete page data including properties and blocks recursively
  • Filter out button properties from Notion page data
  • Return standardized JSON responses (except authentication routes which redirect or show HTML)
  • Use the same controller functions as the API endpoints for consistency

New User Registration Flow

  1. Authentication: User must be authenticated via Google OAuth (handled by LastLogin)
  2. Database Lookup: System queries GLANCE_DEMOS_DB_ID database for user's email
  3. User Creation: If not found, creates new user record with email address
  4. Welcome Page: Redirects to /glimpse/thanks with next steps information
  5. Admin Process: Admin reviews new users and adds demo URLs manually
  6. User Return: User can return to /glimpse/login once URL is configured

Database Requirements for Login

The GLANCE_DEMOS_DB_ID database must contain:

  • Email property: Contains user's email address (exact match with authenticated email)
  • URL property: Contains user's redirect URL (optional for new users)

Supported URL property names: URL, Link, Redirect URL, Demo URL, url, link Supported URL property types: url, rich_text, title

Error Handling

The login endpoint provides detailed error information for debugging:

  • Missing environment variables
  • Database query failures
  • User creation failures (falls back to access denied page)
  • Invalid or missing URL properties
  • URL format validation errors

The dashboard displays both routes in a comparison table for easy testing.

Development

The application is built with:

  • Hono: Web framework for routing and middleware
  • LastLogin: Authentication service
  • TypeScript: Type-safe development
  • Val Town: Hosting platform

Webhook Authentication

The application supports webhook endpoints for external integrations (like Notion webhooks):

Configuration

Set the webhook secret in your environment:

NOTION_WEBHOOK_SECRET=your-secret-key-here

Webhook Endpoints

  • POST /tasks/notion-webhook - Main webhook endpoint for Notion integrations (requires X-API-KEY header)
  • POST /tasks/url - Updates Notion page URL property with glimpse URL (requires X-API-KEY header)
  • POST /tasks/test - Test endpoint for webhook authentication (requires X-API-KEY header)
  • GET /tasks/debug-webhook - Debug endpoint to check webhook configuration

Authentication

Webhook endpoints require the X-API-KEY header:

curl -X POST https://your-val.web.val.run/tasks/test \ -H "X-API-KEY: your-secret-key-here"

Testing

Use the webhook testing form in the dashboard:

  1. Navigate to your dashboard at /
  2. Find the "Webhook Endpoint" section
  3. Enter your NOTION_WEBHOOK_SECRET value
  4. Click "Test Webhook" to verify authentication

Environment Variables

Configure these environment variables for full functionality:

  • GLANCE_DEMOS_DB_ID - Notion database ID for demos
  • GLANCE_CONTENT_DB_ID - Notion database ID for content
  • GLANCE_INTERACTIONS_DB_ID - Notion database ID for interactions
  • NOTION_API_KEY - Notion API key for database access
  • NOTION_WEBHOOK_SECRET - Secret key for webhook authentication

Real-time Viewing Analytics

The application includes real-time viewing analytics with immediate Notion synchronization:

Blob Storage + Notion Sync

  • Fast blob updates: Page viewing status stored in Val Town blob storage for instant response (~100ms)
  • Immediate Notion sync: When users start viewing pages, Notion database is updated immediately
  • Automatic cleanup: Cron job runs every minute to mark stale sessions (>1 minute old) as not viewing

Viewing Data Flow

  1. User starts viewing: Frontend calls /api/viewing → Blob updated → Notion synced immediately
  2. User continues viewing: Frontend updates blob every 4 seconds (no Notion calls)
  3. User leaves/session stale: Cron detects stale session → Blob updated → Notion synced immediately

Notion Database Schema

Pages in your Notion databases should include these properties for viewing analytics:

  • Viewing (Checkbox) - Real-time viewing status
  • Last Viewed (Date) - Timestamp of last viewing activity
  • Current Viewer (Rich Text) - Email of current viewer
  • Tab Visible (Checkbox) - Whether page tab is currently visible

Frontend Integration

  • Page Visibility API: Tracks when users switch tabs or minimize windows
  • Periodic updates: Calls viewing API every 4 seconds while page is active
  • Session management: Automatic cleanup handles crashed browsers and network issues
  • Performance: Non-blocking API calls don't impact user 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.