A modern, responsive personal portfolio website built with Next.js, TypeScript, and Tailwind CSS. This website showcases my skills, experience, and projects as a Senior Full-Stack Developer specializing in React, TypeScript, Next.js, and Ruby on Rails.
Visit the live website at andriifurmanets.com
- Responsive Design: Optimized for all device sizes from mobile to desktop
- Dark/Light Mode: Theme toggle with system preference detection
- Modern UI: Clean, professional design with smooth animations
- SEO Optimized: Comprehensive metadata, structured data, and OpenGraph images
- Mobile-First Navigation: Hamburger menu for mobile with smooth transitions
- Interactive Sections: About, Experience, Skills, Education, and Contact
- Contact Form: Email integration for direct communication
- Optimized Performance: Fast loading times and efficient rendering
- Framework: Next.js 15 with App Router
- Language: TypeScript
- Styling: Tailwind CSS
- Animations: Framer Motion
- Icons: Lucide React and React Icons
- Form Handling: React Hook Form with Zod
- Email Integration: EmailJS
- Theming: next-themes
- SEO: Next.js Metadata API, next-sitemap
personal-website/
βββ public/ # Static assets
β βββ icons/ # Technology icons
β βββ logos/ # Logo files
β βββ og-image.svg # OpenGraph image
βββ src/
β βββ app/ # Next.js App Router
β β βββ layout.tsx # Root layout with metadata
β β βββ page.tsx # Home page
β β βββ globals.css # Global styles
β βββ components/ # React components
β β βββ sections/ # Page sections (Hero, About, etc.)
β β βββ ui/ # Reusable UI components
β βββ lib/ # Utility functions and hooks
βββ tailwind.config.js # Tailwind configuration
βββ next.config.js # Next.js configuration
βββ package.json # Dependencies and scripts
- Node.js 18.17.0 or later
- npm or yarn
-
Clone the repository:
git clone https://github.com/afurm/personal-website.git cd personal-website -
Install dependencies:
npm install # or yarn install -
Run the development server:
npm run dev # or yarn dev -
Open http://localhost:3000 in your browser to see the result.
Create a .env.local file in the root directory with the following variables:
# EmailJS Configuration
NEXT_PUBLIC_EMAILJS_SERVICE_ID=your_service_id
NEXT_PUBLIC_EMAILJS_TEMPLATE_ID=your_template_id
NEXT_PUBLIC_EMAILJS_USER_ID=your_user_id
The contact form uses EmailJS for sending emails. You'll need to:
- Create an account at EmailJS
- Create a service and email template
- Update the environment variables with your credentials
The website includes comprehensive favicon support for various devices and browsers. To properly set up the favicon:
-
Generate favicon files using the SVG templates in the
publicdirectory:favicon.svg- Vector version of the faviconfavicon-large.svg- Larger vector version for generating different sizes
-
You'll need to create the following files (you can use an online favicon generator like RealFaviconGenerator):
favicon.ico- Multi-size ICO file (16x16, 32x32, 48x48)favicon-16x16.png- 16x16 PNG faviconfavicon-32x32.png- 32x32 PNG faviconapple-touch-icon.png- 180x180 PNG for iOS devicesandroid-chrome-192x192.png- 192x192 PNG for Android devicesandroid-chrome-512x512.png- 512x512 PNG for Android devices
-
The
site.webmanifestfile is already configured to reference these icons for PWA support.
The website is fully responsive with special considerations for mobile users:
- Hamburger menu for navigation
- Vertically stacked buttons in the hero section
- Optimized tech stack display
- Custom theme toggle in mobile menu
This website implements several SEO best practices:
- Comprehensive metadata in
layout.tsx - OpenGraph and Twitter card images
- Structured data with Schema.org markup
- Automatically generated sitemap and robots.txt
- Proper heading hierarchy
- Semantic HTML structure
npm run build
# or
yarn buildThis will create an optimized production build and generate the sitemap.
The site can be easily deployed to:
- Vercel (recommended for Next.js)
- Netlify
- AWS Amplify
Most content is stored in the component files under src/components/sections/. Update these files to change the information displayed on the website.
The website uses Tailwind CSS for styling. Customize the design by modifying:
tailwind.config.jsfor theme colors and extensions- Component-level classes for specific styling
This project is licensed under the MIT License - see the LICENSE file for details.
Andrii Furmanets - Senior Full-Stack Developer
Built with β€οΈ using Next.js and React
The contact form on this website sends submissions to a Telegram bot. Follow these steps to set it up correctly:
-
Create a Telegram bot:
- Message @BotFather on Telegram
- Use the
/newbotcommand and follow the instructions - BotFather will give you a bot token - copy this for the next step
-
Get your chat ID:
- Message @userinfobot on Telegram
- It will reply with your user information, including your ID
- Copy your ID (a number like 434334343)
-
Configure environment variables:
- Create a
.env.localfile in the root directory with the following:
TELEGRAM_BOT_TOKEN=your_bot_token_here TELEGRAM_CHAT_ID=your_chat_id_here- Replace the placeholder values with your actual bot token and chat ID
- Create a
-
Important: Start a conversation with your bot:
- Find your bot on Telegram (by the username you gave it)
- Send it a message (like "/start")
- This step is crucial - your bot can only send messages to users who have initiated a conversation with it
-
Test the connection:
- After starting your development server, visit
/api/telegram-testin your browser - This will send a test message to your Telegram account
- If successful, you'll receive a message on Telegram and see a success response in the browser
- If it fails, check the error message and make sure you've completed step 4
- After starting your development server, visit
-
Restart the development server:
npm run dev # or yarn dev
Now when someone submits the contact form, you'll receive a notification in Telegram with their name, email, and message.
If you're experiencing issues with the Telegram integration:
-
"Chat not found" error:
- Make sure you've started a conversation with your bot
- Verify that the chat ID in
.env.localmatches your Telegram user ID
-
No messages being received:
- Check that your bot token is correct
- Ensure your development server is running
- Try the test endpoint at
/api/telegram-test
-
Bot stopped working:
- Telegram bot tokens can expire if you regenerate them
- If you created a new token, update it in
.env.local
This website includes a blog system that uses Markdown files to generate blog posts. Here's how to create and format blog posts:
Blog posts are stored as Markdown files in the blogs/ directory. Each file must include:
- Front Matter: YAML metadata at the top of the file between triple dashes (
---) - Content: The main body of the blog post in Markdown format
- Create your Markdown files directly in the
blogs/directory - The filename should ideally match or relate to the slug (e.g.,
getting-started-with-nextjs.md) - The system will automatically process all
.mdfiles in this directory
Each blog post must include the following front matter fields:
---
title: "Your Blog Post Title"
description: "A brief description for SEO and previews (150-160 characters recommended)"
date: "YYYY-MM-DD"
tags: ["tag1", "tag2", "tag3"]
slug: "your-blog-post-slug"
---- title: The title of your blog post
- description: A brief summary for SEO and previews (150-160 characters recommended)
- date: Publication date in YYYY-MM-DD format
- tags: An array of relevant tags (used for categorization and filtering)
- slug: The URL-friendly identifier for the post (used in the URL path)
The blog content uses standard Markdown syntax:
-
Headings: Use
#for h1,##for h2, etc. -
Emphasis: Use
*italic*for italic and**bold**for bold -
Lists: Use
-for unordered lists and1.for ordered lists -
Links: Use
[link text](URL) -
Images: Use
 -
