A cutting-edge, high-performance personal portfolio and blog built with Astro 5.9, React 18, TailwindCSS 3.4, and MDX. This project represents a complete architectural migration from Next.js to Astro, delivering superior performance while maintaining all functionality and visual fidelity with 2025 web design standards.
π Live Demo: https://febryan.web.id π Performance: Optimized for speed and user experience β‘ Build Time: < 30 seconds π¦ Bundle Size: < 500KB (gzipped) π¨ Design: 2025 Modern Web Standards with Motion Design π§ Architecture: Static Site Generation with Islands Architecture βοΈ Hosting: Cloudflare Pages with global CDN
This portfolio showcases modern web development practices with a focus on:
- Performance-First Architecture: Static site generation with selective hydration using Astro's Islands Architecture
- 2025 Design Standards: Modern UI/UX with micro-interactions, motion design, and storytelling elements
- Developer Experience: TypeScript, hot reload, component-driven development with excellent DX
- Content Management: MDX-powered blog with advanced features, syntax highlighting, and rich content
- Accessibility: WCAG 2.1 AA compliant with semantic HTML and proper ARIA attributes
- SEO Optimization: Structured data, dynamic meta tags, Open Graph, and automatic sitemap generation
- Progressive Enhancement: Works without JavaScript, enhanced with React components where needed
- π Advanced dark/light mode with smooth transitions and persistent theme storage
- π± Fully responsive design optimized for all devices with mobile-first approach
- π Styled with TailwindCSS 3.4 and custom components following 2025 design trends
- π Lightning-fast page loads with Astro's static site generation and Islands Architecture
- β¨ Smooth micro-interactions and motion design with Framer Motion
- π― Intelligent floating navigation with active section detection and smooth scrolling
- π Storytelling elements with emotional connections through motion design
- π¨ Modern UI components with proper visual hierarchy and spacing
- π Configurable sections that can be enabled/disabled per user preferences
- π MDX blog support with rich content and React component integration
- π¨ Advanced syntax highlighting for code blocks with Shiki and custom themes
- π Copy code buttons with improved UX and mobile touch support
- π Powerful blog search functionality with real-time filtering
- π·οΈ Tag-based blog filtering with dedicated tag pages
- π Accurate reading time estimation with code block consideration
- π Blog statistics and metadata with configurable display
- π Social sharing buttons with Open Graph optimization
- π Table of Contents (TOC) with auto-scroll and active section highlighting
- ποΈ Archive page with chronological organization
- π Pagination with SEO-friendly URLs
- β‘ Built with Astro 5.9 for optimal performance and modern architecture
- π§ Full TypeScript support for type safety and better developer experience
- π¦ Component-based architecture with reusable React components
- π― Advanced SEO optimization with structured data, JSON-LD, and dynamic meta tags
- πΊοΈ Automatic sitemap generation with proper priority and change frequency
- π± Progressive Web App (PWA) ready with service worker and manifest
- π Security headers configured for production deployment
- π Optimized build process with code splitting and asset optimization
- π Performance monitoring with Core Web Vitals optimization
- π Hot module replacement for instant development feedback
- Node.js: 18.0.0 or higher (LTS recommended)
- Package Manager: npm (included with Node.js), yarn, or pnpm
- Git: For version control and cloning the repository
# Clone the repository
git clone https://github.com/Pepryan/astro-portfolio.git
cd astro-portfolio
# Install dependencies
npm install
# or with yarn
yarn install
# or with pnpm
pnpm install
# Start development server
npm run dev
# Server will start at http://localhost:4321
# Build for production
npm run build
# Preview production build locally
npm run preview
# Deploy to GitHub Pages (if configured)
npm run deploy# Development server with hot reload
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview
# Type checking
npx astro check
# Format code
npx prettier --write .
# Lint code
npx eslint . --fixastro-portfolio/
βββ src/
β βββ components/ # React components
β β βββ About.tsx # About section component
β β βββ BlogCard.tsx # Blog post card component
β β βββ BlogPostLayout.tsx # Blog post layout wrapper
β β βββ CareerSection.tsx # Experience and education
β β βββ Contact.tsx # Contact section
β β βββ CopyCodeScript.astro # Code copy functionality
β β βββ CustomHead.astro # SEO and meta tags
β β βββ Footer.tsx # Site footer
β β βββ Header.tsx # Navigation header
β β βββ Hero.tsx # Hero section
β β βββ LayoutWrapper.tsx # Main layout wrapper
β β βββ PortfolioSection.tsx # Projects showcase
β β βββ SearchModal.tsx # Blog search functionality
β β βββ TableOfContents.tsx # TOC for blog posts
β β βββ ThemeProvider.tsx # Dark/light theme management
β β βββ ThemeToggle.tsx # Theme switch component
β βββ content/ # Content collections
β β βββ config.ts # Content schema definitions
β β βββ posts/ # Blog posts (.mdx files)
β β βββ cloud-native-architecture-guide.mdx
β β βββ modern-web-development-2025.mdx
β β βββ react-performance-optimization.mdx
β βββ layouts/ # Astro layouts
β β βββ Layout.astro # Base layout with SEO
β βββ pages/ # File-based routing
β β βββ index.astro # Homepage
β β βββ 404.astro # Custom 404 page
β β βββ archive.astro # Blog archive page
β β βββ rss.xml.ts # RSS feed generation
β β βββ blog/ # Blog routing
β β βββ index.astro # Blog listing page
β β βββ [...slug].astro # Dynamic blog post pages
β β βββ tags/ # Tag-based filtering
β β βββ index.astro # All tags page
β β βββ [tag].astro # Posts by tag
β βββ styles/ # Global styles
β β βββ globals.css # TailwindCSS base styles
β βββ utils/ # Utility functions
β β βββ readingTime.ts # Reading time calculation
β β βββ seo.ts # SEO utilities
β βββ config/ # Configuration files
β βββ components.ts # Site configuration
βββ public/ # Static assets
β βββ images/ # Image assets
β β βββ default-og-image.webp # Default Open Graph image
β β βββ default-og-image.svg # SVG version
β β βββ preview.webp # Portfolio preview
β βββ documents/ # Downloadable files
β βββ favicon.ico # Site favicon
β βββ robots.txt # Search engine directives
β βββ site.webmanifest # PWA manifest
βββ netlify.toml # Legacy deployment config (optional)
βββ astro.config.mjs # Astro configuration
βββ tailwind.config.mjs # TailwindCSS configuration
βββ tsconfig.json # TypeScript configuration
βββ package.json # Dependencies and scripts
The main configuration file src/config/components.ts contains all customizable settings:
export const seoConfig = {
site: {
name: "Your Portfolio Name",
title: "Your Title - Your Profession",
description: "Your description",
url: "https://yourdomain.com",
language: "en",
locale: "en_US"
},
author: {
name: "Your Name",
email: "your.email@example.com",
url: "https://yourdomain.com",
jobTitle: "Your Job Title",
location: "Your Location"
}
}- Hero Section: Personal introduction and call-to-action
- About Section: Detailed personal story and background
- Experience: Work history with responsibilities and technologies
- Education: Academic background and certifications
- Skills: Technical skills organized by categories
- Projects: Portfolio items with links and descriptions
- Contact: Contact information and social media links
- Homepage Layout: Choose between traditional or 2025 modern design
- Section Visibility: Enable/disable sections as needed
- Navigation: Configure floating navigation and header options
- Theme: Customize colors, fonts, and spacing
// tailwind.config.mjs
export default {
theme: {
extend: {
colors: {
primary: '#3b82f6',
secondary: '#64748b'
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif']
}
}
}
}- Base Styles:
src/styles/globals.css - Component Styles: Individual component files using TailwindCSS classes
- Dark Mode: Automatic dark mode support with
dark:prefixes - Custom CSS: Add custom styles in the globals.css file
Create new blog posts by adding .mdx files to src/content/posts/:
---
title: "Your Post Title"
date: "2025-01-01"
summary: "Brief description of your post"
tags: ["tag1", "tag2", "tag3"]
category: "Technology"
author: "Your Name"
draft: false
image: "/images/post-image.jpg" # Optional
---
# Your Content Here
Write your blog post content using Markdown and MDX syntax.
You can include React components and interactive elements.- Images: Store in
public/images/directory - Documents: Store downloadable files in
public/documents/ - Favicons: Replace favicon files in
public/directory - Manifest: Update
public/site.webmanifestfor PWA settings
Create new blog posts by adding .mdx files to src/content/posts/:
---
title: "Your Post Title"
date: "2025-01-01"
summary: "Brief description of your post"
tags: ["tag1", "tag2", "tag3"]
category: "Technology"
author: "Your Name"
draft: false
hidden: false
image: "/images/post-cover.jpg"
imageAlt: "Description of the image"
readingTime: 5 # Optional, auto-calculated if not provided
featured: true # Show in featured posts
seo:
title: "Custom SEO Title"
description: "Custom meta description"
keywords: ["keyword1", "keyword2"]
openGraph:
title: "Custom OG Title"
description: "Custom OG description"
type: "article"
twitter:
card: "summary_large_image"
title: "Custom Twitter Title"
description: "Custom Twitter description"
schema:
type: "BlogPosting"
author:
name: "Your Name"
url: "https://yourdomain.com"
publisher:
name: "Your Blog"
url: "https://yourdomain.com"
---
# Your Content Here
Write your blog post content using **Markdown** and **MDX** syntax.
## Code Blocks with Syntax Highlighting
```javascript
// JavaScript example with syntax highlighting
function greet(name) {
console.log(`Hello, ${name}!`);
}
greet('World');You can include React components directly in your MDX:
- β Automatic table of contents generation
- β Reading time estimation
- β Code copy buttons
- β Social sharing
- β SEO optimization
- β Related posts suggestions
### Blog Configuration
#### **Content Schema**
The blog uses Astro's content collections with TypeScript schemas for validation:
```typescript
// src/content/config.ts
const postsCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
date: z.date(),
summary: z.string(),
tags: z.array(z.string()),
category: z.string(),
author: z.string(),
draft: z.boolean().default(false),
hidden: z.boolean().default(false),
image: z.string().optional(),
featured: z.boolean().default(false)
})
});
- Search: Real-time search across all posts
- Filtering: Filter by tags, categories, or date
- Pagination: Configurable posts per page
- Archive: Chronological organization by year/month
- RSS Feed: Automatic RSS feed generation at
/rss.xml - Sitemap: Automatic sitemap generation for SEO
- Connect Repository: Link your GitHub repository to Cloudflare Pages
- Build Settings:
- Build command:
npm run build - Build output directory:
dist - Node.js version:
18or higher - Environment variables: Set
NODE_ENV=production
- Build command:
- Deploy: Automatic deployment on push to main branch
- Custom Domain: Configure your custom domain in Cloudflare Pages settings
- Global CDN: Benefit from Cloudflare's worldwide edge network
- Performance: Enhanced caching and compression automatically applied
- Security: Built-in DDoS protection and SSL certificates
# Install Wrangler CLI
npm install -g wrangler
# Build the project
npm run build
# Deploy to Cloudflare Pages
wrangler pages deploy dist# Install Netlify CLI
npm install -g netlify-cli
# Build the project
npm run build
# Deploy to Netlify
netlify deploy --prod --dir=dist# Install Vercel CLI
npm install -g vercel
# Deploy to Vercel
vercel --prod# Build and deploy to GitHub Pages
npm run deploy
# This command:
# 1. Builds the project
# 2. Creates .nojekyll file
# 3. Deploys to gh-pages branch# Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]# Build the project
npm run build
# Upload the `dist/` folder to your hosting provider
# The dist folder contains all static files ready for deploymentFor production deployment, configure these environment variables:
- Build command:
npm run build - Build output directory:
dist - Node.js version:
18 - Environment variables:
NODE_ENV:productionSITE_URL:https://febryan.web.id
SITE_URL: Your production domain (e.g., https://febryan.web.id)NODE_ENV: Set to "production"BUILD_COMMAND: "npm run build"PUBLISH_DIRECTORY: "dist"
The portfolio features a comprehensive, custom sitemap implementation that automatically excludes draft posts and includes proper SEO metadata:
- Automatic Draft Filtering: Only published posts (non-draft, non-hidden) are included
- Enhanced Metadata: Includes
lastmod,changefreq, andpriorityfor better SEO - Comprehensive Coverage: All pages, blog posts, tag pages, and static routes
- Proper URL Structure: Clean, SEO-friendly URLs with correct encoding
- Sitemap Index: Organized structure for better search engine crawling
/sitemap-index.xml- Main sitemap index/sitemap.xml- Complete sitemap with all URLs and metadata
- Homepage: 1.0 (highest priority, weekly updates)
- Blog listing: 0.9 (high priority, daily updates)
- Projects: 0.8 (high priority, weekly updates)
- Archive: 0.7 (medium priority, weekly updates)
- Blog posts: 0.7 (medium priority, monthly updates)
- Contact/About: 0.6/0.5 (lower priority, monthly updates)
- Tag pages: 0.5 (medium priority, weekly updates)
src/utils/sitemap.ts- Sitemap generation utilitiessrc/pages/sitemap.xml.ts- Main sitemap endpointsrc/pages/sitemap-index.xml.ts- Sitemap index endpointpublic/robots.txt- Updated with correct sitemap referencesscripts/validate-sitemap.js- Validation script for sitemap integrity
# Validate sitemap after build
npm run validate-sitemap
# Build and validate in one command
npm run build:validate- Better Crawling: Search engines can efficiently discover all pages
- Fresh Content: Automatic lastmod dates help search engines prioritize recent content
- Priority Signals: Clear priority hierarchy guides search engine focus
- Clean Structure: No draft/hidden content cluttering search results
The astro.config.mjs file includes comprehensive settings:
export default defineConfig({
site: 'https://febryan.web.id',
output: 'static',
integrations: [
mdx({
remarkPlugins: [remarkGfm],
rehypePlugins: [
[rehypePrettyCode, {
theme: 'night-owl',
keepBackground: true,
defaultLang: 'plaintext',
grid: true
}]
],
syntaxHighlight: false
}),
react(),
tailwind({ applyBaseStyles: false })
// Custom sitemap implementation in src/pages/sitemap.xml.ts
]
});- MDX Support: Rich content with React components
- Syntax Highlighting: Shiki-powered code highlighting with night-owl theme
- React Integration: Interactive components where needed
- TailwindCSS: Utility-first CSS framework
- Sitemap Generation: Automatic SEO-friendly sitemap
- Static Generation: Optimal performance with pre-rendered pages
Blog posts use Astro's content collections with TypeScript schemas:
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const postsCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
date: z.date(),
summary: z.string(),
tags: z.array(z.string()),
category: z.string(),
author: z.string(),
draft: z.boolean().default(false),
hidden: z.boolean().default(false),
image: z.string().optional(),
imageAlt: z.string().optional(),
featured: z.boolean().default(false)
})
});
export const collections = {
posts: postsCollection
};{
"extends": "astro/tsconfigs/strict",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@/components/*": ["./src/components/*"],
"@/utils/*": ["./src/utils/*"],
"@/config/*": ["./src/config/*"]
}
}
}- β‘ Lighthouse Scores: Optimized for real-world performance
- Performance: 85-95/100 (varies by content and network)
- Accessibility: 95-100/100
- Best Practices: 90-100/100
- SEO: 95-100/100
- π Loading Times:
- First Contentful Paint (FCP): < 1.5s
- Largest Contentful Paint (LCP): < 3.0s
- First Input Delay (FID): < 100ms
- Cumulative Layout Shift (CLS): < 0.1
- π¦ Bundle Size: < 500KB (gzipped)
- β‘ Build Time: < 30 seconds
- π Time to Interactive (TTI): < 4s
- βοΈ CDN Performance: Global edge caching with Cloudflare
- π― Structured Data: JSON-LD schema markup for rich snippets
- π± Mobile-First: Responsive design optimized for all devices
- π Meta Tags: Dynamic meta tags for each page
- π Open Graph: Social media preview optimization
- π¦ Twitter Cards: Enhanced Twitter sharing
- πΊοΈ Sitemap: Automatic XML sitemap generation
- π€ Robots.txt: Search engine crawling directives
- π Canonical URLs: Proper URL canonicalization
- π Internal Linking: Strategic internal link structure
- βοΈ CDN SEO: Enhanced by Cloudflare's global network for faster indexing
β
LCP: 1.5-2.5s (Good: < 2.5s)
β
FID: 50-80ms (Good: < 100ms)
β
CLS: 0.05-0.08 (Good: < 0.1)
β
TTFB: 200-400ms (Good: < 600ms) - Enhanced by Cloudflare CDN
β
FCP: 1.0-1.5s (Good: < 1.8s)
- βΏ WCAG 2.1 AA Compliant: Full accessibility compliance
- β¨οΈ Keyboard Navigation: Complete keyboard accessibility
- π Screen Reader Support: Proper ARIA labels and semantic HTML
- π¨ Color Contrast: WCAG AA color contrast ratios
- π Focus Management: Visible focus indicators
- π± Touch Targets: Minimum 44px touch targets for mobile
- Framework: Astro 5.9 - Modern static site generator
- UI Library: React 18 - Component-based UI
- Styling: TailwindCSS 3.4 - Utility-first CSS
- Content: MDX - Markdown with React components
- Animations: Framer Motion - Motion library
- Icons: React Icons - Icon library
- Syntax Highlighting: Shiki - Code highlighting
- Typography: Tailwind Typography - Prose styling
- Language: TypeScript - Type safety
# 1. Clone and setup
git clone https://github.com/Pepryan/astro-portfolio.git
cd astro-portfolio
npm install
# 2. Start development
npm run dev
# 3. Make changes and test
npm run build
npm run preview
# 4. Deploy
git add .
git commit -m "Your changes"
git push origin main- TypeScript: Full type safety with strict mode
- ESLint: Code linting with Astro and React rules
- Prettier: Code formatting with consistent style
- Husky: Git hooks for pre-commit checks
- Commitlint: Conventional commit messages
We welcome contributions! Here's how to get started:
- Fork the repository on GitHub
- Clone your fork locally
- Create a feature branch (
git checkout -b feature/amazing-feature) - Install dependencies (
npm install) - Start development server (
npm run dev)
- Make your changes following the existing code style
- Test your changes thoroughly
- Build the project (
npm run build) - Preview the production build (
npm run preview) - Commit your changes with conventional commit format
- Push to your feature branch (
git push origin feature/amazing-feature) - Create a Pull Request with a clear description
- Wait for review and address any feedback
- Follow the existing code style and conventions
- Write clear, descriptive commit messages
- Test your changes on multiple devices and browsers
- Update documentation if needed
- Be respectful and constructive in discussions
This project is licensed under the MIT License - see the LICENSE file for details.
- β Commercial use allowed
- β Modification allowed
- β Distribution allowed
- β Private use allowed
- β No warranty provided
- β No liability accepted
Febryan Ramadhan
- π Website: https://febryan.web.id
- πΌ GitHub: @Pepryan
- π LinkedIn: febryanramadhan
- π¦ Twitter: @pepryan
- π§ Email: febryanramadhan@gmail.com
Cloud Engineer & DevOps Specialist based in Bogor, Indonesia. Passionate about building scalable, reliable systems and sharing knowledge through open-source projects and technical writing.
- Astro - The web framework for content-driven websites
- React - A JavaScript library for building user interfaces
- TailwindCSS - A utility-first CSS framework
- TypeScript - JavaScript with syntax for types
- Framer Motion - A production-ready motion library for React
- MDX - Markdown for the component era
- Shiki - A beautiful syntax highlighter
- Modern web design trends and 2025 standards
- Accessibility-first development practices
- Performance optimization techniques
- Developer experience improvements
- Cloudflare Pages for reliable hosting and global CDN
- Astro community for excellent documentation and support
- Open-source contributors who make projects like this possible
- Web development community for sharing knowledge and best practices
If you found this project helpful, please consider:
- β Starring the repository on GitHub
- π Reporting any bugs or issues
- π‘ Suggesting new features or improvements
- π Sharing the project with others
- π Contributing to the codebase
Made with β€οΈ by Febryan Ramadhan
