Portfolio Website
Create a professional portfolio website with animations, responsive design, and modern UI/UX
100 min•By Priygop Team•Last updated: Feb 2026
Portfolio Features
Example
// Portfolio website features
- Responsive design
- Smooth animations
- Project showcase
- Skills and experience
- Contact form
- Blog section
- Dark/light theme
- SEO optimization
- Performance optimization
// Portfolio structure
src/
├── components/
│ ├── layout/
│ │ ├── Header.js
│ │ ├── Footer.js
│ │ └── Navigation.js
│ ├── sections/
│ │ ├── Hero.js
│ │ ├── About.js
│ │ ├── Skills.js
│ │ ├── Projects.js
│ │ ├── Experience.js
│ │ ├── Contact.js
│ │ └── Blog.js
│ ├── ui/
│ │ ├── Button.js
│ │ ├── Card.js
│ │ ├── Modal.js
│ │ └── ThemeToggle.js
│ └── animations/
│ ├── FadeIn.js
│ ├── SlideIn.js
│ └── Parallax.js
├── pages/
│ ├── Home.js
│ ├── About.js
│ ├── Projects.js
│ ├── Blog.js
│ └── Contact.js
├── hooks/
│ ├── useScrollPosition.js
│ ├── useTheme.js
│ └── useIntersectionObserver.js
├── data/
│ ├── projects.js
│ ├── skills.js
│ ├── experience.js
│ └── blog-posts.js
└── styles/
├── globals.css
├── components.css
└── animations.cssModern UI Components
Example
// Modern portfolio components
import { motion } from 'framer-motion';
import { useState, useEffect } from 'react';
// Hero section with animations
function Hero() {
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
useEffect(() => {
const handleMouseMove = (e) => {
setMousePosition({ x: e.clientX, y: e.clientY });
};
window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
}, []);
return (
<motion.section
className="hero"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1 }}
>
<motion.div
className="hero-content"
initial={{ y: 100, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.8, delay: 0.2 }}
>
<motion.h1
initial={{ scale: 0.8 }}
animate={{ scale: 1 }}
transition={{ duration: 0.5, delay: 0.5 }}
>
Hi, I'm <span className="highlight">Your Name</span>
</motion.h1>
<motion.p
initial={{ y: 50, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.8, delay: 0.7 }}
>
Full-Stack Developer & UI/UX Designer
</motion.p>
<motion.div
className="hero-buttons"
initial={{ y: 50, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.8, delay: 0.9 }}
>
<Button variant="primary">View Projects</Button>
<Button variant="secondary">Contact Me</Button>
</motion.div>
</motion.div>
<motion.div
className="floating-elements"
animate={{
x: mousePosition.x * 0.01,
y: mousePosition.y * 0.01,
}}
transition={{ type: "spring", stiffness: 50 }}
>
<div className="floating-shape shape-1"></div>
<div className="floating-shape shape-2"></div>
<div className="floating-shape shape-3"></div>
</motion.div>
</motion.section>
);
}
// Project showcase with filters
function Projects() {
const [filter, setFilter] = useState('all');
const [projects, setProjects] = useState([]);
const categories = ['all', 'web', 'mobile', 'design', 'other'];
const filteredProjects = projects.filter(project =>
filter === 'all' || project.category === filter
);
return (
<section className="projects">
<motion.h2
initial={{ opacity: 0, y: 50 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
>
My Projects
</motion.h2>
<div className="filter-buttons">
{categories.map(category => (
<motion.button
key={category}
onClick={() => setFilter(category)}
className={`filter-btn ${filter === category ? 'active' : ''}`}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
{category.charAt(0).toUpperCase() + category.slice(1)}
</motion.button>
))}
</div>
<motion.div
className="projects-grid"
layout
>
{filteredProjects.map((project, index) => (
<motion.div
key={project.id}
layout
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.8 }}
transition={{ duration: 0.3, delay: index * 0.1 }}
whileHover={{ y: -10 }}
>
<ProjectCard project={project} />
</motion.div>
))}
</motion.div>
</section>
);
}
// Project card component
function ProjectCard({ project }) {
const [isHovered, setIsHovered] = useState(false);
return (
<motion.div
className="project-card"
onHoverStart={() => setIsHovered(true)}
onHoverEnd={() => setIsHovered(false)}
whileHover={{ scale: 1.02 }}
>
<div className="project-image">
<img src={project.image} alt={project.title} />
<motion.div
className="project-overlay"
initial={{ opacity: 0 }}
animate={{ opacity: isHovered ? 1 : 0 }}
transition={{ duration: 0.3 }}
>
<div className="project-links">
<a href={project.liveUrl} target="_blank" rel="noopener">
Live Demo
</a>
<a href={project.githubUrl} target="_blank" rel="noopener">
GitHub
</a>
</div>
</motion.div>
</div>
<div className="project-content">
<h3>{project.title}</h3>
<p>{project.description}</p>
<div className="project-tech">
{project.technologies.map(tech => (
<span key={tech} className="tech-tag">{tech}</span>
))}
</div>
</div>
</motion.div>
);
}
// Skills section with progress bars
function Skills() {
const skills = [
{ name: 'React', level: 90 },
{ name: 'JavaScript', level: 85 },
{ name: 'Node.js', level: 80 },
{ name: 'Python', level: 75 },
{ name: 'CSS/SASS', level: 88 },
{ name: 'TypeScript', level: 70 },
];
return (
<section className="skills">
<motion.h2
initial={{ opacity: 0, y: 50 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
>
Skills & Technologies
</motion.h2>
<div className="skills-grid">
{skills.map((skill, index) => (
<motion.div
key={skill.name}
className="skill-item"
initial={{ opacity: 0, x: -50 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.6, delay: index * 0.1 }}
>
<div className="skill-header">
<h3>{skill.name}</h3>
<span>{skill.level}%</span>
</div>
<div className="skill-bar">
<motion.div
className="skill-progress"
initial={{ width: 0 }}
whileInView={{ width: `${skill.level}%` }}
transition={{ duration: 1, delay: 0.2 }}
/>
</div>
</motion.div>
))}
</div>
</section>
);
}