Introduction
This documentation provides step-by-step guidance on how to build a portfolio website using Next js. The goal is to help others set up their own portfolio efficiently.
Here's a link to have an overview of the portfolio site
https://www.loom.com/share/04a6843f67de48d0962ab2ddf2311a9f?sid=43940911-7c80-4fbe-ba19-f683e662ff90
Prerequisites
Before starting, ensure you have the following installed:
Basic knowledge of HTML, CSS, and JavaScript
- A code editor (e.g., VS Code)
-
Node.js installed
Link to watch a tutorial on how to install node.js
https://www.loom.com/share/23fd05a76b424682b2517b17fe9b33c4?sid=3129f99e-73da-484a-b6c2-3f74e3a8fe3d -
Your project folder with the neccessary dependencies
Link to watch how to create your next.js project folder
https://www.loom.com/share/74b232a97d654d48b69f0bcc8fb06a1a?sid=4291f2a5-011c-4732-bbf8-a33ad1c246dd GitHub account
Netlify / Vercel account
A web browser (Chrome, Firefox, Edge, etc.)
Project Setup
- Open your a Code Editor
- Open the project folder in your preferred code editor.
- Run the development command line
- Run the command line in the terminal of vscode
- npm run dev
After click on the local url, so it's opened in your browser
Folder Structure
portfolio-project/
│-- next
│-- app/
| | -- components/
| | |-- About.jsx
| | |-- Contact.jsx
| | |-- Footer.jsx
| | |-- Head.jsx
| | |-- Navbar.jsx
| | |-- Project.jsx
| | |-- Service.jsx
| -- global.css
| -- layout.js
| -- page.js
│-- node.modules
│--public
│-- tailwind.config.ms
*NOTE: You must create the components folder in the app folder and then create the about, contact, footer, head, navbar, project and service within the component folder.
*
Customization
- Update the tailwind.config.mjs code
- Open tailwind.config.mjs and update the file with this code
/** @type {import('tailwindcss').Config} */
import { Montserrat, Poppins } from "next/font/google";
// eslint-disable-next-line import/no-anonymous-default-export
export default {
content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {
colors: {
background: "var(--background)",
foreground: "var(--foreground)",
},
},
fontFamily: {
Poppins: ["Poppins", "sans-serif"],
Montserrat: ["Montserrat", "serif"],
},
boxShadow: {
shadowWhite: "2px 2px 0 #cbd5e1",
},
gridTemplateColumns: {
auto: "repeat(auto-fit, minmax(200px, 1fr))",
},
},
plugins: [],
};
- Update the global.css
- Change the code the the global.css file with this
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--foreground: #ffffff;
--background: #171717;
}
*,
*::before,
*::after {
box-sizing: border-box;
overflow-x: hidden;
}
body {
color: var(--foreground);
background: var(--background);
font-family: Poppins;
}
- Modify layout.js Section
- Update the code in layout.js with the code below
import { Poppins, Montserrat } from "next/font/google";
import "./globals.css";
const poppins = Poppins({
subsets: ["latin"],
weight: ["400", "500", "600", "700"],
});
const montserrat = Montserrat({
subsets: ["latin"],
weight: ["400"],
});
export const metadata = {
title: "Portfolio - "Your name",
description:
"Showcasing the work and skills of a passionate frontend developer with a focus on web development, UX/UI design, and problem-solving",
};
export default function RootLayout({ children }) {
return (
<html lang="en" className="scroll-smooth">
<body
className={`${poppins.className} ${montserrat.className} antialiased`}
>
{children}
</body>
</html>
);
}
3.** Modify page.js Section**
Update the code in page.js with the code below
import Image from "next/image";
import Navbar from "./components/Navbar";
import Head from "./components/Head";
import About from "./components/About";
import Service from "./components/Service";
import Project from "./components/Project";
import Contact from "./components/Contact";
import Footer from "./components/Footer";
export default function Home() {
return (
<div>
<Navbar />
<Head />
<About />
<Service />
<Project />
<Contact />
<Footer />
</div>
);
}
- *Open the Navbar.jsx *
- In this file follow this code format
"use client";
import Image from "next/image";
import React, { useRef } from "react";
import logo from "../assets/logo3.png";
import close from "../assets/close-white.png";
import menu from "../assets/menu-white.png";
const Navbar = () => {
const sideMenu = useRef();
const openMenu = () => {
sideMenu.current.style.transform = "translateX(-15rem)";
};
const closeMenu = () => {
sideMenu.current.style.transform = "translateX(16rem)";
};
return (
<nav>
<div className=" hidden sm:flex justify-between bg-opacity-50 backdrop-blur-md bg-[#222222] py-2 px:[5rem] sm:px-20 lg:px-[20rem] fixed top-0 right-0 left-0 z-50">
<Image src={logo} className=" w-20 md:w-24 " alt="" />
<div className="flex sm:gap-5 text-xs lg:text-sm lg:gap-12 items-center gap-2">
<a href="#top" className="hover:text-[#ffbc92] duration-500">
Home
</a>
<a href="#about" className="hover:text-[#ffbc92] duration-500 ">
About
</a>
<a href="#service" className="hover:text-[#ffbc92] duration-500">
Services
</a>
<a href="#project" className="hover:text-[#ffbc92] duration-500">
Projects
</a>
<a href="#contacts" className="hover:text-[#ffbc92] duration-500">
Contact
</a>
</div>
</div>
<div className="bg-[#222222] fixed w-full h-[4rem] bg-opacity-50 backdrop-blur-md sm:hidden z-50">
<Image src={logo} className=" w-20 md:w-24 mt-7 ml-5 fixed " alt="" />
<button>
<Image
onClick={openMenu}
src={menu}
className="w-6 mt-3 sm:hidden -right-[1px] mr-3 fixed"
alt=""
/>
</button>
</div>
<div>
<ul
ref={sideMenu}
className="sm:hidden flex flex-col gap-4 bg-slate-700 z-50 py-12 px-5 fixed rounded-sm h-screen -right-[15rem] w-[12rem] duration-500"
>
<div onClick={closeMenu}>
<button>
<Image
src={close}
className="w-4 absolute top-5 left-[10rem] "
alt=""
/>
</button>
</div>
<li>
<a href="#top" onClick={closeMenu}>
Home
</a>
</li>
<li>
<a href="#about" onClick={closeMenu}>
About
</a>
</li>{" "}
<li>
<a href="#service" onClick={closeMenu}>
Services
</a>
</li>{" "}
<li>
<a href="#project" onClick={closeMenu}>
Projects
</a>
</li>{" "}
<li>
<a href="#contacts" onClick={closeMenu}>
Contact
</a>
</li>
</ul>
</div>
</nav>
);
};
export default Navbar;
- *Open the Head.jsx *
- In this file follow this code format
import Image from "next/image";
import React from "react";
import profileImg from "../assets/profile-img.png";
import hand from "../assets/hand-icon.png";
const Head = () => {
return (
<div className="">
<div className=" flex flex-col items-center mx-auto mt-20 text-center gap-2">
<Image src={profileImg} className="rounded-full w-32" alt="" />
<p className=" text-[1rem] w-[20rem] sm:w-full justify-center sm:text-2xl flex sm:gap-2 font-semibold lg:text-2xl">
Hey There! I go by the name _[Your name]_
<Image
src={hand}
className=" w-7 h-[28px] -translate-x-2 sm:translate-x-0 sm:h-auto sm:w-7 "
/>
</p>
<h2 className="text-2xl sm:text-[2rem] sm:w-[40rem] mt-2 overflow-y-hidden lg:text-5xl lg:w-[58rem]">
A frontend Developer and Blockchain enthusiast
</h2>
<p className=" text-[13px] w-[20rem] sm:text-[15px] sm:w-[38rem] mt-3 lg:text-[16px] lg:w-[45rem]">
I am an IT student with a strong interest in frontend development and
the blockchain field. I am focused on building user-friendly,
responsive websites and am actively exploring blockchain technologies.
My goal is to contribute positively to the ecosystem by developing
innovative solutions and improving the user experience.
</p>
<div className="flex flex-col gap-5 sm:flex-row sm:gap-20 mt-10 font-bold">
<a
href="#contacts"
className="border rounded-3xl py-3 px-6 bg-white text-black hover:text-[#f08847] duration-500"
>
Let's connect
</a>
<a
href="/Your-Resume.pdf"
className="border rounded-3xl py-3 px-8 hover:text-[#ffbc92] duration-500"
download
>
My resume
</a>
</div>
</div>
</div>
);
};
export default Head;
- *Open the About.jsx *
- In this file follow this code format
import Image from "next/image";
import React from "react";
import myImage from "../assets/user-image.png";
import lang from "../assets/Logos.png";
import vscode from "../assets/vscode.png";
import vercel from "../assets/vercel.png";
import netlify from "../assets/netlify.png";
import figma from "../assets/figma.png";
import github from "../assets/github.png";
const About = () => {
return (
<div id="about">
<div className="mt-32 text-center ">
<h2 className="mb-12 text-3xl sm:text-4xl lg:text-5xl font-bold bg-gradient-to-r from-[#FF8660] to-[#9A33FF] text-transparent bg-clip-text overflow-y-hidden">
About me
</h2>
<div className="flex flex-col lg:flex-row items-center lg:justify-center lg:gap-40 lg:items-start gap-5">
<Image src={myImage} className="rounded-xl w-52 lg:w-64" alt="" />
<div>
<p className="text-[13px] w-[21rem] mx-auto sm:mx-0 sm:text-[14px] sm:w-[30rem] lg:text-[16px] lg:w-[40rem] lg:text-left">
I am an aspiring frontend developer, learning the necessary tech
stack i need to succeed in my field. I have worked on few projects
that helped me to reinforce what i've learnt as well as improve
upon my skills. I'm willing to work and collaborate with people to
learn and grow.
</p>
<div className="mt-10 lg:text-left">
<p className="mb-5 font-bold text-lg lg:text-xl bg-gradient-to-r from-[#FF8660] to-[#9A33FF] text-transparent bg-clip-text">
Experience with
</p>
<a className="flex lg:justify-start justify-center ">
<Image src={lang} className="w-72 sm:w-80" />
</a>
</div>
<div className=" mt-7 ">
<p className=" font-bold text-lg lg:text-xl lg:text-left bg-gradient-to-r from-[#FF8660] to-[#9A33FF] text-transparent bg-clip-text">
Tools I use
</p>
<div className=" flex gap-7 sm:gap-10 lg:justify-start justify-center overflow-y-visible ">
<a href="https://code.visualstudio.com/" target="_blank">
<Image
alt=""
src={vscode}
className="w-9 sm:w-10 mt-4 duration-500 bg-white rounded-xl border p-2 hover:bg-slate-200 hover:shadow-shadowWhite hover:-translate-y-1"
/>
</a>
<a href="https://www.figma.com/" target="_blank">
<Image
alt=""
src={figma}
className="w-9 sm:w-10 duration-500 mt-4 bg-white rounded-xl border p-2 hover:bg-slate-200 hover:shadow-shadowWhite hover:-translate-y-1"
/>
</a>
<a href="https://vercel.com/" target="_blank">
<Image
alt=""
src={vercel}
className="w-[38px] sm:w-[40px] duration-500 mt-4 border rounded-xl bg-white r p-2 hover:bg-slate-200 hover:shadow-shadowWhite hover:-translate-y-1"
/>
</a>
<a href="https://www.netlify.com/" target="_blank">
<Image
alt=""
src={netlify}
className="w-[38px] sm:w-[40px] duration-500 mt-4 bg-white rounded-xl border p-2 hover:bg-slate-200 hover:shadow-shadowWhite hover:-translate-y-1"
/>
</a>
<a href="https://github.com/" target="_blank">
<Image
alt=""
src={github}
className="w-[40px] sm:w-[42px] duration-500 mt-4 bg-white rounded-xl border p-2 hover:bg-slate-200 hover:shadow-shadowWhite hover:-translate-y-1"
/>
</a>
</div>{" "}
</div>
</div>
</div>
</div>
</div>
);
};
export default About;
- *Open the Service.jsx *
- In this file follow this code format
import Image from "next/image";
import React from "react";
import ui from "../assets/ui-icon.png";
import graphic from "../assets/graphics-icon.png";
import web from "../assets/web-icon.png";
const Service = () => {
return (
<div id="service" className="">
<div className="my-32 ">
<h2 className="text-3xl sm:text-4xl lg:text-5xl overflow-y-hidden font-bold text-center bg-gradient-to-r from-[#FF8660] to-[#9A33FF] text-transparent bg-clip-text">
What I do
</h2>
<ul className="mt-10 flex flex-col sm:flex-row items-center mx-auto gap-6 w-[80%] lg:w-[60%]">
<li className=" border-none rounded-xl p-8 w-3/4 h-[15rem] bg-slate-900 hover:bg-slate-800 duration-500 ">
<Image alt="" src={web} className="w-10 mb-3" />
<h2 className="text-sm lg:text-[1rem] font-semibold mb-3 bg-gradient-to-r from-[#FF8660] to-[#9A33FF] text-transparent bg-clip-text">
Web development
</h2>
<p className=" text-[13px] ">
Building fast and responsive websites.
</p>
</li>
<li className=" border-none rounded-xl p-8 w-3/4 h-[15rem] bg-slate-900 hover:bg-slate-800 duration-500 ">
<Image alt="" src={ui} className="w-10 mb-3" />
<h2 className="text-sm lg:text-[1rem] font-semibold mb-3 bg-gradient-to-r from-[#FF8660] to-[#9A33FF] text-transparent bg-clip-text">
UI/UX design
</h2>
<p className=" text-[13px]">
Designing simple and intuitive websites
</p>
</li>
<li className="border-none rounded-xl p-7 w-3/4 h-[15rem] bg-slate-900 hover:bg-slate-800 duration-500 ">
<Image alt="" src={graphic} className="w-10 mb-3" />
<h2 className="text-sm lg:text-[1rem] font-semibold mb-3 bg-gradient-to-r from-[#FF8660] to-[#9A33FF] text-transparent bg-clip-text">
Graphic design
</h2>
<p className=" text-[13px]">Creating visually appealing designs</p>
</li>
</ul>
</div>
</div>
);
};
export default Service;
- Open the Project.jsx In this file follow this code format
import React from "react";
import profileLinks from "../assets/work-1.png";
import guessGame from "../assets/guess_game.png";
import pigGame from "../assets/pig_game.png";
import landingPage from "../assets/landing_page.jpg";
import send from "../assets/send-icon.png";
import Image from "next/image";
const Project = () => {
return (
<div id="project">
<div className=" mt-20 mb-10 w-3/4 mx-auto">
<div className="">
<h2 className="mb-10 text-3xl sm:text-4xl lg:text-5xl overflow-y-hidden text-center bg-gradient-to-r from-[#FF8660] to-[#9A33FF] text-transparent bg-clip-text">
Projects i Built
</h2>
<ul className="grid grid-cols-auto gap-4 place-items-center ">
<li>
<Image src={profileLinks} className="w-[17rem] h-44" alt="" />
<div className="bg-slate-900 hover:bg-slate-800 py-2 px-5 rounded-xl mt-2 flex gap-10 items-center w-[17rem]">
<a
href="https://social-links-profile-main-six-xi.vercel.app/"
target="_blank"
>
<p className="font-semi-bold bg-gradient-to-r from-[#FF8660] to-[#9A33FF] text-transparent bg-clip-text">
Social links profile
</p>
<p className="text-sm">Web design</p>
</a>
<a
href="https://social-links-profile-main-six-xi.vercel.app/"
target="_blank"
>
<Image
alt=""
src={send}
className="bg-white w-8 p-2 aspect-square rounded-xl hover:bg-gray-200"
/>
</a>
</div>
</li>
<li>
<Image src={guessGame} className="w-[17rem] rounded-xl" alt="" />
<div className="bg-slate-900 w-[17rem] hover:bg-slate-800 py-2 px-5 rounded-xl mt-2 flex gap-24 items-center">
<a href="https://guess-game-by-suad.netlify.app/" className="">
<p className="font-semi-bold bg-gradient-to-r from-[#FF8660] to-[#9A33FF] text-transparent bg-clip-text">
Guess game
</p>
<p className="text-sm">Web design</p>
</a>
<a
href="https://guess-game-by-suad.netlify.app/"
target="_blank"
>
<Image
alt=""
src={send}
className="bg-white w-8 p-2 aspect-square rounded-xl hover:bg-gray-200"
/>
</a>
</div>
</li>
<li>
<Image src={pigGame} className="w-[17rem] rounded-xl" alt="" />
<div className="bg-slate-900 w-[17rem] hover:bg-slate-800 py-2 px-5 rounded-xl mt-2 flex gap-28 items-center">
<a href="" target="_blank">
<p className="font-semi-bold bg-gradient-to-r from-[#FF8660] to-[#9A33FF] text-transparent bg-clip-text">
Pig game
</p>
<p className="text-sm">Web design</p>
</a>
<a href="https://pig-game-by-suad.netlify.app/" target="_blank">
<Image
alt="https://pig-game-by-suad.netlify.app/"
src={send}
className="bg-white w-8 p-2 aspect-square rounded-xl hover:bg-gray-200"
/>
</a>
</div>
</li>
<li>
<Image
src={landingPage}
className="w-[17rem] rounded-xl"
alt=""
/>
<div className="bg-slate-900 w-[17rem] hover:bg-slate-800 py-2 px-5 rounded-xl mt-2 flex gap-7 items-center">
<a
href="https://huddle-landing-page-by-suad.netlify.app/"
target="_blank"
>
<p className="font-semi-bold bg-gradient-to-r from-[#FF8660] to-[#9A33FF] text-transparent bg-clip-text">
Huddle landing page
</p>
<p className="text-sm">UI/UX</p>
</a>
<a
href="https://huddle-landing-page-by-suad.netlify.app/"
target="_blank"
>
<Image
alt=""
src={send}
className="bg-white w-8 p-2 aspect-square rounded-xl hover:bg-gray-200"
/>
</a>
</div>
</li>
</ul>
</div>
</div>
</div>
);
};
export default Project;
- *Open the Contact.jsx *
- In this file follow this code format
import Image from "next/image";
import React from "react";
import x from "../assets/x.png";
import linkedin from "../assets/linkedin.png";
import whatsapp from "../assets/whatsapp.png";
import email from "../assets/mail_icon_dark.png";
const Contact = () => {
return (
<div
id="contacts"
className="mt-36 mb-16 flex flex-col items-center gap-5"
>
<div className="text-center">
<h2 className=" text-xl sm:text-4xl font-bold overflow-y-hidden mb-2 bg-gradient-to-r from-[#FF8660] to-[#9A33FF] text-transparent bg-clip-text">
Want to collaborate with me?
</h2>
<p className=" text-md sm:text-xl font-semibold ">
Lets connect on social media app!{" "}
</p>
</div>
<div className="flex gap-4 sm:gap-6">
<p className="bg-gradient-to-r from-[#FF8660] to-[#9A33FF] text-transparent bg-clip-text">
Connect:
</p>
<a href=" " target="_blank">
<Image
alt="mailto:suadmacaulay50@gmail.com"
src={email}
className="w-[1.4rem] sm:w-[1.6rem] translate-y-1"
/>
</a>
<a href=" " target="_blank">
<Image
alt="https://www.linkedin.com/in/suad-macaulay"
src={linkedin}
className="w-[1.5rem] sm:w-[1.7rem]"
/>
</a>
<a href=" " target="_blank">
<Image
alt="https://wa.me/0598399951"
src={whatsapp}
className="w-[1.6rem] sm:w-[1.8rem]"
/>
</a>
<a href=" " target="_blank">
<Image
alt="https://x.com/moreofababe"
src={x}
className="w-[1.6rem] sm:w-7"
/>
</a>
</div>
</div>
);
};
export default Contact;
- *Open the Footer.jsx *
- In this file follow this code format
import React from "react";
const Footer = () => {
return (
<div>
<div className="border-t text-center mx-[15%]">
<p className="my-5">© [Your name]. All rights reserved</p>
</div>
</div>
);
};
export default Footer;
Deployment
Once you’ve customized your portfolio, deploy it online.
**
Use this link to watch a step by step guide on how to push your project to github and how to deploy on Netlify or Vercel.
https://scrimba.com/learn-html-and-css-c0p/~020
Conclusion
This documentation provides a foundation to build and customize your own portfolio website. If you encounter issues, feel free to reach out!
Author: Suad Macaulay
Top comments (0)