Overview
Frontend-development
Frontend Development: Building Components with Tailwind CSS
In this module, you’ll learn how to build the frontend of a social media application similar to Twitter using Next.js 15 and Tailwind CSS. We’ll guide you through setting up the project, creating reusable components relevant to a social media platform, and styling them effectively. By the end of this module, you’ll have a solid understanding of how to build a modern, responsive web application using these cutting-edge technologies.
Estimated reading time: ~40 minutes
Table of Contents
- Introduction to Frontend Development
- Prerequisites
- Setting Up the Next.js 15 Project with Tailwind CSS
- Understanding Components in Next.js 15
- Building the Social Media App Components
- Navigation Bar
- Tweet/Post Component
- Feed Component
- Profile Component
- Styling with Tailwind CSS
- Using Utility Classes
- Responsive Design
- State Variants
- Fetching Data from the Backend
- Best Practices
- Conclusion
- Additional Resources
Introduction to Frontend Development
Frontend development focuses on building the user interface and experience of web applications. By using modern tools like Next.js and Tailwind CSS, developers can create efficient, scalable, and responsive applications.
- Next.js 15 is a React framework that enables server-side rendering, static site generation, and offers a new App Router architecture, making it ideal for building performant applications.
- Tailwind CSS is a utility-first CSS framework that allows you to style components directly in your markup, providing flexibility and efficiency.
In this module, we’ll combine these technologies to build the frontend of a social media app.
Prerequisites
Before starting, make sure you have:
- Basic knowledge of JavaScript, React, and TypeScript
- Node.js 18.18 or later installed: Verify by running
node -v
- Code Editor: VS Code is recommended
- Understanding of CSS fundamentals
Setting Up the Next.js 15 Project with Tailwind CSS
1. Verify Node.js Installation
Ensure you have Node.js 18.18 or later installed:
node -v
If not, download and install the latest version from the Node.js official website.
2. Create a New Next.js App
Run the following command to create a new Next.js 15 project:
npx create-next-app@latest
Configuration Options
During setup, you’ll be prompted to configure your project. For this application, consider the following options:
- What is your project named?
social-media-app
- Would you like to use TypeScript?
Yes
- Would you like to use ESLint?
Yes
- Would you like to use Tailwind CSS?
Yes
- Would you like to use
src/
directory?No
(orYes
, depending on your preference) - Would you like to use App Router? (recommended)
Yes
- Would you like to customize the default import alias?
Yes
(accept the default@/*
)
These settings provide a robust foundation for your application.
Navigate to the project directory:
cd social-media-app
3. Project Structure
Next.js 15 introduces the App Router, which utilizes the app/
directory for routing. Your project structure should look like this:
social-media-app/
├── app/
│ ├── layout.tsx
│ ├── page.tsx
│ └── api/
├── public/
├── styles/
├── next.config.js
├── package.json
└── tsconfig.json
app/layout.tsx
: Defines the root layout of your application.app/page.tsx
: Serves as the main entry point for your application.app/api/
: Contains API route handlers.
4. Tailwind CSS Setup
Since you selected Tailwind CSS during project setup, it is already configured. Verify the tailwind.config.js
file:
// tailwind.config.js
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx}', // Include the app directory
'./components/**/*.{js,ts,jsx,tsx}', // Include the components directory
],
theme: {
extend: {},
},
plugins: [],
};
Ensure that Tailwind directives are included in your global CSS file (styles/globals.css
):
@tailwind base;
@tailwind components;
@tailwind utilities;
5. Start the Development Server
Run the development server:
npm run dev
Visit http://localhost:3000
to see your Next.js app running.
Understanding Components in Next.js 15
In Next.js 15, components are organized within the app
directory. Each folder inside app
can contain:
- Page Components: The main content for each page on your site.
- Named
page.tsx
orpage.jsx
- Named
- Layout Components: Create a consistent look and feel across multiple pages, such as a header, footer, or navbar.
- Named
layout.tsx
orlayout.jsx
- Named
- Server Components: Fetch and render content on the server, ideal for static or SEO-friendly content.
- Default type for components in Next.js 15’s
app
directory.
- Default type for components in Next.js 15’s
- Client Components: Enable interactivity and handle user interactions.
- Defined by adding
'use client';
at the top of the file.
- Defined by adding
Note: Next.js 15 supports React 19, which introduces features like Server Actions and improved hydration error handling.
Building the Social Media App Components
We’ll build the following components:
- Navigation Bar
- Tweet/Post Component
- Feed Component
- Profile Component
Folder Structure
Organize your components within the app
and components
directories:
social-media-app/
├── app/
│ ├── feed/
│ │ ├── page.tsx
│ │ └── Tweet.tsx
│ ├── profile/
│ │ ├── page.tsx
│ │ └── ProfileInfo.tsx
│ ├── layout.tsx
│ └── page.tsx
├── components/
│ └── Navbar.tsx
└── styles/
└── globals.css
Navigation Bar
1. Create the Navbar Component
Create a components
directory and add Navbar.tsx
:
// components/Navbar.tsx
'use client';
import Link from 'next/link';
import Image from 'next/image';
export default function Navbar() {
return (
<nav className="bg-white border-b border-gray-200">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between h-16">
<div className="flex">
<Link href="/" className="flex-shrink-0 flex items-center">
<Image
className="h-8 w-8"
src="/logo.svg"
alt="Logo"
width={32}
height={32}
/>
<span className="ml-2 font-bold text-xl">MySocialApp</span>
</Link>
<div className="hidden sm:-my-px sm:ml-6 sm:flex sm:space-x-8">
<Link href="/feed" className="inline-flex items-center px-1 pt-1 text-sm font-medium text-gray-900">
Home
</Link>
<Link href="/profile" className="inline-flex items-center px-1 pt-1 text-sm font-medium text-gray-500 hover:text-gray-700">
Profile
</Link>
</div>
</div>
<div className="flex items-center">
<button className="text-sm font-medium text-gray-500 hover:text-gray-700">Logout</button>
</div>
</div>
</div>
</nav>
);
}
Explanation:
- Uses Next.js
Link
component for navigation. - Includes links to Home and Profile.
- Utilizes Tailwind CSS classes for styling.
2. Include Navbar in the Layout
Update app/layout.tsx
:
// app/layout.tsx
import '../styles/globals.css';
import Navbar from '@/components/Navbar';
import { ReactNode } from 'react';
export const metadata = {
title: 'MySocialApp',
description: 'A social media app built with Next.js 15 and Tailwind CSS',
};
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en">
<body>
<Navbar />
{children}
</body>
</html>
);
}
Tweet/Post Component
1. Create the Tweet Component
Create app/feed/Tweet.tsx
:
// app/feed/Tweet.tsx
'use client';
import Image from 'next/image';
interface TweetProps {
tweet: {
id: number;
username: string;
handle: string;
time: string;
content: string;
comments: number;
retweets: number;
likes: number;
};
}
export default function Tweet({ tweet }: TweetProps) {
return (
<div className="border-b border-gray-200 p-4">
<div className="flex">
<Image
className="h-12 w-12 rounded-full"
src="/default-avatar.png"
alt="User Avatar"
width={48}
height={48}
/>
<div className="ml-3">
<div className="flex items-center">
<span className="font-bold">{tweet.username}</span>
<span className="ml-2 text-sm text-gray-500">@{tweet.handle}</span>
<span className="ml-2 text-sm text-gray-500">· {tweet.time}</span>
</div>
<p className="mt-1">{tweet.content}</p>
<div className="flex mt-2 space-x-4 text-gray-500">
<button className="flex items-center space-x-1 hover:text-blue-500">
{/* Add SVG icons or use icon libraries */}
<span>{tweet.comments}</span>
</button>
<button className="flex items-center space-x-1 hover:text-green-500">
<span>{tweet.retweets}</span>
</button>
<button className="flex items-center space-x-1 hover:text-red-500">
<span>{tweet.likes}</span>
</button>
</div>
</div>
</div>
</div>
);
}
Explanation:
- Displays tweet content with user information.
- Uses TypeScript for type safety.
- Styled with Tailwind CSS.
Feed Component
1. Create the Feed Page
Create app/feed/page.tsx
:
// app/feed/page.tsx
import Tweet from './Tweet';
interface TweetData {
id: number;
username: string;
handle: string;
time: string;
content: string;
comments: number;
retweets: number;
likes: number;
}
export default function FeedPage() {
const tweets: TweetData[] = [
{
id: 1,
username: 'John Doe',
handle: 'johndoe',
time: '2h',
content: 'This is my first tweet!',
comments: 5,
retweets: 2,
likes: 20,
},
// Add more tweet objects
];
return (
<div className="max-w-2xl mx-auto mt-4">
{tweets.map((tweet) => (
<Tweet key={tweet.id} tweet={tweet} />
))}
</div>
);
}
Explanation:
- Renders a list of tweets using the
Tweet
component. - Simulates fetching data from a backend.
Profile Component
1. Create the ProfileInfo Component
Create app/profile/ProfileInfo.tsx
:
// app/profile/ProfileInfo.tsx
'use client';
import Image from 'next/image';
export default function ProfileInfo() {
return (
<div className="border-b border-gray-200 p-4">
<div className="relative">
<div className="h-32 bg-gray-200"></div>
<Image
className="absolute -bottom-12 left-4 h-24 w-24 rounded-full border-4 border-white"
src="/default-avatar.png"
alt="User Avatar"
width={96}
height={96}
/>
</div>
<div className="mt-16 px-4">
<h1 className="text-xl font-bold">John Doe</h1>
<p className="text-gray-500">@johndoe</p>
<p className="mt-2">Bio goes here. This is a brief description about the user.</p>
<div className="flex mt-2 space-x-4 text-gray-500">
<span>
<strong>100</strong> Following
</span>
<span>
<strong>200</strong> Followers
</span>
</div>
</div>
</div>
);
}
Explanation:
- Displays user’s profile information.
- Styled with Tailwind CSS.
2. Create the Profile Page
Create app/profile/page.tsx
:
// app/profile/page.tsx
import ProfileInfo from './ProfileInfo';
import Tweet from '../feed/Tweet';
interface TweetData {
id: number;
username: string;
handle: string;
time: string;
content: string;
comments: number;
retweets: number;
likes: number;
}
export default function ProfilePage() {
const tweets: TweetData[] = [
{
id: 1,
username: 'John Doe',
handle: 'johndoe',
time: '1h',
content: 'Hello from my profile!',
comments: 2,
retweets: 1,
likes: 10,
},
// Add more tweet objects
];
return (
<div className="max-w-2xl mx-auto mt-4">
<ProfileInfo />
{tweets.map((tweet) => (
<Tweet key={tweet.id} tweet={tweet} />
))}
</div>
);
}
Explanation:
- Combines
ProfileInfo
and user’s tweets. - Reuses
Tweet
component for consistency.
Styling with Tailwind CSS
Using Utility Classes
Tailwind CSS utility classes allow you to style components directly in your markup.
Examples:
- Layout and Spacing:
flex
,grid
,block
p-4
(padding),m-4
(margin)
- Typography:
text-xl
,font-bold
,text-gray-500
- Colors:
bg-white
,bg-gray-200
,text-blue-500
- Borders and Shadows:
border
,border-gray-200
,rounded-full
Responsive Design
Tailwind provides responsive variants using breakpoint prefixes.
Breakpoints:
sm
— 640pxmd
— 768pxlg
— 1024pxxl
— 1280px2xl
— 1536px
Usage Example:
<div class="text-base md:text-lg lg:text-xl">
Responsive Text Size
</div>
State Variants
Style components based on interaction states like hover, focus, and active.
Hover State:
<button class="text-gray-500 hover:text-blue-500">
Like
</button>
Fetching Data from the Backend
In a real application, you would fetch data from your backend API.
1. Creating API Routes
Next.js 15 allows you to create API routes within the app/api/
directory.
Example:
Create app/api/tweets/route.ts
:
// app/api/tweets/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
const tweets = [
{
id: 1,
username: 'John Doe',
handle: 'johndoe',
time: '2h',
content: 'This is my first tweet!',
comments: 5,
retweets: 2,
likes: 20,
},
// Add more tweet objects or fetch from a database
];
return NextResponse.json(tweets);
}
2. Fetching Data in Server Components
Update app/feed/page.tsx
to fetch data from the API:
// app/feed/page.tsx
import Tweet from './Tweet';
export default async function FeedPage() {
const res = await fetch('<http://localhost:3000/api/tweets>', { cache: 'no-store' });
const tweets = await res.json();
return (
<div className="max-w-2xl mx-auto mt-4">
{tweets.map((tweet: any) => (
<Tweet key={tweet.id} tweet={tweet} />
))}
</div>
);
}
Notes:
- Use
{ cache: 'no-store' }
to prevent caching. - Ensure your API is correctly set up.
3. Using Client Components for Interactivity
For interactive components, define them as Client Components:
// components/InteractiveComponent.tsx
'use client';
import { useState } from 'react';
export default function InteractiveComponent() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Clicked {count} times
</button>
);
}
Best Practices
- Component Reusability:
- Create reusable components like
Tweet
,ProfileInfo
, andNavbar
. - Keep components focused and maintainable.
- Create reusable components like
- Organize Your Project:
- Use a logical folder structure.
- Separate components, pages, and styles.
- Optimize Images:
- Use Next.js
Image
component for optimized images. - Provide
width
andheight
for better performance.
- Use Next.js
- Responsive Design:
- Ensure your app looks good on all screen sizes.
- Test on mobile, tablet, and desktop views.
- Accessibility:
- Use semantic HTML elements.
- Provide
alt
text for images. - Ensure sufficient color contrast.
- Consistent Styling:
- Stick to a consistent color palette and typography.
- Customize the Tailwind config file (
tailwind.config.js
) if needed.
- Data Fetching Strategies:
- Use Server Components for data fetching when possible.
- Use Client Components for interactivity.
- Error Handling:
- Handle errors when fetching data.
- Provide user feedback for loading states.
- Leverage Next.js 15 Features:
- Utilize React 19 features like Server Actions.
- Explore Partial Prerendering for performance.
- Development Tools:
- Use Turbopack for faster development builds.
Conclusion
Congratulations! You’ve learned how to:
- Set up a Next.js 15 project with Tailwind CSS.
- Understand and create components relevant to a social media app.
- Use Tailwind CSS utility classes to style your components.
- Build a responsive and modern frontend application.
- Fetch data from a backend API in Next.js.
- Leverage new features in Next.js 15, including React 19 support.
By mastering these concepts, you’re well on your way to building full-stack web applications.
Additional Resources
- Next.js Documentation: nextjs.org/docs
- Tailwind CSS Documentation: tailwindcss.com/docs
- Next.js 15 App Router Guide: nextjs.org/docs/app
- Tutorials:
- Next.js 15 Crash Course (Update with actual link when available)
- Building a Twitter Clone with Next.js 15 and Tailwind CSS (Update with actual link when available)
- Component Libraries:
- Authentication:
- State Management:
- Explore using React Context or Redux for global state.
🎉 Congratulations! You’ve completed the Frontend Development module. Continue building on this foundation by adding more features and refining your application.