This content originally appeared on DEV Community and was authored by A0mineTV
Building a Modern Blog Platform with React 19, TypeScript, and shadcn/ui
In this article, I’ll walk you through building a complete blog platform using the latest web technologies. We’ll create a feature-rich application with authentication, role-based access control, and a beautiful, responsive UI.
Full Source Code: You can find the complete project on GitHub: blog-ts Repository
Project Overview
Our blog platform includes:
- Modern Authentication System with login/register modals
- Role-Based Access Control (Admin, Author, Reader)
- Blog Management with posts, authors, and tags
- Responsive Design with Tailwind CSS
- Type-Safe Development with strict TypeScript
- Modern UI Components using shadcn/ui and Radix UI
Tech Stack
Core Technologies
- React 19 – Latest React with improved performance
- TypeScript 5.8 – Strict typing for better development experience
- Vite – Lightning-fast build tool
- pnpm – Efficient package management
UI & Styling
- Tailwind CSS 4.1 – Utility-first CSS framework
- shadcn/ui – Beautiful, accessible UI components
- Radix UI – Unstyled, accessible components
- Lucide React – Beautiful icon library
State Management & Data
- React Query (TanStack) – Powerful data fetching and caching
- React Auth Kit – Complete authentication solution
- Custom Hooks – Reusable business logic
Project Structure
blog-ts/
├── src/
│ ├── components/
│ │ ├── ui/ # shadcn/ui components
│ │ ├── auth/ # Authentication components
│ │ ├── blog/ # Blog-specific components
│ │ └── layout/ # Layout components
│ ├── hooks/ # Custom React hooks
│ ├── services/ # API services
│ ├── types/ # TypeScript type definitions
│ ├── lib/ # Utility functions
│ └── data/ # Mock data
├── public/ # Static assets
└── package.json
Key Features Implementation
1. Authentication System
The authentication system uses React Auth Kit with custom hooks for a seamless user experience.
Type Definitions (src/types/auth.ts
):
export interface User {
id: string
email: string
name: string
avatar?: string
role: UserRole
createdAt: string
lastLoginAt?: string
}
export type UserRole = 'admin' | 'author' | 'reader'
export interface LoginCredentials {
email: string
password: string
rememberMe?: boolean
}
export interface RegisterCredentials {
email: string
password: string
confirmPassword: string
name: string
acceptTerms: boolean
}
Permission System:
export const PERMISSIONS = {
POSTS: {
CREATE: 'posts:create',
EDIT: 'posts:edit',
DELETE: 'posts:delete',
PUBLISH: 'posts:publish'
},
USERS: {
VIEW: 'users:view',
EDIT: 'users:edit',
DELETE: 'users:delete'
},
ADMIN: {
ACCESS: 'admin:access'
}
} as const
export const ROLE_PERMISSIONS: Record<UserRole, string[]> = {
admin: [
PERMISSIONS.POSTS.CREATE,
PERMISSIONS.POSTS.EDIT,
PERMISSIONS.POSTS.DELETE,
PERMISSIONS.POSTS.PUBLISH,
PERMISSIONS.USERS.VIEW,
PERMISSIONS.USERS.EDIT,
PERMISSIONS.USERS.DELETE,
PERMISSIONS.ADMIN.ACCESS
],
author: [
PERMISSIONS.POSTS.CREATE,
PERMISSIONS.POSTS.EDIT,
PERMISSIONS.POSTS.PUBLISH
],
reader: []
}
2. Blog Data Models
Blog Post Interface (src/types/blog.ts
):
export interface BlogPost {
id: string;
title: string;
content: string;
excerpt: string;
author: Author;
publishedAt: string;
updatedAt?: string;
tags: string[];
featuredImage?: string;
readingTime: number;
isPublished: boolean;
slug: string;
views?: number;
}
export interface Author {
id: string;
name: string;
email: string;
avatar?: string;
bio?: string;
social?: {
twitter?: string;
linkedin?: string;
github?: string;
};
}
3. Main Application Component
The main App.tsx
showcases the integration of all features:
import { useState, memo } from 'react'
import { AuthModal } from '@/components/auth/AuthModal'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { LoadingSpinner } from '@/components/ui/LoadingSpinner'
import { useAuth } from '@/hooks/useAuth'
import { useBlogData } from '@/hooks/useBlog'
export default memo(function App() {
const [authModalOpen, setAuthModalOpen] = useState(false)
const [authMode, setAuthMode] = useState<'login' | 'register'>('login')
const { isAuthenticated, isCheckingAuth, user, logout, isLoggingOut } = useAuth()
const { posts, authors, isLoading } = useBlogData()
// Component implementation...
})
4. Custom Hooks
Authentication Hook:
// Custom hook for authentication logic
const { isAuthenticated, isCheckingAuth, user, logout, isLoggingOut } = useAuth()
Blog Data Hook:
// Custom hook for blog data fetching with React Query
const { posts, authors, isLoading } = useBlogData()
UI Components
The project uses a comprehensive set of UI components:
- Authentication: Modal-based login/register forms
- Navigation: Responsive header with user status
- Cards: Blog post cards with hover effects
- Buttons: Various button variants and states
- Badges: Role indicators and tags
- Loading States: Spinners and skeleton loaders
Component Architecture
// Memoized component for performance
const AuthButtons = memo(function AuthButtons() {
if (isCheckingAuth) {
return <LoadingSpinner size="sm" />
}
if (isAuthenticated && user) {
return (
<div className="flex items-center gap-3">
<div className="flex items-center gap-2">
<User className="h-4 w-4" />
<span className="text-sm font-medium">{user.name}</span>
<Badge variant="secondary" className="text-xs">
{user.role}
</Badge>
</div>
{/* Logout and settings buttons */}
</div>
)
}
return (
<div className="flex items-center gap-2">
<Button variant="ghost" size="sm" onClick={handleLoginClick}>
Se connecter
</Button>
<Button variant="default" size="sm" onClick={handleRegisterClick}>
S'inscrire
</Button>
</div>
)
})
Getting Started
Prerequisites
- Node.js 18+
- pnpm (recommended package manager)
Installation
- Clone the repository:
git clone https://github.com/VincentCapek/blog-ts.git
cd blog-ts
pnpm install
- Development:
pnpm dev
- Build for production:
pnpm build
pnpm preview
Configuration
The project uses pnpm exclusively with these key scripts:
{
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
}
}
Key Dependencies
{
"dependencies": {
"react": "^19.1.0",
"react-dom": "^19.1.0",
"@tanstack/react-query": "^5.81.5",
"react-auth-kit": "^3.1.3",
"@tailwindcss/vite": "^4.1.11",
"tailwindcss": "^4.1.11",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-dialog": "^1.1.14",
"lucide-react": "^0.525.0",
"clsx": "^2.1.1",
"tailwind-merge": "^3.3.1"
}
}
Key Features Breakdown
Authentication Flow
- Modal-based auth – Clean UX with overlays
- Persistent sessions – Remember user login state
- Role-based UI – Different interfaces per user role
- Secure logout – Proper token cleanup
Blog Features
- Article listing – Grid layout with excerpts
- Author profiles – Author information display
- Tag system – Categorization and filtering
- Reading time – Calculated reading estimates
- Responsive design – Mobile-first approach
Developer Experience
- TypeScript strict mode – Maximum type safety
- ESLint configuration – Code quality enforcement
- Component organization – Clear separation of concerns
- Custom hooks – Reusable business logic
- Performance optimization – React.memo for components
Best Practices Implemented
React Patterns
-
Memoization with
React.memo
for performance - Custom hooks for business logic separation
- Compound components for complex UI elements
- Controlled components for form handling
TypeScript Excellence
-
Strict typing with no
any
types - Interface definitions for all data structures
- Type guards for runtime safety
- Generic components for reusability
Code Organization
- Feature-based structure – Components grouped by functionality
- Barrel exports – Clean import statements
- Consistent naming – Clear, descriptive names
- Separation of concerns – Logic, UI, and data layers
Future Enhancements
Planned features for the next iterations:
- Rich Text Editor – For creating and editing posts
- Comment System – User engagement features
- Search Functionality – Full-text search across posts
- Social Sharing – Share buttons for posts
- Admin Dashboard – Content management interface
- SEO Optimization – Meta tags and structured data
- Dark Mode – Theme switching capability
- Infinite Scroll – Performance optimization for large lists
Key Takeaways
This project demonstrates:
- Modern React development with the latest features
- Type-safe development with comprehensive TypeScript usage
- Component architecture with reusable, composable pieces
- Authentication patterns for real-world applications
- Performance optimization through memoization and code splitting
- User experience focus with loading states and responsive design
Contributing
The codebase is structured for easy contribution:
- Clear separation of UI, business logic, and data
- TypeScript interfaces for all contracts
- Consistent patterns throughout the application
- Comprehensive linting to maintain code quality
Resources
-
Project Repository – Complete source code
- React 19 Documentation
- TypeScript Handbook
- shadcn/ui Components
- Tailwind CSS
- React Query Guide
This blog platform showcases how modern web development tools can come together to create a robust, scalable, and maintainable application. The combination of React 19, TypeScript, and modern tooling provides an excellent foundation for building complex web applications.
This content originally appeared on DEV Community and was authored by A0mineTV