Introduction to Next.js and Building a Portfolio Site with Next.jsπŸš€βœ¨

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MyrinNew
    Senior Member
    • Feb 2024
    • 5175

    #1

    Introduction to Next.js and Building a Portfolio Site with Next.jsπŸš€βœ¨

    Introduction to Next.js

    NextJS is a powerful React framework that enables developers to build performant and scalable web applications with ease. This documentation will guide you through creating a portfolio site using NextJS.


    Key NextJS Features

    App Router

    NextJS 13+ introduces the App Router, a new routing system that provides:
    • File-based routing
    • Nested layouts
    • Simplified data fetching
    • Automatic code splitting
    • Server and client components


    Example of Routing Structure





    app/
    β”œβ”€β”€ page.tsx # Main landing page
    β”œβ”€β”€ about/
    β”‚ └── page.tsx # About page
    β”œβ”€β”€ projects/
    β”‚ └── page.tsx # Projects page
    └── layout.tsx # Global layout







    Performance Optimizations

    NextJS offers multiple optimization techniques:
    • Automatic image optimization
    • Lazy loading of components
    • Static and server-side rendering
    • Incremental Static Regeneration (ISR)
    • Automatic code splitting


    Package Management

    package-lock.json

    • Locks dependency versions precisely
    • Ensures consistent builds across different environments
    • Prevents unexpected package updates
    • Improves build reproducibility


    Components in NextJS

    Server Components

    • Render on the server
    • Reduce client-side JavaScript
    • Improve initial page load performance
    • Default in App Router


    Client Components

    • Interactive components
    • Use client-side rendering
    • Enable state and event handling
    • Marked with 'use client' directive


    Project Setup

    Clone the repo





    git clone https://github.com/Headstarter-AI-KN...-Portfolio.git







    Initial Configuration





    npm install







    This command:
    • Read the package.json file
    • Download and install all listed dependencies
    • Create a node_modules folder
    • Generate or update the package-lock.json file to ensure
      consistent installations across different environments


    Diving into the codes

    Overview

    The Portfolio is a React functional component that composes multiple section components into a single page layout.


    Page file contents

    Component Imports





    import React from "react";
    import HeroSection from "./components/hero-section/HeroSection";
    import ServiceSection from "./components/service-section/ServiceSection";
    import Navbar from "./components/navbar/Navbar";
    import ContactSection from "./components/contact-section/ContactSection";
    import BrandSection from "./components/brand-section/BrandSection";
    import Footer from "./components/footer/Footer";







    Component Layout





    const Portfolio = () => {
    return (

    Navbar />
    HeroSection />
    div className="min-h-screen p-8 pt-0">
    BrandSection />
    ServiceSection />
    ContactSection />
    Footer />
    div>
    >
    );
    };







    Key Observations

    • Uses React Fragment (...>) for wrapping components
    • Utilizes a container div with utility classes for spacing
    • Follows a top-to-bottom page composition strategy
    • Separates Navbar and HeroSection from other content sections


    Component Sections

    1. Navbar: Site navigation
    2. HeroSection: Landing/introduction area
    3. BrandSection: Brand or client showcase
    4. ServiceSection: Services or capabilities overview
    5. ContactSection: Contact information or form
    6. Footer: Page footer/additional links


    Navbar Component:

    • Scroll-Aware Design:
      • The navbar dynamically changes its appearance (e.g., shadow and backdrop blur) based on the user’s scroll position. This ensures visibility while maintaining aesthetic appeal.
      • Accomplished using the useEffect hook and the scrollY property from the window object.




    useEffect(() => {
    const handleScroll = () => {
    setIsScrolled(window.scrollY > 0);
    };
    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
    }, []);
    • Copy-to-Clipboard Functionality:
      • Includes a button that lets users copy an email address directly to their clipboard using the navigator.clipboard API.




    const copyEmail = () => {
    navigator.clipboard.writeText("isaacoboenimil@gmai l.com");
    };
    • Responsive Mobile Menu:
      • The navbar adapts to smaller screen sizes by including a mobile menu button (Menu and X icons from Lucide).
      • When toggled, the menu displays navigation links and actions in a user-friendly way for mobile devices.




    Button
    variant="ghost"
    onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
    className="inline-flex items-center justify-center p-2"
    >
    {isMobileMenuOpen ? X className="h-6 w-6" /> : Menu className="h-6 w-6" />}
    Button>
    • Desktop and Mobile Navigation Links:
      • Provides social links (e.g., LinkedIn, Dribbble, Instagram) as well as buttons for copying an email or accessing a CV.
      • These are conditionally rendered based on screen size using Tailwind CSS’s utility classes (e.g., hidden md:flex).


    HeroSection Component

    Imports





    import { Button } from "@/components/ui/button";
    import Image from "next/image";
    import React from "react";
    • Button Component: The button is imported from a custom UI library (@/components/ui/button). This approach indicates a modular design for reusability across the app.
    • Image Component: The Image component is part of Next.js. It’s a powerful tool for optimizing images in web applications, providing features like lazy loading, responsive sizing, and automatic format selection (e.g., WebP).
    • React: A foundational import for all React components.


    HeroSection Function





    function HeroSection() {
    return (
    section className="grid min-h-[70vh] place-content-center rounded-b-[100px] bg-stone-400/50 p-10 text-center">
    ...
    /section>
    );
    }







    Details on Styling the Section





    section className="grid min-h-[70vh] place-content-center rounded-b-[100px] bg-stone-400/50 p-10 text-center">
    • grid: Establishes a grid layout. Combined with place-content-center, it centers the content both horizontally and vertically.
    • min-h-[70vh]: Ensures the hero section takes up at least 70% of the viewport height.
    • rounded-b-[100px]: Applies a custom, large rounded border radius to the bottom, adding a soft curve for a modern aesthetic.
    • bg-stone-400/50: Sets a semi-transparent light gray background with Tailwind's opacity feature (/50).
    • p-10: Adds padding around the section.
    • text-center: Centers all text content inside this section.


    Image Component





    Image
    width={300}
    height={300}
    src="/assets/images/images.jpeg"
    alt="Profile"
    className="mx-auto mb-4 h-40 w-40 rounded-full object-cover"
    />
    • Optimization: The Image component ensures better performance through optimized loading and resizing.
    • Props:
      • src: Path to the image. Here, it’s served from /assets/images/images.jpeg.
      • alt: Alt text for accessibility and SEO purposes.
      • width and height: Fixed dimensions for better performance.
    • Styling:
      • mx-auto: Horizontally centers the image.
      • h-40 w-40: Defines fixed height and width (10rem each).
      • rounded-full: Creates a circular image.
      • object-cover: Ensures the image scales without distortion.


    Heading





    h1 className="mb-4 text-4xl font-bold">
    Building digital
    br />
    products, brands, and
    br />
    experience.
    /h1>
    • mb-4: Adds margin-bottom for spacing.
    • text-4xl: Sets a large font size.
    • font-bold: Applies bold styling for emphasis.
    • Text Layout: The use of
      tags breaks the text into multiple lines, creating a structured and visually appealing layout.


    Button Component





    Button className="mt-6 p-8 text-2xl">Latest Work/Button>
    • Custom Button: The button component, likely styled and built within your custom library, is reusable.
    • Props and Styling:
      • mt-6: Adds top margin for spacing.
      • p-8: Applies generous padding for a clickable and prominent button.
      • text-2xl: Enlarges the text for better readability.
    • Text: The button directs users to view the "Latest Work," potentially linking to a portfolio or case studies.


    BrandSection Component

    Imports





    import Image from "next/image";
    import React from "react";
    • Image: Next.js's Image component ensures efficient image rendering with features like lazy loading and responsive sizing.
    • React: Essential for defining React components.


    BrandSection Function





    function BrandSection() {
    ...
    return (
    section className="relative z-10 my-20 rounded-b-[100px] bg-white px-10 py-20">
    ...
    /section>
    );
    }







    Brands Array





    const brands = [
    { name: "National Bank of Canada", link: "/assets/images/national-bank-of-canada-logo.png" },
    { name: "Matter", link: "/assets/images/matter.png" },
    { name: "Coca-Cola", link: "/assets/images/Coca-Cola.png" },
    { name: "Adobe", link: "/assets/images/Adobe-logo.png" },
    { name: "Subway", link: "/assets/images/subway-logo.png" },
    { name: "Code Academy", link: "/assets/images/code-academy.png" },
    ];
    • Structure: Each brand has a name and a link to the corresponding image file.
    • Scalability: Adding or removing brands is easyβ€”just update the array.


    Styling the Section





    section className="relative z-10 my-20 rounded-b-[100px] bg-white px-10 py-20">
    • relative z-10: Positions the section above other elements for proper layering.
    • my-20: Adds vertical margin for spacing.
    • rounded-b-[100px]: Applies a curved bottom border for a smooth, modern look.
    • bg-white: Sets a clean white background.
    • px-10 py-20: Adds padding for a well-spaced layout.


    Grid Layout





    div className="grid grid-cols-6 items-center justify-items-center gap-8 opacity-50">
    • grid: Establishes a grid layout for displaying the logos.
    • grid-cols-6: Divides the grid into six equal columns, ensuring each brand gets its own space.
    • items-center: Vertically centers the grid items.
    • justify-items-center: Horizontally centers the grid items.
    • gap-8: Adds consistent spacing between the items.
    • opacity-50: Reduces the opacity, giving the logos a subdued, professional look.


    Dynamic Rendering of Brands





    {brands.map((brand, index) => (
    div key={index} className="text-sm font-medium">
    Image
    width={100}
    height={100}
    src={brand.link}
    alt={brand.name}
    className="mx-auto mb-4"
    />
    /div>
    ))}
    • Mapping: The brands array is iterated with map() to render each brand dynamically.
    • Key Prop: The key prop (index) ensures React efficiently updates the DOM.
    • Image Component:
      • src: Specifies the image path for each logo.
      • alt: Improves accessibility and SEO with descriptive alt text.
      • width and height: Ensures consistent logo sizing (100x100 px).
      • className: Centers the image and adds a small margin at the bottom (mx-auto mb-4).
    • Wrapper Div: Includes text-sm for small text size and font-medium for medium-weight font (if text is needed later).


    ServiceSection Component

    Imports





    import { Card } from "@/components/ui/card";
    import React from "react";
    • Card: A reusable UI component likely styled for consistent card-based layouts. This simplifies the process of rendering each service as a visually cohesive block.
    • React: Required to define and use React components.


    ServiceSection Function





    function ServiceSection() {
    ...
    return (
    section className="mb-20 py-52 px-20 w-full bg-stone-400/20 -my-52">
    ...
    /section>
    );
    }







    Services Array





    const services = [
    {
    title: "UX & UI",
    description: "Designing interfaces that are intuitive, efficient, and enjoyable to use",
    icon: "🎨",
    },
    {
    title: "Web & Mobile App",
    description: "Transforming ideas into exceptional web and mobile app experiences",
    icon: "πŸ“±",
    },
    {
    title: "Design & Creative",
    description: "Crafting visually stunning designs that connect with your audience",
    icon: "✨",
    },
    {
    title: "Development",
    description: "Bringing your vision to life with the latest technology and design trends",
    icon: "πŸ’»",
    },
    ];
    • Structure: Each service has a title, description, and an icon to visually represent the service.
    • Purpose: Makes the component dynamic and scalableβ€”adding or updating services only requires modifying this array.


    Styling the Section





    section className="mb-20 py-52 px-20 w-full bg-stone-400/20 -my-52">
    • mb-20: Adds vertical margin at the bottom for spacing between sections.
    • py-52 px-20: Provides generous padding for a spacious layout.
    • w-full: Ensures the section spans the full width of the viewport.
    • bg-stone-400/20: Applies a semi-transparent background with a soft stone-gray tone.
    • -my-52: Adds a negative margin to overlap the previous or next sections slightly for a layered effect.


    Heading and Subheading





    div className="mb-16 text-center">
    h2 className="mb-2 text-3xl font-bold">
    Collaborate with brands and agencies
    /h2>
    p className="text-xl text-gray-600">to create impactful results./p>
    /div>
    • Heading (h2): Styled with text-3xl for a prominent font size and font-bold for emphasis.
    • Subheading (p): Smaller (text-xl) and styled with text-gray-600 for a subtle, secondary emphasis.


    Grid Layout for Services





    div className="grid sm:grid-cols-4 gap-8">
    • grid: Enables a grid layout for the cards.
    • sm:grid-cols-4: Defines a 4-column grid on small screens and larger.
    • gap-8: Adds consistent spacing between grid items.


    Dynamic Rendering of Services





    {services.map((service, index) => (
    Card key={index} className="p-6 bg-stone-400/20">
    div className="mb-4 text-2xl">{service.icon}/div>
    h3 className="mb-2 text-lg font-semibold">{service.title}/h3>
    p className="text-sm text-gray-600">{service.description}/p>
    /Card>
    ))}
    • Mapping: Each service is rendered dynamically using the .map() function.
    • Card Component:
      • Wrapper (Card): Styled with p-6 for padding and bg-stone-400/20 for a consistent background.
      • Icon: Displayed in text-2xl for a visually striking representation.
      • Title: Styled with text-lg and font-semibold for emphasis.
      • Description: Styled with text-sm and text-gray-600 for readability and a softer tone.
    • Key Prop: Ensures each card has a unique identifier (index) for efficient rendering.


    ContactSection Component

    Imports





    import { Button } from "@/components/ui/button";
    import { HandshakeIcon } from "lucide-react";
    import React from "react";
    • Button: A customizable button component for creating consistent, styled buttons.
    • HandshakeIcon: An icon imported from the lucide-react library to visually enhance the section.
    • React: Enables the use of JSX to build the component.


    ContactSection Function





    function ContactSection() {
    ...
    return (
    section className="-my-40 rounded-t-[100px] bg-white p-28 text-center">
    ...
    /section>
    );
    }
    • The function defines the ContactSection component.
    • The section element serves as the container for the entire component, styled with Tailwind CSS classes.


    Styling the Section





    section className="-my-40 rounded-t-[100px] bg-white p-28 text-center">
    • -my-40: Adds negative vertical margins to overlap the previous section for a seamless flow.
    • rounded-t-[100px]: Gives the section a unique curved top with a large border radius.
    • bg-white: Sets a clean, white background.
    • p-28: Adds ample padding to create a spacious layout.
    • text-center: Centers all text and content horizontally.


    Icon Wrapper





    div className="mb-8 grid place-content-center">
    div className="rounded-full bg-muted p-8">
    HandshakeIcon size={50} />
    /div>
    /div>
    • Outer Wrapper:
      • mb-8: Adds a margin at the bottom to separate the icon from the heading.
      • grid place-content-center: Centers the icon wrapper both vertically and horizontally.
    • Inner Wrapper:
      • rounded-full: Ensures the icon container is perfectly circular.
      • bg-muted: Applies a muted background color, likely defined in the theme.
      • p-8: Adds padding inside the circular wrapper for a spacious look.
    • HandshakeIcon: The icon is rendered with a size of 50px, making it bold and noticeable.


    Heading





    h2 className="mb-8 text-3xl font-bold">
    Tell me about your next
    br />
    project
    /h2>
    • mb-8: Creates separation from the buttons below.
    • text-3xl: Sets a large, attention-grabbing font size.
    • font-bold: Enhances readability by making the text bold


    Footer Component

    Imports





    import React from "react";
    • React: This import enables JSX and is essential for creating React components.


    Footer Function





    function Footer() {
    ...
    return (
    footer className="mt-20 flex items-center justify-between text-sm text-gray-600">
    ...
    /footer>
    );
    }
    • The function defines the Footer component.
    • The footer element serves as the container for the footer content and is styled with Tailwind CSS classes.


    Styling the Footer





    footer className="mt-20 flex items-center justify-between text-sm text-gray-600">
    • mt-20: Adds a margin-top of 20 units, creating space between the footer and the content above it.
    • flex: Utilizes Flexbox for layout, allowing easy alignment of child elements.
    • items-center: Vertically centers the content inside the footer.
    • justify-between: Distributes space between the child elements, placing one at the left and the other at the right.
    • text-sm: Sets a smaller text size for the footer content.
    • text-gray-600: Applies a medium gray color to the text for a subtle and soft appearance.


    Content in the Footer

    1. Copyright Text




    div>Β© 2024 All rights reserved./div>
    • Displays the copyright text with the year 2024.
    • div: A simple container for the copyright notice.

    1. Navigation Links




    nav className="space-x-4">
    Link href="#">HeadStarter/Link>
    /nav>
    • nav: A semantic HTML element for navigation links. In this case, it contains only one link.
    • space-x-4: Adds horizontal spacing between elements within the nav container (though there's only one link here, it can accommodate additional links with equal spacing).
    • : A React component used for client-side navigation, though the href="#" here doesn't direct to any specific page.





    Default Export





    export default Footer;







    Key Features

    1. Simple Layout:
      • The footer is divided into two main sections: the copyright notice on the left and a navigation link on the right, using Flexbox for alignment.
    2. Small Text for Footer:
      • The text is styled in a smaller, subtle gray, ensuring that the footer does not distract from the main content but remains legible.
    3. Extensibility:
      • The navigation section () has space for additional links if needed, making it easy to expand in the future.


    Best Practices

    • Use server components by default
    • Implement lazy loading for heavy components
    • Optimize images with Next/Image
    • Leverage built-in TypeScript support
    • Modularize your code


    Performance Optimization Techniques

    1. Use next/image for automatic image optimization
    2. Implement code splitting
    3. Utilize static generation for non-dynamic content
    4. Enable incremental static regeneration


    Recommended Packages

    • Tailwind CSS for styling
    • Lucide React Icons for icons
    • Shadcn UI for component library


    Deployment

    • Vercel (recommended)
    • Netlify
    • GitHub Pages


    Learning Resources

    • NextJS Official Documentation
    • React Documentation
    • Vercel Deployment Guides




    More...
Working...