custom-endpoints
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.
Viewing readonly version of main branch: v176View latest version
A simple community message board application built with React Router 7, demonstrating a full-stack approach with server-side rendering and client-side navigation.
- Server-Side Rendering: All pages are server-rendered when accessed directly
- Client-Side Navigation: After initial load, navigation happens client-side
- Topic Management: Create and view discussion topics
- Messaging System: Post messages in topics
- Direct Message Links: Link directly to specific messages via timestamps
- Search Functionality: Search topics and messages with URL parameters
- Loading Indicators: Visual feedback during async operations
āāā backend/
ā āāā database/
ā ā āāā migrations.ts # Database schema
ā ā āāā queries.ts # Database queries
ā āāā index.ts # Server entry point
āāā frontend/
ā āāā components/
ā ā āāā LoadingSpinner.tsx
ā ā āāā MessageForm.tsx
ā ā āāā MessageList.tsx
ā ā āāā SearchForm.tsx
ā āāā index.html # HTML template
ā āāā index.tsx # Client entry point
āāā routes/
ā āāā App.tsx # Main application component
ā āāā Home.tsx # Home page component
ā āāā Home.loader.ts # Home page data loader
ā āāā Topic.tsx # Topic detail component
ā āāā Topic.loader.ts # Topic data loader
ā āāā Topic.action.ts # Topic message creation action
ā āāā TopicMessage.loader.ts # Direct message link loader
ā āāā Topics.action.ts # Topic creation action
ā āāā Search.tsx # Search results component
ā āāā Search.loader.ts # Search data loader
āāā shared/
āāā routes.ts # Route definitions
āāā types.ts # Shared TypeScript types
The application uses React Router 7's createStaticHandler
, createStaticRouter
, and StaticRouterProvider
to render pages on the server. When a user directly accesses a URL:
- The server receives the request
- It runs the appropriate loaders/actions for the matched route
- The page is rendered with the data and sent to the client
- The client hydrates the page with
createBrowserRouter
andRouterProvider
After the initial page load, navigation happens entirely on the client:
- React Router handles link clicks and form submissions
- Data is fetched asynchronously using loaders and actions
- A loading spinner is displayed during data fetching
- The UI updates without a full page reload
- Topics: Stored in SQLite with title and creation timestamp
- Messages: Linked to topics with content and creation timestamp
- Search: Queries both topics and messages, with results in the URL
/
- Home page with list of topics/
- Create new topic/topics/:topicId
- View a topic and its messages/topics/:topicId/messages/:messageId
- Direct link to a message/search?q=query
- Search results
This application demonstrates a "Val Town fullstack framework" approach, combining:
- Hono: For server-side routing and handling
- React Router 7: For both server and client-side routing
- SQLite: For data persistence
- TypeScript: For type safety across the stack
The code is structured to be idiomatic and simple, serving as a reference for building full-stack applications with React Router 7. The project uses a Remix-style file naming convention with co-located components, loaders, and actions in the /routes
directory.