A simple community message board application built with React Router 7, demonstrating a full-stack approach with server-side rendering and client-side navigation.
├── 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:
createBrowserRouter
and RouterProvider
After the initial page load, navigation happens entirely on the client:
/
- 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 resultsdeno run -A backend/index.ts
http://localhost:3000
in your browserThis application demonstrates a "Val Town fullstack framework" approach, combining:
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.