Portfolio Website in Next.js
Introduction
The purpose of this project is to create a portfolio website to display personal projects, experience, contact details, and socials, while maintaining and clean modern design. Additionally an important feature is automatically populating my projects from my notes app notion as CMS through its API.
The Goal is to showcase my project portfolio, experience, and personality through my personal website to potential employers, colleagues, and connections. and provide an easy way for them to find my socials and reach out to me.
Project Details
- Problem: Standing out as a computer science student in a competitive job market can be difficult. An impressive portfolio website is crucial to differentiate oneself from other candidates and make a lasting impression on potential employers by showcasing skills, experience, and projects effectively.
- Tools and Technologies:
- Next Js: For developing the Website
- Notion API, Notion Renderer: To pull data from my notion projects database, and render a clone of the page.
- Tailwind CSS
- Nodemailer: to enable contact forms
- Vercel: For deployment
- Challenges:
- My projects are documented on Notion, so using Notion as a CMS to pull my project documentation and display them on my website was a good solution, however was sightly challenging considering Notion’s official API is fairly new and a lot of the notion page renders weren’t compatible with the fetched data.
Dependencies
- Tailwind CSS: Used for styling the web interface. (MIT License)
- react-notion-x: Used for rendering Notion pages in a React application. (MIT License)
- Notion Client: Used for interacting with the Notion API. (MIT License)
- Notion API: Used for accessing Notion data. (Proprietary License)
- Nodemailer: Used for sending emails. (MIT License)
- Framer Motion: Used for creating animations and interactive UI components. (MIT License)
Screenshots or Demo
You’re probably seeing this page through my portfolio website so this section is trivial. But here’s a screenshot of the main page.


Visit Project: karimjaouhar.com
Page Insights

Code Samples
Timeline
Implementing the Timeline feature was an interesting UI challenge, the goal was a to have a vertical timeline that displays:
date, emoji, content can be in permutation the following states: next for events that have events that follow them, and future for events in the future. I achieved this using two components
TimeLineItem , and TimeLine .TimeLineItem
Each TimeLineItem takes the following props
date, emojis, content, next, future. A timeline item follows this structure which allows them to chain together seamlessly :
Date | Line + Node | Emoji | Content |
export function TimeLineItem({date, emojis, content, next, future}) { return ( <div className="flex h-20 space"> {/* Contains Date, Line, Conent sections*/} {future? <div className="bg-gray-200 dark:bg-gray-800 text-xs font-bold py-1 px-1 rounded-md w-2/12 md:w-1/12 my-auto text-center"> <p>{date}</p> </div> : <div className="bg-blue-200 dark:bg-blue-800 text-xs font-semibold py-1 px-1 rounded-md w-2/12 md:w-1/12 my-auto text-center"> <p>{date}</p> </div> } {/* If the timeline event is in the future, the date is background is gray, otherwise its blue*/} <div className="h-full w-1/12 flex-col relative"> {/* container for the timeline line and node*/} {future? <div className="h-8 w-0.5 mx-auto right-1/2 flex flex-col"> .... {/* divs with alternating colours to create a dashed effect*/} </div> : <div className="bg-gray-500 dark:bg-gray-600 h-8 w-0.5 mx-auto right-1/2"></div>} {/* show the prev line dashed if the event is in the futre, solid otherwise*/} <div className="bg-gray-300 dark:bg-gray-200 w-2 h-2 rounded-full mx-auto z-10"></div> {/*Timeline Dot / Node*/} {(next && future)? <div className="bg-gray-500 dark:bg-gray-600 h-1/2 w-0.5 mx-auto right-1/2 flex flex-col"> .... {/* divs with alternating colours to create a dashed effect*/} </div> : next? <div className="bg-gray-500 dark:bg-gray-600 h-1/2 w-0.5 mx-auto right-1/2"></div> : <></>} {/* show the next line dashed if the event is in the futre, solid otherwise, or dont show at all if next is disabled*/} </div> <div className="w-10/12 flex my-auto"> {/* container for emoji and content section */} <div className=" bg-gray-200 dark:bg-gray-800 p-3 flex my-auto rounded-md"> <div className="w-1/12 px-2"> {/* contain the emoji within the 1/12 of that section*/} <p className="text-md">{emojis}</p> </div> <div className="w-11/12 px-2"> {/* contain the content within the 11/12 of that section*/} <p className="pl-2 text-xs md:text-sm">{content}</p> </div> </div> </div> </div> ) }


import { TimeLineItem } from './TimeLineItem' export function TimeLine() { return ( <div> <TimeLineItem date={2002} emojis="🇱🇧" content="I was born and raised in my home country Lebanon" next={true} future={false}/> <TimeLineItem date={2005} emojis="🏫" content="I attended DISB German School up until grade 9" next={true} future={false}/> <TimeLineItem date={2017} emojis="🇨🇦" content="I moved to Canada with my family" next={true} future={false}/> <TimeLineItem date={2020} emojis="👨🎓" content="Graduated from Iroquois Ridge High School" next={true} future={false}/> <TimeLineItem date={2020} emojis="🏫" content="Enrolled in the Computer Science program at York University" next={true} future={false}/> <TimeLineItem date={2023} emojis="👨🎓" content="Graduated with BSc. Computer Science degree?" next={true} future={true}/> <TimeLineItem date={"----"} emojis="👨💻" content="Got my first job As a Developer?" next={false} future={true}/> </div> ) }
Links
Github Repository: https://github.com/karimjawhar5/portfolio
Visit Project: https://karimjaouhar.com/
Conclusion
In summary, I created a modern and professional portfolio website that showcases my personal projects, experience, and contact information. Despite some challenges with a new API, I was able to use Next.js and Notion's API and Renderer to automatically populate project details and maintain a consistent design. My website serves as a valuable tool for potential employers, colleagues, and connections to learn about my skills, experience, and personality, while also providing an easy way to reach out and connect.
