React 30-Project 15: Building developer portfolio using React.js
Introduction:
In this tutorial, we’ll build an online developer portfolio using React.js. We’ll take the static site resume code from the Start Bootstrap repository and convert the static HTML code to JSX for rendering in React. This will allow us to leverage the benefits of React’s component-based architecture for creating a dynamic and interactive developer portfolio.
Goal
Our goal is to convert a static resume template into JSX based component site with sections as shown below 👇
Try this task once before continuing with solution below.
Prerequisites:
Before starting, ensure you have the following:
- Node.js installed on your machine
- Basic knowledge of React.js
- Code editor (e.g., Visual Studio Code)
Step 1: Set Up a New React App
Create a new React app using Create React App:
npx create-react-app developer-portfolio
cd developer-portfolio
Step 2: Create Components
We are going to convert the main index file in StartBootsrap resume template into smaller components.
The file can be found here:- Github
We are going to copy protfolio sections from the above file and use HTML to JSX convertor like Magic ReactJS to get JSX based syntax for individual components. Below you will find the converted code added into different components.
Inside the `src` folder, create a new folder named components. Inside it, create a following components:
Navigation.js:
import React from "react";
export default function Navigation() {
return (
<nav
className="navbar navbar-expand-lg navbar-dark bg-primary fixed-top"
id="sideNav"
>
<a className="navbar-brand js-scroll-trigger" href="#page-top">
<span className="d-block d-lg-none">Saurabh Mhatre</span>
<span className="d-none d-lg-block">
<img
className="img-fluid img-profile rounded-circle mx-auto mb-2"
src="img/profile.png"
alt=""
/>
</span>
</a>
<button
className="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon" />
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav">
<li className="nav-item">
<a className="nav-link js-scroll-trigger" href="#about">
About
</a>
</li>
<li className="nav-item">
<a className="nav-link js-scroll-trigger" href="#experience">
Experience
</a>
</li>
<li className="nav-item">
<a className="nav-link js-scroll-trigger" href="#education">
Education
</a>
</li>
<li className="nav-item">
<a className="nav-link js-scroll-trigger" href="#skills">
Skills
</a>
</li>
<li className="nav-item">
<a className="nav-link js-scroll-trigger" href="#projects">
Projects
</a>
</li>
<li className="nav-item">
<a className="nav-link js-scroll-trigger" href="#interests">
Interests
</a>
</li>
<li className="nav-item">
<a className="nav-link js-scroll-trigger" href="#awards">
Awards
</a>
</li>
</ul>
</div>
</nav>
);
}
About.js:
export default function About() {
return (
<section className="resume-section" id="about">
<div className="resume-section-content">
<h1 className="mb-0">
Saurabh
<span className="text-primary">Native</span>
</h1>
<div className="subheading mb-5">Software Developer - Navi Mumbai</div>
<p className="lead mb-5">
I am experienced in building product websites, hybrid mobile
applications and backend development. My previous experience of
working in large product based companies as well as emerging startups
will surely help in product development for companies at various
stages.
</p>
<div className="social-icons">
<a
className="social-icon"
href="https://www.linkedin.com/in/saurabhnative/"
>
<i className="fab fa-linkedin-in" />
</a>
<a className="social-icon" href="https://github.com/saurabhnative">
<i className="fab fa-github" />
</a>
<a className="social-icon" href="https://twitter.com/saurabhnative">
<i className="fab fa-twitter" />
</a>
<a
className="social-icon"
href="https://www.youtube.com/channel/UCtWzTuAO-uEnGhrktGNPi0g/featured"
>
<i className="fab fa-youtube" />
</a>
<a className="social-icon" href="https://smhatre59.medium.com/">
<i className="fab fa-medium" />
</a>
</div>
</div>
</section>
);
}
Update name, job role, job details and social links as per your profile.
Experience .js:
export default function Experience() {
return (
<div>
<section className="resume-section" id="experience">
<div className="resume-section-content">
<h2 className="mb-5">Experience</h2>
<div className="d-flex flex-column flex-md-row justify-content-between mb-5">
<div className="flex-grow-1">
<h3 className="mb-0">Senior Web Developer</h3>
<div className="subheading mb-3">Crowdfire</div>
<p>
Building features in products of Crowdfire for social media
clients in order increase annual revenue. Making sure that the
product is stable, has lesser bugs and itegrating new
technologies which are production ready while keeping in sync
with product owners for daily business requirements.
</p>
</div>
<div className="flex-shrink-0">
<span className="text-primary">August 2018 - Present</span>
</div>
</div>
<div className="d-flex flex-column flex-md-row justify-content-between mb-5">
<div className="flex-grow-1">
<h3 className="mb-0">Web Developer</h3>
<div className="subheading mb-3">Burrp Pvt Limited</div>
<p>
Migrated old food ordering website to newer version using React
framework. Helped in building hybrid mobile applications using
React Native. Coordinated with design team and product owners
for inclusion of various features in order to improve brand
reach across various platforms.
</p>
</div>
<div className="flex-shrink-0">
<span className="text-primary">January 2018 - August 2018</span>
</div>
</div>
<div className="d-flex flex-column flex-md-row justify-content-between">
<div className="flex-grow-1">
<h3 className="mb-0">Fullstack developer</h3>
<div className="subheading mb-3">Reliance Jio</div>
<p>
Collaboratively worked with various media platforms to build
websites and mobile applications in Jio media applications
suite. Worked in server side development, devops and client side
platform development primarily using MERN stack, ReactNative and
Apple TV JS Framework.
</p>
</div>
<div className="flex-shrink-0">
<span className="text-primary">June 2015 - June 2017</span>
</div>
</div>
</div>
</section>
<hr className="m-0" />
</div>
);
}
Update your work experience in the above section.
Education.js:
export default function Education() {
return (
<div>
<section className="resume-section" id="education">
<div className="resume-section-content">
<h2 className="mb-5">Education</h2>
<div className="d-flex flex-column flex-md-row justify-content-between mb-5">
<div className="flex-grow-1">
<h3 className="mb-0">University of Mumbai</h3>
<div className="subheading mb-3">Bachelor of Engineering</div>
<div>
In Computer Science with One year Internship in Cloud Computing
</div>
<p>Percentage: Above 70% in all semesters</p>
</div>
<div className="flex-shrink-0">
<span className="text-primary">June 2011 - June 2015</span>
</div>
</div>
<div className="d-flex flex-column flex-md-row justify-content-between">
<div className="flex-grow-1">
<h3 className="mb-0">
Changu Kana Thakur High School and College
</h3>
<div className="subheading mb-3">
Computer Science Vocational + PCM group
</div>
<p>Percentage: 93.33(First rank in college in HSC/12th Std)</p>
</div>
<div className="flex-shrink-0">
<span className="text-primary">June 2009 - June 2011</span>
</div>
</div>
</div>
</section>
<hr className="m-0" />
</div>
);
}
Update your educational details in the above section.
Skills.js
export default function Skills() {
return (
<div>
<section className="resume-section" id="skills">
<div className="resume-section-content">
<h2 className="mb-5">Skills</h2>
<div className="subheading mb-3">
Programming Languages & Tools
</div>
<ul className="list-inline dev-icons">
<li className="list-inline-item">
<i className="fab fa-html5" />
</li>
<li className="list-inline-item">
<i className="fab fa-css3-alt" />
</li>
<li className="list-inline-item">
<i className="fab fa-js-square" />
</li>
<li className="list-inline-item">
<i className="fab fa-react" />
</li>
<li className="list-inline-item">
<i className="fab fa-node-js" />
</li>
<li className="list-inline-item">
<i className="fab fa-sass" />
</li>
<li className="list-inline-item">
<i className="fab fa-wordpress" />
</li>
<li className="list-inline-item">
<i className="fab fa-grunt" />
</li>
<li className="list-inline-item">
<i className="fab fa-npm" />
</li>
</ul>
<div className="subheading mb-3">Workflow</div>
<ul className="fa-ul mb-0">
<li>
<span className="fa-li">
<i className="fas fa-check" />
</span>
Mobile-First, Responsive Design
</li>
<li>
<span className="fa-li">
<i className="fas fa-check" />
</span>
MERN Stack development & Debugging
</li>
<li>
<span className="fa-li">
<i className="fas fa-check" />
</span>
Cross Functional Teams
</li>
<li>
<span className="fa-li">
<i className="fas fa-check" />
</span>
Agile Development & Scrum
</li>
</ul>
</div>
</section>
<hr className="m-0" />
</div>
);
}
Update skills as per your tech stack.
Next is Projects.js
export default function Projects() {
return (
<div>
<section className="resume-section" id="projects">
<div className="resume-section-content projects">
<h2 className="mb-1">Projects</h2>
<div className="subheading mb-2">Frontend projects</div>
<div className="d-flex row">
<div
className="card col-md-3 col-12 mx-2 mb-1"
style={{ width: "14rem" }}
>
<img
className="card-img-top"
src="img/RandomQuotes.png"
alt="Card image cap"
/>
<div className="card-body">
<h5 className="card-title">Random Advice using Javascript</h5>
<a
href="https://github.com/saurabhnative/randomadvicegenerator"
target="_blank"
className="btn btn-primary"
>
Github
</a>
<a
href="https://generateadvice.netlify.app/"
target="_blank"
className="btn btn-secondary"
>
Demo
</a>
</div>
</div>
<div
className="card col-md-3 col-12 mx-2 mb-1"
style={{ width: "16rem" }}
>
<img
className="card-img-top"
src="img/StoriesFeed.png"
alt="Card image cap"
/>
<div className="card-body">
<h5 className="card-title">Stories Feed App</h5>
<a
href="https://github.com/saurabhnative/storiesfeedapp"
target="_blank"
className="btn btn-primary"
>
Github
</a>
<a
href="https://stories-feed-app.netlify.app/"
target="_blank"
className="btn btn-secondary"
>
Demo
</a>
</div>
</div>
<div
className="card col-md-3 col-12 mx-2 mb-1"
style={{ width: "14rem" }}
>
<img
className="card-img-top"
src="img/IDCardGen.png"
alt="Card image cap"
/>
<div className="card-body">
<h5 className="card-title">ID Card Generator</h5>
<a
href="https://github.com/saurabhnative/react30_1_id_card_generator"
target="_blank"
className="btn btn-primary"
>
Github
</a>
<a
href="https://id-card-generator-2021.netlify.app/"
target="_blank"
className="btn btn-secondary"
>
Demo
</a>
</div>
</div>
</div>
</div>
</section>
{/* Interests*/}
<section className="resume-section" id="interests">
<div className="resume-section-content">
<h2 className="mb-5">Interests</h2>
<p>
Apart from being a web developer, I enjoy most of my time being
outdoors. On weekdays I go for walks daily. During the weekends I
attend latin dance classes and technical meetups. I also enjoy
trekking, exploring local cuisines and blogging.
</p>
<p className="mb-0">
When forced indoors, I follow a number of sci-fi and fantasy genre
movies and television shows, I am an aspiring blogger, and I spend a
large amount of my free time exploring the latest technology
advancements in the front-end web development world.
</p>
</div>
</section>
<hr className="m-0" />
</div>
);
}
Here I have added only three projects with images added in `public/img` folder. You can add all completed projects in the series. If the projects are more, then you upload project images to external image CDN like Cloudinary and add image URLs in project images section. You can update intereest section as well.
Last component is `Awards.js`:
export default function Awards() {
return (
<section className="resume-section" id="awards">
<div className="resume-section-content">
<h2 className="mb-5">Awards & Certifications</h2>
<ul className="fa-ul mb-0">
<li>
<span className="fa-li">
<i className="fas fa-trophy text-warning" />
</span>
Attended workshop on Deep Learning organised by Nvidia at IIT Bombay
</li>
<li>
<span className="fa-li">
<i className="fas fa-trophy text-warning" />
</span>
Data Science Masters Program - GreyAtom Certification
</li>
<li>
<span className="fa-li">
<i className="fas fa-trophy text-warning" />
</span>
Participation in national level React.js Conference at Goa
</li>
</ul>
</div>
</section>
);
}
Update awards as per your achievements.
Step 3: Update App Component
Update src/App.js to include the above components:
import "./styles.css";
import Navigation from "./components/Navigation";
import About from "./components/About";
import Experience from "./components/Experience";
import Education from "./components/Education";
import Skills from "./components/Skills";
import Projects from "./components/Projects";
import Awards from "./components/Awards";
export default function App() {
return (
<div id="page-top">
<Navigation />
<div className="container-fluid p-0">
<About />
<Experience />
<Education />
<Skills />
<Projects />
<Awards />
</div>
</div>
);
}
Step 4: Styling the app
Update styles.css from below file:
Step 5: Run the App
Run below command in terminal:
npm start
Visit http://localhost:3000 in your browser to see the online developer portfolio.
Source code:
Conclusion:
In this tutorial, we built an online developer portfolio using React.js by converting the static site resume code from the Start Bootstrap repository to JSX. This example demonstrates how to use React to create a dynamic and interactive portfolio. Feel free to customize the portfolio further based on your preferences and add additional features as needed.
Check out my YouTube channel for more content:-
Call for donation
Creating a series like React30 takes substantial amount of time and efforts. If you found this articles useful then consider donating a small amount to motivate me to write more such articles/tutorials in future.
Donate via Paypal | Buy me a coffee
Check out the next part in the series to learn about implementation of theme switching in react apps using useContext hook:-