Building a Simple Social Network Web App with Next.js
A Hands-On Tutorial
In the exciting journey of mastering a new programming language, nothing beats the hands-on experience of building a real-world project. The practical application of concepts not only solidifies your understanding but also equips you with an impressive portfolio to showcase to potential employers. In this tutorial, we’ll embark on a journey to build a simple social network web app using Next.js — a powerful React framework. By the end of this tutorial, you’ll have a functional social network prototype, along with a deeper understanding of Next.js, React, and database integration.
Understanding the Project: A Simple Social Network
Before we dive into the code, let’s outline the project’s key features and components.
Key Features:
- User authentication and registration.
- User profiles with profile pictures and basic information.
- Creating, editing, and deleting posts.
- Liking and commenting on posts.
- Real-time updates using WebSockets.
Tech Stack:
- Next.js: A React framework for server-side rendering and routing.
- Firebase: A cloud-based platform for authentication and real-time database.
- Tailwind CSS: A utility-first CSS framework for efficient styling.
Step 1: Setting Up Your Project
First, ensure you have Node.js and npm (Node Package Manager) installed on your machine. Open your terminal and create a new Next.js project:
npx create-next-app my-social-networkNavigate to the project directory:
cd my-social-networkInstall the required dependencies:
npm install firebase tailwindcss
Step 2: Setting Up Firebase
Firebase will serve as our authentication and real-time database solution. Create a Firebase project and obtain your configuration settings from the Firebase console.
Authentication:
- Enable Email/Password authentication in the Firebase console.
- In the Next.js project, create a file named
firebase.jsin the root directory. Add your Firebase configuration:
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
const firebaseConfig = {
apiKey: 'YOUR_API_KEY',
authDomain: 'YOUR_AUTH_DOMAIN',
projectId: 'YOUR_PROJECT_ID',
storageBucket: 'YOUR_STORAGE_BUCKET',
messagingSenderId: 'YOUR_MESSAGING_SENDER_ID',
appId: 'YOUR_APP_ID',
};
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
}
export const auth = firebase.auth();
export const firestore = firebase.firestore();Real-time Database:
- Create a Firestore database in the Firebase console.
- Set up rules to secure your database (optional, but recommended).
Step 3: Building the User Authentication System
Authentication is the cornerstone of any social network. Let’s create a user registration and login system.
- Create a
componentsfolder in the project directory. Inside, createAuthForm.js:
import { useState } from 'react';
import { auth } from '../firebase';
const AuthForm = ({ isRegister }) => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
try {
if (isRegister) {
await auth.createUserWithEmailAndPassword(email, password);
} else {
await auth.signInWithEmailAndPassword(email, password);
}
} catch (error) {
console.error('Authentication Error:', error);
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="email"
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<input
type="password"
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">{isRegister ? 'Register' : 'Login'}</button>
</form>
);
};
export default AuthForm;- In the
pagesfolder, createlogin.jsandregister.js:
import AuthForm from '../components/AuthForm';
const Login = () => {
return (
<div>
<h1>Login</h1>
<AuthForm />
</div>
);
};
export default Login;import AuthForm from '../components/AuthForm';
const Register = () => {
return (
<div>
<h1>Register</h1>
<AuthForm isRegister />
</div>
);
};
export default Register;Step 4: Designing User Profiles and Posts
Now, let’s create user profiles and the ability to create posts.
- In the
componentsfolder, createProfile.js:
import { useState, useEffect } from 'react';
import { auth, firestore } from '../firebase';
const Profile = () => {
const [user, setUser] = useState(null);
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((authUser) => {
if (authUser) {
firestore.collection('users').doc(authUser.uid).get()
.then((doc) => {
if (doc.exists) {
setUser(doc.data());
}
});
} else {
setUser(null);
}
});
return () => unsubscribe();
}, []);
return (
<div>
{user ? (
<div>
<img src={user.photoURL} alt={user.displayName} />
<h2>{user.displayName}</h2>
</div>
) : (
<p>Please login to see your profile</p>
)}
</div>
);
};
export default Profile;- In the
pagesfolder, createprofile.js:
import Profile from '../components/Profile';
const ProfilePage = () => {
return (
<div>
<h1>Your Profile</h1>
<Profile />
</div>
);
};
export default ProfilePage;Step 5: Implementing Post Creation and Display
Now, let’s allow users to create and display posts.
- In the
componentsfolder, createPostForm.js:
import { useState } from 'react';
import { firestore, auth } from '../firebase';
const PostForm = () => {
const [content, setContent] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
try {
if (content) {
await firestore.collection('posts').add({
content,
userId: auth.currentUser.uid,
createdAt: new Date(),
});
setContent('');
}
} catch (error) {
console.error('Error creating post:', error);
}
};
return (
<form onSubmit={handleSubmit}>
<textarea
placeholder="Write your post..."
value={content}
onChange={(e) => setContent(e.target.value)}
/>
<button type="submit">Post</button>
</form>
);
};
export default PostForm;- In the
componentsfolder, createPost.js:
import { useState, useEffect } from 'react';
import { firestore } from '../firebase';
const Post = ({ postId, content, userId, createdAt }) => {
const [user, setUser] = useState(null);
useEffect(() => {
firestore.collection('users').doc(userId).get()
.then((doc) => {
if (doc.exists) {
setUser(doc.data());
}
});
}, [userId]);
return (
<div>
{user && (
<div>
<img src={user.photoURL} alt={user.displayName} />
<h3>{user.displayName}</h3>
</div>
)}
<p>{content}</p>
<p>{createdAt.toDate().toLocaleString()}</p>
</div>
);
};
export default Post;- In the
pagesfolder, createfeed.js:
import { useState, useEffect } from 'react';
import { firestore } from '../firebase';
import PostForm from '../components/PostForm';
import Post from '../components/Post';
const Feed = () => {
const [posts, setPosts] = useState([]);
useEffect(() => {
const unsubscribe = firestore.collection('posts')
.orderBy('createdAt', 'desc')
.onSnapshot((snapshot) => {
setPosts(snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
})));
});
return () => unsubscribe();
}, []);
return (
<div>
<h1>Feed</h1>
<PostForm />
{posts.map((post) => (
<Post key={post.id} {...post} />
))}
</div>
);
};
export default Feed;Step 6: Adding Real-Time Updates with WebSockets
To enable real-time updates, we’ll integrate WebSockets using Firebase’s Firestore real-time listeners.
- In the
componentsfolder, updatePost.js:
// ... (previous code)
import { firestore } from '../firebase';
const Post = ({ postId, content, userId, createdAt }) => {
// ... (previous code)
useEffect(() => {
// ... (previous code)
const unsubscribe = firestore.collection('posts').doc(postId)
.onSnapshot((snapshot) => {
if (snapshot.exists) {
const updatedPost = snapshot.data();
setContent(updatedPost.content);
}
});
return () => unsubscribe();
}, [postId]);
return (
<div>
{/* ... (previous code) */}
</div>
);
};
export default Post;Step 7: Styling with Tailwind CSS
Finally, let’s enhance the visual appeal of our social network using Tailwind CSS.
- Open the
styles/globals.cssfile and add the following:
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';- Create a
tailwind.config.jsfile in the project root and customize your styles:
module.exports = {
purge: [],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
};Conclusion
Congratulations! You’ve successfully built a simple social network web app using Next.js. Through this hands-on project, you’ve gained insights into setting up authentication, real-time databases, user profiles, post creation, and real-time updates. By expanding on this foundation, you can add more features like user authentication, commenting, and user interactions to create a more robust social network platform. Remember, practical experience is key to mastering any technology, and this project is just the beginning of your coding journey.
The skills you’ve honed in this project — Next.js, Firebase, React, and Tailwind CSS — are valuable assets that can help you embark on even more ambitious web development projects. Whether you’re aiming to enhance your portfolio, learn new concepts, or prepare for job interviews, this simple social network web app serves as a testament to your dedication and growth as a programmer. Happy coding!
And there you have it — a step-by-step tutorial on how to build a simple social network web app using Next.js, Firebase, React, and Tailwind CSS. Remember, practice makes perfect, so don’t hesitate to modify and expand upon this project as you continue your web development journey.
In Plain English
Thank you for being a part of our community! Before you go:
- Be sure to clap and follow the writer! 👏
- You can find even more content at PlainEnglish.io 🚀
- Sign up for our free weekly newsletter. 🗞️
- Follow us on Twitter, LinkedIn, YouTube, and Discord.





