| name | figma-portfolio-nextjs |
| description | Build and customize a modern developer/designer portfolio with Next.js, TypeScript, and TailwindCSS featuring animated typing effects and responsive layouts. |
| triggers | ["create a portfolio website","build a developer portfolio with nextjs","customize figma portfolio template","add projects to portfolio site","setup personal portfolio with tailwind","configure nextjs portfolio animations","deploy portfolio to vercel","modify portfolio hero section"] |
Figma Portfolio - Next.js Developer Portfolio
Skill by ara.so — Design Skills collection.
A personal portfolio template for developers and designers, built with Next.js 16, TypeScript, and TailwindCSS. Features a clean dark-themed UI with purple gradient accents, animated typing effects, responsive layouts, and sections to showcase projects, experience, and creative skills.
Installation
git clone git@github.com:ibrahimmemonn/Figma_Portfolio.git
cd Figma_Portfolio/
npm install
npm run dev
The development server starts at http://localhost:3000.
Project Structure
Figma_Portfolio/
├── app/
│ ├── page.tsx # Main landing page
│ ├── layout.tsx # Root layout with font config
│ └── globals.css # Global styles with Tailwind
├── components/
│ ├── Hero.tsx # Hero section with typing animation
│ ├── Projects.tsx # Project showcase section
│ ├── Experience.tsx # Experience timeline
│ ├── Skills.tsx # Skills display
│ └── Contact.tsx # Contact section
├── public/
│ ├── projects/ # Project images
│ └── assets/ # Icons and media
└── tailwind.config.ts # Tailwind configuration
Key Features & Configuration
Font Configuration
The portfolio uses Poppins font optimized with next/font:
import { Poppins } from 'next/font/google';
const poppins = Poppins({
subsets: ['latin'],
weight: ['300', '400', '500', '600', '700', '800', '900'],
variable: '--font-poppins',
});
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en" className={poppins.variable}>
<body>{children}</body>
</html>
);
}
Hero Section with Typing Animation
'use client';
import { useState, useEffect } from 'react';
export default function Hero() {
const [text, setText] = useState('');
const [isDeleting, setIsDeleting] = useState(false);
const [loopNum, setLoopNum] = useState(0);
const [typingSpeed, setTypingSpeed] = useState(150);
const roles = ['Software Engineer', 'UI/UX Designer', 'Full Stack Developer'];
useEffect(() => {
const handleType = () => {
const i = loopNum % roles.length;
const fullText = roles[i];
setText(
isDeleting
? fullText.substring(0, text.length - 1)
: fullText.substring(0, text.length + 1)
);
setTypingSpeed(isDeleting ? 50 : 150);
if (!isDeleting && text === fullText) {
setTimeout(() => (), );
} (isDeleting && text === ) {
();
(loopNum + );
}
};
timer = (handleType, typingSpeed);
(timer);
}, [text, isDeleting, loopNum, typingSpeed, roles]);
(
);
}
Adding Projects
interface Project {
title: string;
description: string;
image: string;
link: string;
github?: string;
tags: string[];
}
const projects: Project[] = [
{
title: 'E-Commerce Platform',
description: 'Full-stack e-commerce solution with Next.js, Stripe, and MongoDB',
image: '/projects/ecommerce.png',
link: 'https://example.com',
github: 'https://github.com/username/project',
tags: ['Next.js', 'TypeScript', 'Stripe', 'MongoDB'],
},
{
title: 'Portfolio Dashboard',
description: 'Analytics dashboard for tracking portfolio metrics',
image: '/projects/dashboard.png',
link: 'https://example.com',
tags: ['React', 'Chart.js', 'TailwindCSS'],
},
];
export default function Projects() {
return (
);
}
Customizing Theme Colors
import type { Config } from 'tailwindcss';
const config: Config = {
content: [
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
'./app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {
colors: {
primary: {
50: '#faf5ff',
100: '#f3e8ff',
500: '#a855f7',
600: '#9333ea',
700: '#7e22ce',
},
},
backgroundImage: {
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
},
},
},
plugins: [],
};
export default config;
Adding Analytics
import { Analytics } from '@vercel/analytics/react';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
{children}
<Analytics />
</body>
</html>
);
}
Deployment
Deploy to Vercel
npm i -g vercel
vercel
vercel --prod
Or connect your GitHub repository to Vercel for automatic deployments on every push to main.
Environment Variables
NEXT_PUBLIC_SITE_URL=https://your-domain.com
NEXT_PUBLIC_GA_ID=your-google-analytics-id
Common Customization Patterns
Add a Contact Form
'use client';
import { useState } from 'react';
export default function Contact() {
const [formData, setFormData] = useState({
name: '',
email: '',
message: '',
});
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const response = await fetch('/api/contact', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData),
});
if (response.ok) {
alert('Message sent successfully!');
setFormData({ name: '', email: '', message: '' });
}
};
return (
Get In Touch
setFormData({ ...formData, name: e.target.value })}
className="w-full px-4 py-3 bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500"
required
/>
setFormData({ ...formData, email: e.target.value })}
className="w-full px-4 py-3 bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500"
required
/>
setFormData({ ...formData, message: e.target.value })}
rows={5}
className="w-full px-4 py-3 bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500"
required
/>
Send Message
);
}
Smooth Scroll Navigation
export default function Navigation() {
const scrollToSection = (id: string) => {
const element = document.getElementById(id);
element?.scrollIntoView({ behavior: 'smooth' });
};
return (
<nav className="fixed top-0 w-full bg-gray-900/80 backdrop-blur-sm z-50">
<div className="max-w-6xl mx-auto px-4 py-4 flex justify-between items-center">
<div className="text-xl font-bold">Portfolio</div>
<div className="flex gap-6">
<button onClick={() => scrollToSection('projects')} className="hover:text-purple-400">
Projects
</button>
<button onClick={() => scrollToSection('experience')} className="hover:text-purple-400">
Experience
</button>
<button onClick={() => scrollToSection('contact')} className="hover:text-purple-400">
Contact
);
}
Troubleshooting
Images Not Loading
Ensure images are in the public directory and referenced with absolute paths:
<img src="/projects/myproject.png" alt="Project" />
Typing Animation Not Working
Check that the component is marked as 'use client' for client-side interactivity:
'use client';
import { useState, useEffect } from 'react';
Tailwind Styles Not Applied
Verify tailwind.config.ts content paths include all component directories:
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
],
Build Errors
Clear Next.js cache and rebuild:
rm -rf .next
npm run build