A personal portfolio and technical blog built with React, TypeScript, and Vite.
- Professional Portfolio: Showcases experience, education, skills, and achievements
- Technical Blog: In-depth articles on various technologies (NestJS, GraphQL, React, etc.)
- Modern UI: Clean, responsive design using Material UI
- Performance Optimized: Implements code splitting, lazy loading, and optimized bundling
- SEO Friendly: Schema.org structured data and meta tags for better search engine visibility
graph LR
subgraph Client["Client Layer"]
Browser["Web Browser"]
end
subgraph Delivery["Content Delivery"]
CF["Cloudflare CDN<br/>Edge Caching"]
end
subgraph Origin["Origin Layer"]
S3["AWS S3<br/>Static Hosting"]
end
Browser <--> |"HTTPS"| CF
CF <--> |"Origin Pulls"| S3
graph TB
subgraph App["React Application"]
Entry["Entry Point<br/>main.tsx"]
subgraph Core["Core Infrastructure"]
direction LR
Router["React Router<br/>Route Management"]
ErrorBoundary["Error Boundary<br/>Global Error Handling"]
CodeSplit["Code Splitting<br/>Lazy Loading"]
end
subgraph State["Global State"]
direction LR
Theme["Theme Context<br/>Dark/Light Mode"]
Bookmarks["Bookmarks Context<br/>Article Management"]
end
subgraph Pages["Content Layer"]
direction LR
Home["Home Page<br/>Portfolio"]
Blog["Blog Posts<br/>Technical Articles"]
NotFound["404 Page<br/>Error Handling"]
end
Entry --> Core
Core --> State
Core --> Pages
State --> Pages
end
The first diagram shows how user requests flow through the system. The second diagram shows how the React application is organized internally.
- React with TypeScript
- Vite for fast builds and development
- Material UI for component styling
- React Router for navigation
- React Helmet for document head management
- React Schema.org for structured data
- Marked for markdown rendering
- React Syntax Highlighter for code blocks
- Node.js
- npm or yarn
-
Clone the repository:
git clone https://github.com/yourname/rayperez-site.git cd rayperez-site -
Install dependencies:
npm install # or yarn -
Start the development server:
npm run dev # or yarn dev -
Open http://localhost:5173 in your browser
rayperez-site/
βββ dist/ # Production build output
βββ public/ # Static assets served as-is
βββ src/
β βββ assets/ # Images and project assets
β βββ components/ # Reusable UI components
β βββ constants/ # App constants and configuration
β βββ contexts/ # React contexts (theme, bookmarks)
β βββ data/
β β βββ articles/ # JSON-driven article content
β β βββ content/ # Structured site content (profile, projects, experiences, etc.)
β βββ hooks/ # Custom React hooks
β βββ img/ # Legacy/static images
β βββ pages/
β β βββ articles/ # Blog article page wrappers
β βββ test-utils/ # Testing helpers and providers
β βββ types/ # Shared TypeScript types
β βββ utils/ # Utility functions
β βββ App.tsx # Main app component
β βββ main.tsx # Application entry point
β βββ setupTests.ts # Vitest + RTL setup
β βββ vite-env.d.ts # Vite TS types
βββ scripts/ # Build/automation scripts
βββ docs/ # Documentation and ADRs
βββ infrastructure/ # Terraform/infra as code
βββ coverage/ # Test coverage reports
βββ index.html # Root HTML template
βββ package.json # Scripts and dependencies
βββ tsconfig.json # TypeScript configuration
βββ vite.config.ts # Vite configuration
βββ vitest.config.ts # Vitest configuration
βββ CONTRIBUTING.md # Contributing guidelines
βββ CHANGELOG.md # Changelog
βββ LICENSE # License
βββ README.md # Project overview
npm run dev- Start development servernpm run build- Build for productionnpm run preview- Preview production buildnpm run lint- Run ESLintnpm run format- Format code with Prettier
This project uses ESLint and Prettier for code quality and formatting:
# Format all files
npm run format
# Lint check
npm run lintThis project enforces a minimum 70% code coverage threshold. Tests are run using Vitest and React Testing Library.
To run tests:
npm testTo run tests with coverage:
npm run test:coverage-
Create a production build:
npm run build
-
The build output will be in the
distdirectory, which can be deployed to any static hosting service like:- Netlify
- Vercel
- GitHub Pages
- AWS S3
- Code Splitting: All article pages are lazy-loaded
- Bundle Optimization: Manual chunk splitting in Vite config
- Preloading: Strategic preloading of important routes
- Tree Shaking: Dead code elimination in production builds
- Article content lives in
src/data/articles/*.jsonand followsArticleDocumentschema. - Pages import JSON and render via
JsonBlogPost, which usesArticleRenderer. - Example:
import JsonBlogPost from '../../components/JsonBlogPost'
import { ArticleDocument } from '../../types/articleContent'
import content from '../../data/articles/WhyReactJS.json'
export default function WhyReactJS() {
return (
<JsonBlogPost
title='Why I Choose React'
author='Raymond Perez'
date='2024-07-04'
content={content as ArticleDocument}
/>
)
}Site content (profile, projects, achievements, experiences, education) is stored in structured JSON files in src/data/content/. These files serve as the source of truth for site content and are:
- Version-controlled: All content changes are tracked in Git
- Type-safe: Validated against TypeScript interfaces in
src/types/contentData.ts - Automatically validated: CI pipeline runs validation tests on every push and pull request
- Consistently consumed: Components read directly from these files
For detailed workflow instructions on updating content data, see the Content Flow section in CONTRIBUTING.md.
- Structured Data: Schema.org markup for better search indexing
- Meta Tags:
SocialMetaafter load; static shells from the route HTML build step - Canonical URLs: Static canonical in built HTML; client canonical via
WithCanonical - Route HTML: See docs/static-route-html.md
This project is licensed under the MIT License - see the LICENSE file for details.
- Contributing Guidelines - How to contribute to the project
- Release Process - Release workflow and versioning
- Static route HTML - Crawler shells, meta tags, and deploy order for canonical URLs
- Client route meta - SPA navigation,
SocialMeta, and in-place head updates - Page sections and skeletons - Section styles, type scale, and route loading placeholders
Raymond Perez:
.