Building my portfolio website with Next.js and Tailwind CSS
A Step-by-Step Journey of Creating a Personal Portfolio with Modern Tools and Techniques
I already had a portfolio website built using the Bento layout. But now, I needed to add a blogs section to my portfolio, so I decided to build a new portfolio website with a fresh design.
This time, I chose to use Next.js (because previously, I always built my sites using React.js, so I thought, why not try Next.js this time? ) and Tailwind CSS (my go-to CSS framework that I absolutely love).
My Project Folder Structure
Starting a Next.js Project
To create a fresh Next.js project, run the following command:
npx create-next-app@latest
You can also add any additional packages you need, and you'll be ready to go!
Starting with This Code
<div className="w-full px-8 md:w-11/12 lg:px-0 lg:w-3/4 mx-auto py-20 flex flex-col gap-10">
<Header />
<div className="flex flex-col gap-7 py-5 lg:py-10">
<About />
<Separator />
<Experience />
<Separator />
<Blogs />
<Separator />
<Projects />
<Separator />
<Skills />
<Separator />
<Contact />
</div>
<Footer />
</div>
I styled all my sections within this structure.
Light and Dark Theme in Next.js
To add light and dark mode to my site, I installed the next-themes
package.
Adding Theme Styles
In my globals.css
file, I used the following code to apply background colors based on the theme:
@layer base {
body {
@apply dark:bg-[#1D1F20] bg-gray-200;
}
}
Creating a Theme Toggle Hook
Since I needed to manage the theme across different parts of the site, I created a custom hook, useThemeToggle
, to handle this functionality:
import { useTheme } from "next-themes";
const useThemeToggle = () => {
const { systemTheme, theme, setTheme } = useTheme();
const currentTheme = theme === "system" ? systemTheme : theme;
const toggleTheme = () => {
setTheme(currentTheme === "dark" ? "light" : "dark");
};
return {
currentTheme,
toggleTheme,
};
};
export default useThemeToggle;
Implementing the Theme Toggle Button
export const ThemeToggleButton = () => {
const { currentTheme, toggleTheme } = useThemeToggle();
return (
<button onClick={toggleTheme}>
{currentTheme === "dark" ? (
<Image
src={NightLight}
alt="night"
width={30}
height={30}
className="object-contain"
/>
) : (
<Image
src={nightDark}
alt="light"
width={30}
height={30}
className="object-contain"
/>
)}
</button>
);
};
Adding a Blogs Section
I chose to use static data for the blogs instead of fetching them dynamically (e.g., from Hashnode) to avoid any issues with failed requests, which could result in poor UX. I'll manually update the static data whenever I upload a new blog—it’s not too time-consuming.
Here’s the Blogs
component:
export const Blogs = () => {
return (
<div className="flex flex-col gap-5">
<Heading title="Blogs" />
<article className="flex flex-col gap-5 lg:gap-3 justify-between">
{blogs.map((blog) => (
<Link href={blog.link} target="blank" key={blog.id}>
<div className="flex flex-col gap-3 lg:flex-row lg:justify-between">
<div className="w-full">
<div className="flex items-center gap-3">
<Image
src={Calendar}
alt="calendar"
height={23}
width={23}
className="object-contain"
/>
<h1 className="text-themeText text-sm font-medium">
{blog.date}
</h1>
</div>
</div>
<div className="w-full text-lg flex flex-col gap-3">
<p className="font-bold dark:text-darkHeading text-lightHeading underline">
{blog.title}
</p>
<p className="font-medium dark:text-darkBody text-lightBody">
{blog.subTitle}
</p>
</div>
</div>
</Link>
))}
</article>
</div>
);
};
Deploying My Site on Netlify
I deployed my website on Netlify. You can check it out here:
rumaisa.netlify.app
GitHub Repo Link
You can also check out my GitHub repository here:
https://github.com/rumaisanaveed/new-portfolio
And that’s it for today! I’ll be sharing more such articles soon. Don’t forget to follow me, like, and comment on my articles.
Stay connected with me - Rumaisa Naveed