DEV Community

A0mineTV
A0mineTV

Posted on

Building a Modern Blog Platform with React 19, TypeScript, and shadcn/ui

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
Enter fullscreen mode Exit fullscreen mode

🔧 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
}
Enter fullscreen mode Exit fullscreen mode

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: []
}
Enter fullscreen mode Exit fullscreen mode

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;
  };
}
Enter fullscreen mode Exit fullscreen mode

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...
})
Enter fullscreen mode Exit fullscreen mode

4. Custom Hooks

Authentication Hook:

// Custom hook for authentication logic
const { isAuthenticated, isCheckingAuth, user, logout, isLoggingOut } = useAuth()
Enter fullscreen mode Exit fullscreen mode

Blog Data Hook:

// Custom hook for blog data fetching with React Query
const { posts, authors, isLoading } = useBlogData()
Enter fullscreen mode Exit fullscreen mode

🎨 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>
  )
})
Enter fullscreen mode Exit fullscreen mode

🚀 Getting Started

Prerequisites

  • Node.js 18+
  • pnpm (recommended package manager)

Installation

  1. Clone the repository:
git clone https://github.com/VincentCapek/blog-ts.git
cd blog-ts
pnpm install
Enter fullscreen mode Exit fullscreen mode
  1. Development:
pnpm dev
Enter fullscreen mode Exit fullscreen mode
  1. Build for production:
pnpm build
pnpm preview
Enter fullscreen mode Exit fullscreen mode

Configuration

The project uses pnpm exclusively with these key scripts:

{
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "lint": "eslint .",
    "preview": "vite preview"
  }
}
Enter fullscreen mode Exit fullscreen mode

📦 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"
  }
}
Enter fullscreen mode Exit fullscreen mode

🔑 Key Features Breakdown

Authentication Flow

  1. Modal-based auth - Clean UX with overlays
  2. Persistent sessions - Remember user login state
  3. Role-based UI - Different interfaces per user role
  4. Secure logout - Proper token cleanup

Blog Features

  1. Article listing - Grid layout with excerpts
  2. Author profiles - Author information display
  3. Tag system - Categorization and filtering
  4. Reading time - Calculated reading estimates
  5. Responsive design - Mobile-first approach

Developer Experience

  1. TypeScript strict mode - Maximum type safety
  2. ESLint configuration - Code quality enforcement
  3. Component organization - Clear separation of concerns
  4. Custom hooks - Reusable business logic
  5. 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:

  1. Rich Text Editor - For creating and editing posts
  2. Comment System - User engagement features
  3. Search Functionality - Full-text search across posts
  4. Social Sharing - Share buttons for posts
  5. Admin Dashboard - Content management interface
  6. SEO Optimization - Meta tags and structured data
  7. Dark Mode - Theme switching capability
  8. 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:

  1. Clear separation of UI, business logic, and data
  2. TypeScript interfaces for all contracts
  3. Consistent patterns throughout the application
  4. Comprehensive linting to maintain code quality

📚 Resources


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.

Top comments (0)