A modern counter application built with Next.js, React, and Tailwind CSS. This app allows users to increment, decrement, and reset a counter value with a clean and intuitive interface.
The layout file serves as the root layout for the entire application. It wraps all pages and provides global configuration.
1. Imports
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";Metadata: TypeScript type for defining page metadata (title, description, etc.)Geist&Geist_Mono: Font families imported from Google Fontsglobals.css: Global stylesheet containing base styles
2. Font Configuration
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});- Initializes two font families (sans-serif and monospace)
variable: CSS variable names used throughout the appsubsets: Limits font files to Latin characters only (improves performance)
3. Metadata Definition
export const metadata: Metadata = {
title: "Simple Counter App",
description: "Generated by create next app",
};- Sets the page title and description for SEO and browser tab display
- Helps search engines understand the page content
4. RootLayout Component
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
</html>
);
}- Wraps the entire application structure
children: Rendered page content (injected here)lang="en": Sets HTML language attributeantialiased: Tailwind class that smooths text rendering- Font variables are applied to the body so all child components can use them
The main page component that contains the counter functionality and user interface.
1. Client-Side Directive
"use client";- Marks this component as a Client Component
- Enables use of React hooks like
useState
2. Imports
import { useState } from "react";
import { CounterButton } from "@/components/counter-button";
import { bebasNeue, inter } from "@/fonts";useState: React hook to manage counter stateCounterButton: Reusable button component for counter actions@/fonts: Centralized font exports so pages stay lean
3. Font Initialization
// fonts/index.ts
import { Bebas_Neue, Inter } from "next/font/google";
export const bebasNeue = Bebas_Neue({
weight: "400",
subsets: ["latin"],
display: "swap",
});
export const inter = Inter({
subsets: ["latin"],
display: "swap",
});- Fonts are defined once in
fonts/index.tsusingnext/font/google bebasNeue: Bold display font for headingsinter: Clean text font for controls and labels- Both use
display: "swap"and the Latin subset for performance
4. State Management
const [count, setCount] = useState(0);count: Current counter value (starts at 0)setCount: Function to update counter value
5. Handler Functions
const increment = () => setCount(count + 1); // Adds 1 to count
const decrement = () => setCount(count - 1); // Subtracts 1 from count
const reset = () => setCount(0); // Resets count to 06. UI Layout
- Container: Flexbox layout centered on screen, light gray background
- Card: White rounded container with shadow and padding
- Title: "Counter" heading using Bebas Neue font (bold, large)
- Display: Large number showing current count in blue
- Buttons:
- Minus Button: Red, decrements counter
- Plus Button: Green, increments counter
- Reset Button: Gray, resets counter to 0
- All buttons have hover effects and cursor-pointer for better UX
| Class | Purpose |
|---|---|
flex |
Display: flex (flexible box layout) |
items-center |
Vertical alignment: center |
justify-center |
Horizontal alignment: center |
min-h-screen |
Minimum height: full viewport height |
bg-gray-100 |
Background color: light gray |
bg-white |
Background color: white |
p-8 |
Padding: 2rem on all sides |
rounded-lg |
Border radius: 0.5rem (rounded corners) |
shadow-lg |
Box shadow: large shadow |
w-72 |
Width: 18rem (fixed width) |
text-5xl |
Font size: 3rem (large heading) |
text-6xl |
Font size: 3.75rem (extra large) |
text-center |
Text alignment: center |
mb-8 |
Margin bottom: 2rem |
text-gray-800 |
Text color: dark gray |
text-blue-600 |
Text color: blue |
text-white |
Text color: white |
gap-3 |
Gap between flex items: 0.75rem |
gap-4 |
Gap between flex items: 1rem |
flex-1 |
Flexible grow: equal width |
py-2 |
Padding Y-axis (top & bottom): 0.5rem |
px-4 |
Padding X-axis (left & right): 1rem |
rounded |
Border radius: 0.25rem |
cursor-pointer |
Cursor: pointer (indicates clickable) |
hover:bg-red-600 |
Hover state: darker red background |
hover:bg-green-600 |
Hover state: darker green background |
hover:bg-gray-600 |
Hover state: darker gray background |
| Term | Full Form | Definition |
|---|---|---|
| tsx | TypeScript XML | JavaScript file extension that combines TypeScript and JSX (React syntax) |
| JSX | JavaScript XML | Syntax extension that allows writing HTML-like code in JavaScript |
| React | React Library | JavaScript library for building user interfaces with reusable components |
| Next.js | Next.js Framework | React framework that adds server-side rendering, routing, and optimization |
| Tailwind CSS | Tailwind CSS | Utility-first CSS framework for building custom designs |
| SEO | Search Engine Optimization | Techniques to improve website visibility in search engine results |
| CSS | Cascading Style Sheets | Language for styling HTML elements |
| HTML | HyperText Markup Language | Standard markup language for creating web pages |
| API | Application Programming Interface | Set of rules for software to communicate with each other |
| UX | User Experience | Overall experience of users interacting with an application |
| UI | User Interface | Visual elements and controls that users interact with |
| DOM | Document Object Model | Programming interface representing HTML structure as objects |
| Hook | React Hook | Function that lets you "hook into" React features (e.g., useState) |
| useState | Use State Hook | React hook for managing component state |
| Props | Properties | Data passed from parent to child components |
| Component | React Component | Reusable piece of UI code |
| Variable | Variable | Named storage location for data values |
| Function | Function | Reusable block of code that performs a specific task |
| Readonly | Read Only | Type that prevents modifications after assignment |
| Type | Data Type | Classification of what kind of data a variable holds |
| Export | Export | Make code available for use in other files |
| Import | Import | Include code from other files |
| Default Export | Default Export | Main export from a module (one per file) |
| Metadata | Meta Data | Data about data (e.g., page title and description) |
| Subsets | Subsets | Limited character ranges (e.g., Latin only) |
| Weight | Font Weight | Thickness of font (e.g., 400=normal, 600=bold) |
| Render | Render | Process of displaying content on screen |
| Handler | Event Handler | Function that runs when specific event occurs |
| Click | On Click Event | Event triggered when user clicks an element |
| State | Component State | Data that determines component's current appearance/behavior |
| Button | Button Element | Interactive element users can click |
| Increment | To Increase | Add one or more to a value |
| Decrement | To Decrease | Subtract one or more from a value |
| Reset | Reset Value | Return something to its original/default state |
- Initial State: Counter starts at 0
- User clicks +: Counter increases by 1
- User clicks β: Counter decreases by 1
- User clicks Reset: Counter returns to 0
- Display Updates: All changes are instantly reflected in the UI
- Node.js (v16 or higher)
- npm, yarn, or pnpm
# Install dependencies
pnpm install
# Run development server
pnpm dev
# Open in browser
# Navigate to http://localhost:3000counter/
βββ app/
β βββ layout.tsx # Root layout with font configuration
β βββ page.tsx # Counter component
β βββ globals.css # Global styles
βββ components/
β βββ counter-button.tsx # Shared counter button
β βββ ui/button.tsx # Shadcn-styled base button
βββ fonts/
β βββ index.ts # Centralized font exports (bebasNeue, inter)
βββ lib/
β βββ utils.ts # Utility helpers
βββ public/ # Static files
βββ package.json # Project dependencies
βββ tsconfig.json # TypeScript configuration
βββ postcss.config.mjs # PostCSS/Tailwind pipeline
βββ eslint.config.mjs # ESLint configuration
βββ pnpm-lock.yaml # Locked dependencies
βββ pnpm-workspace.yaml # Workspace settings
βββ components.json # Shadcn UI registry
βββ next.config.ts # Next.js configuration
- Next.js 14: Modern React framework
- React 18: UI library with hooks
- TypeScript: Type-safe JavaScript
- Tailwind CSS: Utility-first styling
- Shadcn UI: Base button styling via
components/ui/button - Google Fonts: Bebas Neue and Inter exported from
fonts/index.ts
- Clean, minimal interface
- Responsive layout centered on screen
- Color-coded buttons (green for +, red for β, gray for Reset)
- Hover effects for better interactivity
- Modern typography with Google Fonts
- Smooth transitions and visual feedback