reactRouter7Example
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in miliseconds.
index.ts
https://tmcw--cd9aa32160bf40d6b55563e36ebc3a12.web.val.run
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
- Clone the repository
- Run the application with
deno run -A backend/index.ts
- Visit
http://localhost:3000
in your browser
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.