As a software developer and tutor, creating a full-stack portfolio is an excellent way to showcase your skills, projects, and expertise. In this article, I’ll walk you through how to build a modern, responsive portfolio using the MERN stack (MongoDB, Express.js, React.js, and Node.js). By the end of this guide, you’ll have a fully functional portfolio that you can deploy and share with the world.
Why the MERN Stack?
The MERN stack is a popular choice for full-stack development because:
- JavaScript Everywhere: You use JavaScript for both frontend and backend development, making it easier to maintain.
- Scalability: MongoDB and Node.js are highly scalable, making them suitable for projects of any size.
- Community Support: With a large and active community, you’ll find plenty of resources and tutorials to help you along the way.
Portfolio Features
Our portfolio will include the following features:
- Homepage: A brief introduction and overview of your skills.
- Projects Section: A showcase of your work with descriptions and links.
- Blog/Tutorials Section: A space to share your knowledge as a tutor.
- Contact Form: A way for visitors to reach out to you.
Step 1: Setting Up the Project
1.1 Create the Project Structure
Start by creating a project folder and setting up the backend and frontend:
mkdir dhanian-portfolio
cd dhanian-portfolio
# Backend setup
mkdir backend
cd backend
npm init -y
npm install express mongoose cors dotenv
# Frontend setup
cd ..
npx create-react-app frontend
cd frontend
npm install axios react-router-dom
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
1.2 Backend Setup
The backend will handle the contact form submissions and serve as the API for your portfolio.
1.2.1 Create the Backend Structure
backend/
├── models/
├── routes/
├── controllers/
├── .env
├── server.js
1.2.2 Set Up the Server
In backend/server.js
, add the following code:
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const dotenv = require('dotenv');
dotenv.config();
const app = express();
const PORT = process.env.PORT || 5000;
// Middleware
app.use(cors());
app.use(express.json());
// MongoDB Connection
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err));
// Routes
app.get('/', (req, res) => {
res.send('Backend is running');
});
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
1.2.3 Add a Contact Model
Create a Contact
model in backend/models/Contact.js
:
const mongoose = require('mongoose');
const ContactSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true },
message: { type: String, required: true },
});
module.exports = mongoose.model('Contact', ContactSchema);
1.2.4 Add a Contact Route
Create a route for the contact form in backend/routes/contact.js
:
const express = require('express');
const router = express.Router();
const Contact = require('../models/Contact');
router.post('/', async (req, res) => {
const { name, email, message } = req.body;
try {
const newContact = new Contact({ name, email, message });
await newContact.save();
res.status(201).json({ message: 'Message sent successfully' });
} catch (err) {
res.status(500).json({ error: 'Server error' });
}
});
module.exports = router;
1.2.5 Update the Server to Use the Contact Route
In backend/server.js
, add:
const contactRoutes = require('./routes/contact');
app.use('/api/contact', contactRoutes);
1.3 Frontend Setup
The frontend will be built using React.js and styled with Tailwind CSS.
1.3.1 Configure Tailwind CSS
Update frontend/tailwind.config.js
:
module.exports = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
};
Add Tailwind to frontend/src/index.css
:
@tailwind base;
@tailwind components;
@tailwind utilities;
1.3.2 Create the Homepage
In frontend/src/components/Home.js
, add:
import React from 'react';
const Home = () => {
return (
<div className="min-h-screen bg-gray-100 flex items-center justify-center">
<h1 className="text-4xl font-bold text-blue-600">Welcome to Dhanian's Portfolio