Code blocks: Use triple backticks with optional language identifier:
// JavaScript code example function hello() { console.log("Hello, world!"); }
---
title: "Getting Started with Next.js"
description: "Learn how to build modern web applications with Next.js"
date: "2024-03-01"
tags: ["nextjs", "react", "web-development"]
slug: "getting-started-with-nextjs"
---
# Getting Started with Next.js
Next.js is a powerful React framework that enables you to build server-side rendered and statically generated web applications with ease.
## Why Next.js?
Next.js provides several key features that make it an excellent choice for modern web development:
1. **Server-side rendering (SSR)** - Improves performance and SEO
2. **Static site generation (SSG)** - Pre-renders pages at build time for optimal performance
## Code Example
```jsx
export default function HomePage() {
return (
<div>
<h1>Welcome to my website!</h1>
<p>Built with Next.js</p>
</div>
);
}To add a new blog post:
- Create a new
.mdfile in theblogs/directory - Add the required front matter at the top of the file
- Write your content using Markdown syntax
- The blog post will automatically appear on the blog page after rebuilding the site
The blog system works as follows:
-
The
src/lib/blog.tsfile contains utility functions that:- Read all Markdown files from the
blogs/directory - Parse the front matter using
gray-matter - Convert Markdown content to HTML using
remarkandremark-html - Generate excerpts for previews
- Sort posts by date
- Read all Markdown files from the
-
The blog pages use these functions to:
- List all blog posts at
/blogs - Display individual posts at
/blogs/[slug] - Show tag-filtered posts at
/blogs/tag/[tag]
- List all blog posts at
-
Each page includes proper SEO metadata and structured data for better search engine visibility
For optimal SEO:
- Use descriptive, keyword-rich titles
- Write compelling meta descriptions (150-160 characters)
- Include relevant tags
- Use proper heading hierarchy (h1, h2, h3, etc.)
- Add alt text to all images
- Keep URLs (slugs) short and descriptive
Creating blog posts that rank well in search engines requires attention to both content quality and technical SEO factors. Follow these guidelines to optimize your blog posts:
-
Primary Keyword Selection:
- Choose one main keyword/phrase that accurately represents your content
- Use tools like Google Keyword Planner, Ubersuggest, or Ahrefs to find relevant keywords
- Select keywords with good search volume but manageable competition
-
Keyword Placement:
- Include your primary keyword in:
- Title (preferably near the beginning)
- First paragraph of content
- At least one subheading (h2 or h3)
- Meta description
- URL slug
- Use secondary keywords and related terms naturally throughout the content
- Maintain a keyword density of 1-2% (don't overuse keywords)
- Include your primary keyword in:
-
Compelling Title:
- Keep titles under 60 characters to avoid truncation in search results
- Use numbers, questions, or "how-to" formats to increase click-through rates
- Include your primary keyword naturally
-
Meta Description:
- Write a compelling summary between 150-160 characters
- Include your primary keyword
- Add a call-to-action to encourage clicks
-
Content Organization:
- Start with a strong introduction that hooks readers
- Use proper heading hierarchy (h1 for title, h2 for main sections, h3 for subsections)
- Break content into scannable sections with descriptive subheadings
- Use bullet points and numbered lists for better readability
- Write paragraphs of 2-3 sentences for better mobile readability
-
Content Length & Depth:
- Aim for comprehensive coverage (1,500+ words for competitive topics)
- Provide unique insights, examples, and actionable information
- Answer common questions related to your topic
- Include statistics, case studies, or research to support your points
-
Images:
- Use descriptive filenames (e.g.,
nextjs-performance-optimization.jpginstead ofimage1.jpg) - Add alt text that includes relevant keywords and describes the image
- Compress images for faster loading (use WebP format when possible)
- Consider adding captions for important images
- Use descriptive filenames (e.g.,
-
Internal & External Links:
- Include 3-5 internal links to other relevant blog posts or pages on your site
- Link to 2-3 authoritative external sources to support your content
- Use descriptive anchor text for links (avoid "click here" or "read more")
- Consider adding a "Related Posts" section at the end
-
Structured Data:
- The blog system automatically adds BlogPosting schema markup
- This helps search engines understand your content and may enable rich results
-
Mobile Optimization:
- Preview your content on mobile devices
- Ensure text is readable without zooming
- Check that images don't overflow the viewport
-
Optimal Publishing Time:
- Use the current date in the front matter for new posts
- Consider updating the date when making significant updates to existing posts
-
URL Structure:
- Keep slugs short, descriptive, and keyword-rich
- Use hyphens to separate words (e.g.,
nextjs-seo-tips) - Avoid special characters, numbers (unless necessary), and stop words
-
Content Freshness:
- Regularly update older posts with new information
- Add editor's notes when making significant updates
---
title: "10 Essential Next.js SEO Tips for Better Rankings in 2024"
description: "Learn how to optimize your Next.js website for search engines with these 10 proven SEO techniques that improve visibility and drive more organic traffic."
date: "2024-03-15"
tags: ["nextjs", "seo", "web-development", "performance"]
slug: "nextjs-seo-tips"
---By following these guidelines, your blog posts will have a better chance of ranking well in search engines, attracting more organic traffic, and providing value to your readers.