Building a Cutting-Edge Commercial Website with Next.js 15, TypeScript, and Tailwind CSS π
Welcome to an in-depth look at my latest project: a commercial website built with the latest technologies to provide a seamless, responsive, and blazing-fast user experience! In this blog post, Iβll walk you through the features, tech stack, and highlights of this project.
π Project Overview
This website is designed to meet modern business needs with:
- Fast and reliable performance
- Scalability
- A visually appealing and consistent design
πΌ Key Features
Here are the core features of this commercial website:
Home Page
The landing page provides users with a captivating introduction to the business.Request a Quote Page
A dedicated page for users to request customized service quotes easily.About Page
Learn more about the companyβs mission, values, and vision.Blog Page
Dynamic content is fetched via an API to keep users updated with the latest articles and insights.Blog Detail Page
Supports dynamic routes to display individual blog posts seamlessly.Pricing Page
Transparent pricing plans to fit varying customer needs.Services Page
A showcase of the wide range of services the business offers.Use Cases Page
Real-world examples of how the solutions can benefit different industries.
π¨ Tech Stack
The website is powered by the following technologies:
Next.js 15
The latest version of Next.js provides server-side rendering (SSR) and incremental static regeneration (ISR) for a high-performance experience.TypeScript
Ensures code quality, maintainability, and scalability for the future.Tailwind CSS
A utility-first CSS framework for building beautiful, responsive designs quickly and consistently.
π Structure and Dynamic Routing
The blog section uses dynamic routes with Next.js. This allows for a structured yet flexible approach to managing individual blog pages. By fetching data via API calls, the blog remains dynamic and easy to maintain.
Example of a dynamic route: app/blog/[slug]/page.tsx
import Image from 'next/image'
import Link from 'next/link'
import { IoCalendarClearOutline as CalendarDays, IoTimeOutline as Clock, IoArrowBack as ArrowLeft} from "react-icons/io5";
import BlogCard from '@/components/BlogCard'
import SocialMedia from '@/components/SocialMedia'
import { Post, Author } from '@/app/utils/types';
async function getPost(slug: string): Promise<Post> {
const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${slug}`);
if (!res.ok) throw new Error('Failed to fetch post');
return res.json();
}
async function getAuthor(userId: number): Promise<Author> {
const res = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`)
if (!res.ok) throw new Error('Failed to fetch author')
return res.json()
}
async function getRelatedPosts(): Promise<Post[]> {
const res = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=3')
if (!res.ok) throw new Error('Failed to fetch related posts')
return res.json()
}
async function getFeaturedPosts(): Promise<Post[]> {
const res = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=3')
if (!res.ok) throw new Error('Failed to fetch featured posts')
return res.json()
}
export default async function BlogPost({ params }: { params: { slug: string } }) {
const { slug } = await params;
const post = await getPost(slug)
const author = await getAuthor(post.userId)
const relatedPosts = await getRelatedPosts()
const featuredPosts = await getFeaturedPosts()
const postUrl = "https://www.example.com/blog/my-awesome-post";
const postTitle = "My Awesome Blog Post";
return (
<div className="min-h-screen py-24">
<div className="container mx-auto px-4">
<Link
href="/blog"
className="inline-flex items-center text-black font-bold hover:text-primary transition-colors mb-8"
>
<ArrowLeft className="w-4 h-4 mr-2" /> Back to Blog
</Link>
<div className="flex flex-col lg:flex-row gap-8">
<div className="lg:w-2/3">
<div className="bg-white rounded-4xl p-8 border-1 border-black shadow-[0px_6px_0px_0px_rgba(0,0,0,1)]">
<div className="relative w-full h-64 mb-8">
<Image
src={`https://picsum.photos/seed/${post.id}/800/600`}
alt={post.title}
fill
priority
sizes="(max-width: 768px) 100vw, 50vw"
className="rounded-3xl object-cover"
/>
</div>
<h1 className="text-4xl font-bold mb-4">{post.title}</h1>
<div className="flex items-center mb-6">
<div className="w-10 h-10 bg-gray-300 rounded-full mr-4"></div>
<div>
<p className="font-bold">{author.name}</p>
<div className="flex items-center text-sm text-gray-500">
<CalendarDays className="w-4 h-4 mr-1" />
{new Date().toISOString().split('T')[0]}
<span className="mx-2">β’</span>
<Clock className="w-4 h-4 mr-1" />
{Math.floor(Math.random() * 10) + 3} min read
</div>
</div>
</div>
<div className="prose max-w-none">
<p>{post.body}</p>
<p>{post.body}</p>
<p>{post.body}</p>
</div>
<div className="mt-16">
<SocialMedia linksType="share" url={postUrl} title={postTitle} />
</div>
</div>
</div>
<div className="lg:w-1/3 space-y-8">
<div className="bg-white rounded-4xl p-6 border-1 border-black shadow-[0px_6px_0px_0px_rgba(0,0,0,1)]">
<h2 className="text-2xl font-bold mb-4">Featured Posts</h2>
<div className="space-y-4">
{featuredPosts.map((featuredPost) => (
<div key={featuredPost.id} className="border-b border-gray-200 pb-4 last:border-b-0 last:pb-0">
<div className="relative w-full h-40 mb-2">
<Image
src={`https://picsum.photos/seed/${featuredPost.id}/800/600`}
alt={featuredPost.title}
fill
sizes="(max-width: 768px) 100vw, 50vw"
className="rounded-xl object-cover"
/>
</div>
<Link href={`/blog/${featuredPost.id}`}>
<h3 className="font-bold hover:text-primary transition-colors">{featuredPost.title}</h3>
</Link>
<p className="text-sm text-gray-500">{new Date().toISOString().split('T')[0]}</p>
</div>
))}
</div>
</div>
</div>
</div>
<div className="mt-12">
<h2 className="text-3xl font-bold mb-6">Related Posts</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{relatedPosts.map((relatedPost) => (
<BlogCard
key={relatedPost.id}
title={relatedPost.title}
excerpt={relatedPost.body.slice(0, 100) + '...'}
slug={relatedPost.id.toString()}
coverImage={`https://picsum.photos/seed/${relatedPost.id}/800/600`}
date={new Date().toISOString().split('T')[0]}
category={['Marketing', 'Design', 'Development'][Math.floor(Math.random() * 3)]}
readTime={`${Math.floor(Math.random() * 10) + 3} min read`}
/>
))}
</div>
</div>
</div>
</div>
)
}
π Resources and Downloads
Download Full Code: Get the complete project files here π Download Full code π Download
β€οΈ Show Some Love!
Enjoy the video, and don't forget to like, share, and subscribe for more amazing projects!
Support me β€οΈ Support Me
π Conclusion
This project demonstrates the power and flexibility of modern web development tools like Next.js, TypeScript, and Tailwind CSS. Whether youβre building a blog, a business site, or a portfolio, these technologies provide the foundation for exceptional user experiences.
Let me know your thoughts in the comments below or connect with me for feedback and discussions!
β€οΈ Thank you for reading!
Top comments (0)